java - 将 JAX-WS 版本 2.2.1 升级到 2.2.8 后的 NPE

标签 java web-services jakarta-ee jaxb jax-ws

该应用程序使用的是 JAX-WS 版本 2.2.1,我在其中发现了处理 CustomException 的问题。由于 com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException 无法生成类:IllegalAnnotationExceptions 计数为 1。所以我将 JAX WS 的版本更改为 JAX-WS 2.2.8,上述问题得到解决(CustomExceptions 的类已创建)。但是现在我在尝试使用该服务时遇到以下错误:

Dec 20, 2013 2:42:42 AM com.sun.xml.ws.server.sei.TieHandler createResponse
SEVERE: null
java.lang.NullPointerException
    at server.service.SampleServiceEndpoint.getItems(SampleServiceEndpoint.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.xml.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:250)
    at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:149)
    at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:88)
    at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1136)
    at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1050)
    at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:1019)
    at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:877)
    at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:420)
    at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:687)
    at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:266)
    at com.sun.xml.ws.transport.http.servlet.ServletAdapter.invokeAsync(ServletAdapter.java:225)
    at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doGet(WSServletDelegate.java:161)
    at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doPost(WSServletDelegate.java:197)
    at com.sun.xml.ws.transport.http.servlet.WSServlet.doPost(WSServlet.java:81)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

以下是我的自定义异常类和故障 bean。

public class ConcurrencyException extends Exception {
private ConcurrencyInfoBean faultInfo;

    public ConcurrencyException(String message, ConcurrencyInfoBean faultInfo) {
        super(message);
        this.faultInfo = faultInfo;
    }

    public ConcurrencyException(String message, ConcurrencyInfoBean faultInfo, Throwable cause) {
        super(message, cause);
        this.faultInfo = faultInfo;
    }

    public ConcurrencyInfoBean getFaultInfo() {
        return faultInfo;
    }
}

public class ConcurrencyInfoBean {
protected String message;

    public ConcurrencyInfoBean() {}

    public String getMessage() {
        return message;
    }

    public void setMessage(String value) {
        this.message = value;
    }
}

为其生成以下类:

package client.service.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="ConcurrencyException", propOrder={"faultInfo", "message"})
public class ConcurrencyException
{
  protected ConcurrencyInfoBean faultInfo;
  protected String message;

  public ConcurrencyInfoBean getFaultInfo()
  {
    return this.faultInfo;
  }

  public void setFaultInfo(ConcurrencyInfoBean paramConcurrencyInfoBean)
  {
    this.faultInfo = paramConcurrencyInfoBean;
  }

  public String getMessage()
  {
    return this.message;
  }

  public void setMessage(String paramString)
  {
    this.message = paramString;
  }
}

package client.service.jaxws;

import javax.xml.ws.WebFault;

@WebFault(name="ConcurrencyException", targetNamespace="http://service.server/")
public class ConcurrencyException_Exception extends Exception
{
  private ConcurrencyException faultInfo;

  public ConcurrencyException_Exception(String paramString, ConcurrencyException paramConcurrencyException)
  {
    super(paramString);
    this.faultInfo = paramConcurrencyException;
  }

  public ConcurrencyException_Exception(String paramString, ConcurrencyException paramConcurrencyException, Throwable paramThrowable)
  {
    super(paramString, paramThrowable);
    this.faultInfo = paramConcurrencyException;
  }

  public ConcurrencyException getFaultInfo()
  {
    return this.faultInfo;
  }
}

package client.service.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="concurrencyInfoBean", propOrder={"message"})
public class ConcurrencyInfoBean
{
  protected String message;

  public String getMessage()
  {
    return this.message;
  }

  public void setMessage(String paramString)
  {
    this.message = paramString;
  }
}

之后我在 Web 服务端点类中获得了 NPE:

@MTOM
@WebService(name = "sampleService")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle=ParameterStyle.WRAPPED)
public class SampleServiceEndpoint extends SpringBeanAutowiringSupport {

    @Autowired
    LookupService lookupService;

    @Autowired
    PersistenceService persistenceService;

    @WebMethod
    public List<Items> getItems() {
        return lookupService.getItems(); // Throws NPE
    }

    @WebMethod
    public long updateItem(@WebParam(name = "item") Item item) throws ConcurrencyException{
        return persistenceService.updateItem(item);
    }

    @XmlMimeType("application/octet-stream")
    @WebMethod
    public DataHandler downloadFaxFile(String filename){
        return  new DataHandler(new FileDataSource(filename));
    }
}

使用Fiddler捕获的请求详情:(请注意User-Agent提到的版本:JAX-WS RI 2.2.4-b01,但实际上我在服务器中使用的是2.2.8。)

POST http://172.16.1.17:8080/sample-server/sampleService HTTP/1.1
Accept: text/xml, multipart/related
Content-Type: multipart/related;start="<rootpart*c42f6a20-3467-47db-9f42-2fd710e98a91@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:c42f6a20-3467-47db-9f42-2fd710e98a91";start-info="text/xml"
SOAPAction: "http://service.server/sampleService/getItemsRequest"
User-Agent: JAX-WS RI 2.2.4-b01
Host: 172.16.1.17:8080
Connection: keep-alive
Content-Length: 461
Connection: close

--uuid:c42f6a20-3467-47db-9f42-2fd710e98a91
Content-Id: <rootpart*c42f6a20-3467-47db-9f42-2fd710e98a91@example.jaxws.sun.com>
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
Content-Transfer-Encoding: binary

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getItems xmlns:ns2="http://service.server/"></ns2:getItems></S:Body></S:Envelope>
--uuid:c42f6a20-3467-47db-9f42-2fd710e98a91--

使用 Fiddler 捕获的响应:

HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: multipart/related; start="<rootpart*fd6818ff-12f2-490b-b0fe-7d99e1196491@example.jaxws.sun.com>"; type="application/xop+xml"; boundary="uuid:fd6818ff-12f2-490b-b0fe-7d99e1196491"; start-info="text/xml"
Transfer-Encoding: chunked
Date: Sat, 21 Dec 2013 08:30:25 GMT
Connection: close

154
--uuid:fd6818ff-12f2-490b-b0fe-7d99e1196491
Content-Id: <rootpart*fd6818ff-12f2-490b-b0fe-7d99e1196491@example.jaxws.sun.com>
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
Content-Transfer-Encoding: binary

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body>
b5
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"><faultcode>S:Server</faultcode><faultstring>java.lang.NullPointerException</faultstring></S:Fault></S:Body></S:Envelope>
2f

--uuid:fd6818ff-12f2-490b-b0fe-7d99e1196491--
0

Spring 配置文件: 1.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="server"/>

    <import resource="datasource.xml"/>
    <import resource="services.xml"/>

</beans>
  1. 服务.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
    <bean id="lookupService" class="server.service.LookupServiceImpl">
        <property name="statusDAO" ref="statusDAO"/>
        <property name="utilDAO" ref="utilDAO"/>
        <property name="logDAO" ref="logDAO"/>
        <property name="faxHistoryDAO" ref="faxHistoryDAO"/>
    </bean>
    
    <bean id="persistenceService" class="server.service.PersistenceServiceImpl">
        <property name="logDAO" ref="logDAO"/>
        <property name="faxHistoryDAO" ref="faxHistoryDAO"/>
    </bean>
    
    <bean id="adminService" class="server.service.AdminServiceImpl">
        <property name="userDAO" ref="userDAO"/>
    </bean>
    
    <bean id="reportService" class="server.service.ReportServiceImpl">
        <property name="reportDAO" ref="reportDAO"/>
    </bean>
    

环境细节: jdk1.7.0_21、tomcat 7、windows 7

最佳答案

我可以通过修改我的 Web 服务端点类来避免 NPE,但不确定以下解决方案是否最佳,但它对我有用:

@MTOM
@WebService(name = "sampleService")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle=ParameterStyle.WRAPPED)
public class SampleServiceEndpoint extends SpringBeanAutowiringSupport {

    @Autowired
    LookupService lookupService;

    @Autowired
    PersistenceService persistenceService;

    @WebMethod(exclude=true)
    private void initLookupService(){
        if(lookupService == null)
            processInjectionBasedOnCurrentContext(this);
    }

    @WebMethod(exclude=true)
    private void initPersistenceService(){
        if(persistenceService == null)
            processInjectionBasedOnCurrentContext(this);
    }

    @WebMethod
    public List<Items> getItems() {
        initLookupService();
        return lookupService.getItems();
    }

    @WebMethod
    public long updateItem(@WebParam(name = "item") Item item) throws ConcurrencyException{
        initPersistenceService()
        return persistenceService.updateItem(item);
    }

    @XmlMimeType("application/octet-stream")
    @WebMethod
    public DataHandler downloadFaxFile(String filename){
        return  new DataHandler(new FileDataSource(filename));
    }
}

关于java - 将 JAX-WS 版本 2.2.1 升级到 2.2.8 后的 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20692167/

相关文章:

java - 如何在文件的特定行之后插入文本

web-services - Axis 错误 : There is no SOAP service at this location

mysql - 如何使用node.js创建一个webservice来将数据插入mysql?

jakarta-ee - Java EE 6 注入(inject)抽象类

jsf - 为什么我不应该将 JSF SessionScoped bean 用于逻辑?

Java - 将字符串转换为 ISO 8601 日期格式错误 Joda-Time

java - 在长 Scala 列表或 Stream 上进行 reduce() 操作期间,Java JVM 关于 GC 的智能程度如何?

java - 选择显示所有元素的下拉列表

使用 CXF 生成 SOAP 1.2 端点的 Java Spring Boot

java - 如何用所需的词而不是冗长的域名来屏蔽 URL?