【问题标题】:EJB Object Null Pointer Exception Inside JAX-WS Web ServiceJAX-WS Web 服务中的 EJB 对象空指针异常
【发布时间】:2012-08-23 09:52:57
【问题描述】:

我试图开发一个在 Web 服务类中利用 EJB 功能的 Web 服务应用程序,但 EJB 对象在运行时为空。

我正在使用 Spring Application Context 配置 Web 服务。有什么问题吗?

代码:

public class CreditCardService implements ICreditCardService {  

  private static final Logger logger = Logger.getLogger(CreditCardService.class.getName());  

  @EJB  
  private CreditcardFacadeLocal databaseFacade;  

  @Override  
  public void addCreditCard(Creditcard card) {  
    logger.log(Level.INFO, "Add credit card start");  
    databaseFacade.addCreditCard(card); // NPE Here  
    logger.log(Level.INFO, "Add create card finish");  
  }  
} 

Web.xml

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">  

    <display-name>CreditCardWebService</display-name>  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>WEB-INF/beans.xml</param-value>  
    </context-param>  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  

    <servlet>  
        <description>Apache CXF Endpoint</description>  
        <display-name>cxf</display-name>  
        <servlet-name>cxf</servlet-name>  
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
        <enabled>true</enabled>  
        <async-supported>false</async-supported>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>cxf</servlet-name>  
        <url-pattern>  
        /services/*</url-pattern>  
    </servlet-mapping>  
    <session-config>  
        <session-timeout>60</session-timeout>  
    </session-config>  
    <welcome-file-list>  
        <welcome-file>index.html</welcome-file>  
        <welcome-file>index.htm</welcome-file>  
        <welcome-file>index.jsp</welcome-file>  
        <welcome-file>default.html</welcome-file>  
        <welcome-file>default.htm</welcome-file>  
        <welcome-file>default.jsp</welcome-file>  
    </welcome-file-list>  
</web-app> 

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">  
    <import resource="classpath:META-INF/cxf/cxf.xml" />  
    <!--  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> -->  
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

    <!-- Create Web Service End Point using Spring DI-->  
    <jaxws:endpoint xmlns:tns="http://service.peter.com/"  
        id="creditcardservice" implementor="com.peter.service.CreditCardService"  
        wsdlLocation="wsdl/creditcardservice.wsdl" endpointName="tns:CreditCardServicePort"  
        serviceName="tns:CreditCardServiceService" address="/CreditCardServicePort">  
        <jaxws:features>  
            <bean class="org.apache.cxf.feature.LoggingFeature" />  
        </jaxws:features>  
    </jaxws:endpoint>  
</beans> 

ejb ojbect 为空的原因是什么?它是否与 CreditCardService 类的 Spring DI 相关但不实例化 ejb 对象?

CXF servlet 的用途是什么?它是用来处理网络服务请求的吗?

请帮忙。

谢谢。

【问题讨论】:

    标签: java spring ejb jax-ws cxf


    【解决方案1】:

    CXF servlet 用于处理 Web 服务请求。 CXF 是一个基于 JAX-WS 的 Web 服务堆栈,但具有 JAX-WS 没有的一些功能。看看here

    您不能在 Web 服务中使用 @EJB 注释注入您的 EJB 对象。 @EJB 注解仅适用于托管 bean,例如 servlet 等...或者在 EJB 上下文中。

    要注入您的EJB,您需要在您的网络服务中查找JNDI。所以它会是这样的:

    /**
     * Java global JNDI.
     */
    private static final String JAVA_GLOBAL = "java:global/";
    
    /**
     * Application name in application server.
     */
    private static final String APP_NAME = "YourAppName/";
    
    /**
     * Application EJB jar name.
     */
    private static final String APP_EJB = "your-ejb/";
    
    /**
     * Credit EJB constant.
     */
    public static final String CREDIT_EJB = JAVA_GLOBAL + APP_NAME + APP_EJB + "CreditcardFacade!your.package.CreditcardFacadeLocal";
    

    现在创建一个通用方法来从 JNDI 获取您的 EJB 对象:

    /**
     * Gets local EJB from JNDI.
     *
     * @param jndiName JNDI constant name to look up for EJB
     * @param <T> generic object
     * @return local EJB object loaded from JNDI
     */
    public static <T> T getLocalEJB(String jndiName) {
        try {
            InitialContext context = new InitialContext();
            return (T) context.lookup(jndiName);
        } catch (NamingException e) {
            LOGGER.error("Naming exception occurred while trying to load EJB from JNDI with JNDI name: " + jndiName, e);
            throw new RuntimeException("Naming exception occurred while trying to load EJB from JNDI with JNDI name: " + jndiName, e);
        }
    }
    

    现在您可以像这样获得您的 EJB:

    CreditcardFacadeLocal facade = JndiUtils.getLocalEJB(JndiUtils.CREDIT_EJB);
    

    我自己在 CXF 网络服务中做过,一切正常。

    【讨论】:

    • 为什么用@WebService注解的类不是托管bean? AFAIK,有两个容器,即 Web 容器和 EJB 容器,其中 EJB 对象可以注入 Web 容器对象(Servlet),因为它的(Servlet)范围由服务器(Web 容器)管理。 WebService 是属于 Web 服务容器还是不属于 Web 容器管理的 CXF/JAX-WS?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多