2013-10-16 66 views
2

我正在嘗試爲使用CXF 2.6.4的REST應用程序開發一個簡單的概念證明。我正在採取非春季的做法。我使用JBoss AS 7.1.1 Final作爲我的Web服務器。使用Apache CXF通過REST解析字符串[]請求參數

以下是我的web服務類:

package restful.webservice; 

import javax.ws.rs.Consumes; 
import javax.ws.rs.GET; 
import javax.ws.rs.POST; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 

import restful.entity.ControllerVersion; 

@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class WebServiceRest implements WebServiceInterface 
{ 

    @Override 
    @POST 
    @GET 
    @Path("/getVersion") 
    public ControllerVersion getVersion(String deviceID, String[] macAddresses) 
    { 

     return new ControllerVersion(); 
    } 
} 

ControllerVersion類:

package restful.entity; 

@XmlRootElement(name = "ControllerVersion") 
public class ControllerVersion { 

    private String version="R1.1.0.0"; 

    public String getVersion() { 
     return version; 
    } 

} 

現在,當我嘗試做一個REST調用我的web服務,我得到以下在服務器端的例外:

18:51:52,913 WARNING [org.apache.cxf.jaxrs.utils.JAXRSUtils] (http--0.0.0.0-8080-1) No message body reader has been found for request class String[], ContentType : application/json. 
18:51:52,927 WARNING [org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper] (http--0.0.0.0-8080-1) javax.ws.rs.WebApplicationException 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1054) 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:614) 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) 
     at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238) 
     at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) 
     at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) 
     at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) 
     at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:236) 
     at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209) 
     at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154) 
     at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:225) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:145) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:201) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) 
     at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) 
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) 
     at java.lang.Thread.run(Thread.java:662) 

libr我有在WEB-INF/lib目錄白羊:

cxf-api-2.6.4.jar 
cxf-bundle-2.6.4.jar 
cxf-rt-frontend-jaxrs-2.6.4.jar 
cxf-rt-frontend-jaxrs.jar 
cxf-rt-transports-http-2.6.4.jar 
geronimo-servlet.jar 
jaxb-api-2.2.5.jar 
jaxb-impl-2.2.5.1.jar 
jaxb-xjc-2.2.5.1.jar 
jettison-1.3.4.jar 
log4j-1.2.16.jar 
neethi-3.0.2.jar 
xmlschema-core-2.0.3.jar 

有趣的是,我試圖做的另一個項目,但這次是在我的web服務方法的簽名,我包括一個自定義類。閱讀自定義類的實例的內容時我沒有任何問題,但在將其返回給客戶端時也沒有問題。

我錯過了什麼嗎?

UPDATE: 我試着下面添加到我的web.xml:

<init-param> 
    <param-name>jaxrs.providers</param-name> 
    <param-value> 
     org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider 
     (writeXsiType=false) 
    </param-value> 
</init-param> 

,並添加以下的依賴,以及:

jackson-jaxrs-1.9.2.jar 
jackson-mapper-asl-1.9.2.jar 
jackson-xc-1.9.2.jar 

現在我發現了以下例外:

19:22:29,762 WARNING [org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper] (http--0.0.0.0-8080-1) javax.ws.rs.WebApplicationException: java.io.IOException: Stream closed 
     at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:243) 
     at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) 
     at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) 
     at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) 
     at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:236) 
     at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209) 
     at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154) 
     at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:225) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:145) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 
     at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:201) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) 
     at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) 
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) 
     at java.lang.Thread.run(Thread.java:662) 
Caused by: java.io.IOException: Stream closed 
     at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:377) 
     at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:193) 
     at java.io.FilterInputStream.read(FilterInputStream.java:116) 
     at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507) 
     at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129) 
     at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224) 
     at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785) 
     at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561) 
     at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:414) 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1038) 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:614) 
     at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) 

更新2: 我試圖執行與不同的簽名的方法,這時候,我已經省略從方法的字符串數組:

public ControllerVersion getVersion(String deviceID) 

一切都沒有字符串數組可以正常使用。你覺得我應該怎麼做?

回答

1

我顯然誤解了REST的工作原理。我所做的,以最終解決問題是以下幾點:

1-改變了我的Web服務的簽名:

@POST 
@Path("/getVersion") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes({"application/xml", "application/json", "application/x-www-form-urlencoded"}) 
public ControllerVersion getVersion(@FormParam("deviceID") String deviceID,@FormParam("macAddresses") String macAddresses) 

2 - 現在,請確保客戶端發送的內容類型的請求(應用程序/ x-www-form-urlencoded),並且客戶端正確地添加了與您在@FormParam註釋中定義的相同的表單參數。

3-現在,您可以使用諸如FlexJson之類的庫來反序列化JSon字符串中的參數。例如,我現在將macAddresses作爲JSon字符串發送:[「mac1」,「mac2」]來自客戶端。在服務器端,我這個JSON字符串轉換爲使用以下方法一個String []:

public static String[] parseStringArrayFromJSONArray(String jsonArray) 
{ 
    String[] stringArray = null; 
    try 
    { 
     JSONArray array = new JSONArray(jsonArray); 
     if (array != null) 
     { 
      stringArray = new String[array.length()]; 

      for (int i = 0; i < array.length(); i++) 
      { 
       stringArray[i] = array.getString(i); 
      } 
     } 
    } catch (Exception e) 
    { 
     stringArray = null; 
    } 

    return stringArray; 
} 

我希望這會幫助別人那裏。

0

您正在使用@Consumes(MediaType.APPLICATION_JSON)。您需要添加jackson-core(也許還有一些jackson依賴關係)才能進行轉換。

+0

我試圖添加傑克遜,但我現在結束了另一個例外。請檢查我原始問題中的「更新」部分。 –

0

cxf默認使用拋棄。爲什麼你有@GET和@POST註釋? 但它說的

java.io.IOException: Stream closed 

因此,有最有可能不被關閉的InputStream。

+0

當我使用Jackson而不是Jettison時,發生了「java.io.IOException:Stream closed」異常。我不知道如何解決這個問題! –

+0

什麼是restful.entity.ControllerVersion?這個類中的代碼是什麼?你返回一個新類的實例的理由是什麼?那天我看到了這個確切的錯誤,我試圖嘗試完全一樣的東西。我的問題是,當我用BufferedWriter編寫JSON時,稱爲.close(),然後是.flush()。出於某種原因,cxf只是首選我來調用.flush()而不是.close()。 – kslote1

+0

我已將ControllerVersion類代碼添加到我原來的帖子中。我只想返回一個自定義類,我想在客戶端解析爲JSon。我不認爲問題出在ControllerVersion類上。請在我上面的帖子中查看UPDATE 2。 –