我打算用Java开发一个简单的web服务,该服务使用EJB,EJB在jar文件中,WebServices在war文件中,两者都打包在一个ear中。我们在JBOSS-AS 7.1上使用EjB 3.0。
这里是我的EJB类及其接口:
@Stateless
public class TestEjb implements ITestEjb {
public boolean authentifier(String login, String password) {
if(login.equals("nico") && password.equals("nr"))
return true;
else
return false;
}
}
@Local
public interface ITestEjb {
public boolean authentifier(String login, String password);
}
这是我的web服务,它注入了以前的EJB:
//@Stateless
@WebService
@SOAPBinding(style = Style.RPC)
public class AuthentificationWS {
@EJB
private ITestEjb testEjb;
public boolean authentifier(String login,String password) {
return testEjb.authentifier(login, password);
}
}
部署运行良好,但当我调用web服务时,EJB总是null(error : java.nullpointerException).
因此,我尝试将@Stateless
添加到我的web服务以将其转换为EJB,但当我尝试由web服务客户端使用它时没有成功。
然后我尝试通过本地jndi查找访问Ejb,如下所示,获取JBOSS日志中的本地jndi url:
final String jndi = "java:module/TestEjb!fr.test.ITestEjb";
testEjb = (ITestEjb) new InitialContext().lookup(jndi);
但这并没有奏效。
最后,我尝试了全局jndi url,如下所示:
final String jndi = "ejb:Num-ear-1.0.0-SNAPSHOT/Num-ejb-1/TestEjb!fr.test.ITestEjb"
testEjb = (ITestEjb) new InitialContext().lookup(jndi);
而且效果很好!!
所以,我不明白为什么我的Web服务不能通过注入或本地Jndi方式本地访问其EJB?
原因是在JBOSS-AS 7.1中,ejb服务的部署和映射方式不同。如果没有为无状态bean指定映射名称,则必须使用其全局名称进行查找,如下所示:ejb:Num-ear-1.0.0-SNAPSHOT/Num-ejb-1/TestEjb!fr.test.ITestEjb
您可以尝试通过以下方式添加映射名称:
@Stateless(name = "ejb/ar/TestEjb", mappedName = "ejb/ar/TestEjb")
public class TestEjb implements ITestEjb {
在您的网络服务中:
@EJB(name = "ejb/ar/TestEjb", mappedName = "ejb/ar/TestEjb")
private ITestEjb testEjb;
在你的web.xml中:
<ejb-local-ref>
<ejb-ref-name>ejb/ar/TestEjb</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>yourpackage.TestEjb</local>
</ejb-local-ref>
在这种情况下,我假设您将web服务部署为web模块。有关如何将web服务部署为web模块的参考,请查看此链接:http://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/
我以前使用过:new InitialContext().lowlup(java:app/domain/TestService)转换为耳朵并使用:
@Local
@Remote
public interface Test {}
@Stateless(name="Test", mapped-name="Test")
public TestService implements Test {}
@Webservice
public MyService{
@EJB(name="Test", mapped-name="Test")
private Test test;
}
这似乎有效,但需要在测试界面()中设置@Remote。Web服务处于战争状态,域在jar中,两者都包含在ear中,并部署在Glassfish(3.1.2)中。很遗憾,我不得不使用annotation@Remote,因为它们都在同一个ear中。如果我省略了@Remote,我会在Glassfish中的部署时得到异常:"试图在ejb上设置ejb引用,而ejb不定义远程接口"。有没有办法省略@Remote??
在没有接口的情况下尝试它,您不再需要在EJB3.x中定义中的接口
@Stateless
public class TestEjb {
public boolean authentifier(String login, String password) {
if(login.equals("nico") && password.equals("nr"))
return true;
else
return false;
}
}
然后按如下注入web服务
@WebService
public class AuthentificationWS {
@EJB
private TestEjb testEjb;
public boolean authentifier(String login,String password) {
return testEjb.authentifier(login, password);
}
}