- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的工作是使用 Servlet 编写一种 Web 服务适配器,然后调用适配器 EJB(SOAP Web 服务),而适配器 EJB 又调用现有的服务方法(也是 EJB)。现有的架构基于EJB 2.0,我暂时无法更改。外部客户应该直接访问 Servlet 而不是 Webservice 类。原因是需要使用 HTTPRequest 中的信息进行一些预处理(从证书和 HTTP header 中获取和映射用户 ID)。因此,Servlet 对 doPost() 方法使用react,执行解析和编码 SOAP XML 数据等预处理,然后调用适配器 EJB(无状态 session Bean),更准确地说,Web 服务方法将触发不同 EJB 中的现有服务方法。到目前为止,这种方法运行良好,直到 EJB 需要现有的 session 或 session 为止。 SessionContext,就像下面处理事务回滚的情况:
protected void preventTransactionRolledBackException() {
if (this.getSessionContext().getRollbackOnly()) {
this.getSessionContext().setRollbackOnly();
}
}
在我的设置中,SessionContext 始终为空。由于整个应用程序已经相当复杂,我尝试仅使用 Servlet 和一个 EJB 发布一个简化的设置,希望我不会排除相关的内容。系统:WebSphere应用服务器8.5
Servlet:
public class NewZekEclsServiceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String operation = null;
response.setContentType("text/xml");
try {
PrintWriter out = response.getWriter();
// Get Header data
// Get Attribute data
// Get Body data:
InputStream body = request.getInputStream();
String xml = IOUtils.toString(body, "UTF-8");
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true); // required as several namespaces might be used
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
operation = getOperation(doc); // method which scans the xml to retrieve the correct operation to use.
if (operation.equalsIgnoreCase("Ping")) {
// Calling the Adapter Bean:
EclsTestBeanBean eclsTestBean = new EclsTestBeanBean();
eclsTestBean.ejbCreate();
PingIn pingIn = new PingIn();
PingOut pingOut = eclsTestBean.ping(pingIn);
String xmlString = convertEclsObjectToSOAPString(pingOut);
out.print(xmlString);
}
}
}
}
EJB(由 Rational Application Developer 9.0 生成):
/**
* Bean implementation class for Session Bean: EclsTestBean
*
* @ejb.bean
* name="EclsTestBean"
* type="Stateless"
* jndi-name="ejb/ch/zek/ecls/EclsTestBeanHome"
* view-type="remote"
* transaction-type="Bean"
*
* @ejb.home
* remote-class="ch.zek.ecls.EclsTestBeanHome"
*
* @ejb.interface
* remote-class="ch.zek.ecls.EclsTestBean"
*
*/
public class EclsTestBeanBean implements javax.ejb.SessionBean {
private Log log = LogFactory.getLog(EcodeAbfragenAction.class);
private SessionContext mySessionCtx;
public SessionContext getSessionContext() {
return mySessionCtx;
}
public void setSessionContext(SessionContext ctx) {
mySessionCtx = ctx;
}
public void ejbCreate() throws CreateException {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
/**
* Basic ping service for ECLS
* @param parameters
* @return
* @throws PingEntityNotFoundException
* @throws PingPermissionException
* @throws PingSystemException
*/
public ch.zek.ecls.PingOut ping(ch.zek.ecls.PingIn parameters) throws java.rmi.RemoteException, ch.zek.ecls.PingPermissionException, ch.zek.ecls.PingEntityNotFoundException, ch.zek.ecls.PingSystemException {
PingOut pingOut = new PingOut();
String pingAnswer = "Ping_ECLS_v1";
String adapter = "";
String operation = "";
Parameter[] msgParams = new Parameter[1];
String eclsEnvironment = "TEST";
pingAnswer += "_" + eclsEnvironment;
logAvailableEjbs();
try {
if (mySessionCtx != null) { // Why can it be null at all?
log.debug("mySessionCtx: " + mySessionCtx.getContextData());
} else {
log.debug("mySessionCtx was null");
InitialContext ic = new InitialContext();
mySessionCtx = (SessionContext) ic.lookup("java:comp/env/sessionContext"); // gives error: javax.naming.NameNotFoundException: Name "comp/env/sessionContext" not found in context "java:".
System.out.println("mySessionCtx: " + mySessionCtx);
}
} catch (Exception e) {
e.printStackTrace();
}
// creating the SOAP data... not relevant for the problem.
msgParams[0] = new Parameter();
msgParams[0].setValue(pingAnswer);
SystemMessage systemMessage = new SystemMessage();
systemMessage.setCode("OK");
systemMessage.setMessage("Ping");
systemMessage.setParameter(msgParams);
pingOut.setSystemMessage(systemMessage);
return pingOut;
}
/**
* ONLY USED DURING DEVELOPMENT:
* Helper method to print "accessible" EJBs.
*/
protected void logAvailableEjbs() {
try {
//Get the Initial Context for the JNDI lookup for a local EJB
InitialContext ic = new InitialContext();
NamingEnumeration<NameClassPair> list;
String level = "";
String name = "";
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
level = "ejb";
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
level = "java:comp";
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
level = "java:comp/env";
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
/*
level = "java:comp/env/ejb"; // Throws Error!
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
*/
level = "java:global";
list = ic.list(level);
while (list.hasMore()) {
name = list.next().getName();
System.out.println(level + "/" + name);
}
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我们正在使用 SoapUI 工具 ( http://www.soapui.org ) 测试设置。同样,我们为简单的 Ping() 服务获得了正确的结果,但是一旦需要与 session 相关的内容,它就会失败。
当然我做了一些研究,特别有趣的是这个链接: How to get SessionContext in JBOSS这也指: http://javahowto.blogspot.co.uk/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html
关于 EJB 生命周期:docs.oracle.com/cd/E13224_01/wlw/docs100/guide/ejb/session/conSessionBeanLifeCycle.htmlJ2EE 教程:docs.oracle.com/javaee/6/tutorial/doc/gipss.html#gipsx(抱歉,不能发布超过 2 个链接...)
但正如代码中所述,我无法访问 java:comp/env/ejb/sessionContext。好吧...甚至 java:comp/env/ejb 也没有。我编写了一个脏帮助器方法来查看 EJB 实际可以访问的内容并获得以下输出:
SystemOut O /jta
SystemOut O /eis
SystemOut O /cell
SystemOut O /thisNode
SystemOut O /DefaultDatasource
SystemOut O /services
SystemOut O /jdbc
SystemOut O /servername
SystemOut O /com.ibm.websphere.ejbcontainer
SystemOut O /com
SystemOut O /zek
SystemOut O /wm
SystemOut O /ejb
SystemOut O /Increment
SystemOut O /tm
SystemOut O ejb/ivtEJBObject
SystemOut O ejb/ch
SystemOut O ejb/mgmt
SystemOut O java:comp/ValidatorFactory
SystemOut O java:comp/TransactionSynchronizationRegistry
SystemOut O java:comp/ORB
SystemOut O java:comp/Validator
SystemOut O java:comp/UserTransaction
SystemOut O java:comp/env
SystemOut O java:comp/BeanManager
SystemOut O java:comp/websphere
SystemOut O java:comp/HandleDelegate
SystemOut O java:global/com.ibm.ws.AppNameSpaces
SystemOut O java:global/NewZekEar
SystemOut O java:global/SchedulerCalendars
SystemOut O java:global/DefaultApplication
SystemOut O java:global/cell
SystemOut O java:global/query
SystemOut O java:global/ManagementEJB
SystemOut O java:global/ivtApp
我还尝试使用注释:
@Resource
private SessionContext mySessionCtx;
或者设置不同的交易类型:
transaction-type="Container"
没有任何帮助。我理解 SessionContext 应该自动创建。但如果不是——必须选择哪种选项来创建新的选项?进一步问题:servlet 还“创建”了一个我可以访问的 session (request.getSession()),但这是不同的(HTTPSession)。我想我无法将此 session 对象共享或“转换”为 session Bean?
最佳答案
您自己实例化了 EclsTestBeanBean
:
EclsTestBeanBean eclsTestBean = new EclsTestBeanBean();
EJB 依赖于将对象包装在代理中,以允许容器添加额外的服务,包括依赖注入(inject) session 上下文,这意味着只有容器可以创建它们并发出它们。您还会发现该对象不会执行任何 EJB 服务,它只是一个 POJO。
要从容器请求 EJB,您需要通过依赖项注入(inject)请求它或从 JNDI 查找它,按照以下答案:
JPA entity manager not correctly injected - Weblogic
那么下一个问题是您的 bean 似乎在 JNDI 中不可用 - 我认为这是因为您没有为其定义本地或远程接口(interface)。这在使用“无接口(interface)” View 的 EJB3 中很好,但在 EJB2 中则不然: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jst.ejb.doc.user%2Ftopics%2Fcearch.html
所以我建议 - 自己编写一个接口(interface)(希望如此),然后 EclsTestBeanBean
在 JNDI 中可用,并从那里查找它而不是实例化它。
(使用 @Resource 注释,请注意,所有基于注释的工作也已添加到 EJB3 中。)
关于java - 从 Servlet 调用的 Session-Bean 中,SessionContext 始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34676918/
我正在使用 Glassfish 4 来部署应用程序。它曾经有一个 EJB,其中 SessionContext 通过 @Resource 注释注入(inject)。 @Stateless @Declar
我将 SessionContext 作为资源注入(inject) EJB(实现容器管理的事务): @Stateless(name = "XXX", mappedName = "PPP-MMM-CCC"
在 Java EE 上下文中,特别是在 CDI 中 ApplicationScoped对象,我需要强制回滚容器管理的事务。 (它是 JPA(事务)操作和一些文件系统操作的组合,后者并不是真正的事务性操
我有一个简单的 (webprofile) EJB 3.1 应用程序并尝试确定 @ApplicationScoped CDI Bean 中的当前用户,所以我使用: Principal callerPri
我不确定以下问题的正确答案是什么。 A developer writes a stateful session bean FooBean with two local business interfa
在 EJB 项目中,我需要替换“javax.ejb.SessionContext”中的调用主体名称。我使用 Jboss AS 6.0 Final 作为应用服务器。 我定义了一个扩展 UsernameP
在 EJB2 ,当调用另一个(本地/远程)bean 时,需要在 EJB 中使用 getEJBBusinessObject() 方法来传递对自身的引用。 是否同样适用于 EJB3 ? 例如 @State
我有一个方法,如果该人具有特定角色并且他们与 JIRA 中的特定组相关联,则可以调用该方法。由于 JIRA 中的组是动态的,因此我无法为每个 JIRA 组分配一个角色。 @DeclareRoles({
由于各种原因,我需要手动查找 SessionContext。在JBoss5中,解决方案 InitialContext initialContext = new InitialContext(); Se
背景: 我正在使用使用 Java 安全性的程序化身份验证(基本身份验证)。我有一个无状态 session bean(EJB 3)。我可以注入(inject) Sessioncontext 以获取安全主
我正在使用 Java EE 6,这是第一次使用 jax-rs 并且我有这个资源类,但我不知道为什么在访问服务时没有检索到我的 session 。登录工作正常,并且可以在应用程序的其他部分检索主体。 @
我需要编写一个 session bean,在代码中的某个位置检查当前用户是否具有某些角色。 为了对我的 EJB3 进行单元测试,我正在尝试 OpenEJB。我按照他们的例子 testing secur
我将单例 EJB 公开为 Restful 服务;要求是通过 Rest API 启动计时器。因为这将是 Web 应用程序,所以我将 ejb 类打包到 war 文件中。我能够成功部署 bean 并调用 W
SessionContext.getBusinessObject() 在文档中描述如下, Obtain an object that can be used to invoke the current
我有一个使用 Keycloak 保护的 JEE 服务 (JaxRx),身份验证有效,但是当我想使用 @RolesAllowed 应用安全性时,我得到了 EJBAccessException。 该服务部
我有一个 EJB 类,它具有 @Resource private SessionContext objSessionContext; 如果我为此属性提供 setter 和 getter,注入(inje
我收到以下 NullPointerException: Caused by: java.lang.NullPointerException at FacadeBean.createRegistrati
我的工作是使用 Servlet 编写一种 Web 服务适配器,然后调用适配器 EJB(SOAP Web 服务),而适配器 EJB 又调用现有的服务方法(也是 EJB)。现有的架构基于EJB 2.0,我
我是一名优秀的程序员,十分优秀!