2012-08-23 31 views
1

我試圖開發一個Web服務應用程序,它利用Web服務類中的EJB函數,但在運行時EJB對象爲空。JAX-WS Web服務中的EJB對象空指針異常

我使用Spring應用程序上下文配置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的用途是什麼?用它來處理Web服務請求嗎?

請幫忙。

謝謝。

回答

1

CXF servlet用於處理Web服務請求。 CXF是基於JAX-WS的Web服務的堆棧,但具有某些功能JAX-WS沒有。看看here

您不能在您的Web服務中使用@EJB註釋將您的EJB對象注入。 @EJB註釋僅適用於託管bean,如servlet等......或在EJB上下文中使用。

要注入您的EJB,您需要使JNDI在您的Web服務中查找。因此,這將是這樣的:

/** 
* 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 web服務中自己完成了,一切都很完美。

+0

爲什麼使用@WebService進行批註不是託管bean? AFAIK,有兩個容器,它們是Web容器和EJB容器,EJB對象可以注入Web容器對象(Servlet),因爲它的(Servlet)範圍由服務器(Web容器)管理。 WebService屬於Web容器還是Web容器管理的CXF/JAX-WS?謝謝。 – peterwkc