如何在java web服务SOAP中注入EJB



我打算用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);
   }
}

最新更新