2016-01-23 59 views
0

我完全被卡住了!花了很多小時在這個沒有進步...CXF @PUT請求「沒有發現消息正文作者」異常

我有一個Spring 4(4.2.3.RELEASE)應用與CXF 3(3.1.4),我正在嘗試JUnit測試。除了PUT請求外,一切都很好。我收到以下錯誤:

Caused by: org.apache.cxf.interceptor.Fault: No message body writer has been found for class com.someproject.logic.api.data.User, ContentType: application/xml 
    at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1222) 
    at org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handleMessage(AbstractClient.java:1091) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) 
    at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:649) 
    at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1093) 
    ... 49 more 

產生的原因:javax.ws.rs.ProcessingException:沒有消息體的作家已經發現了類com.someproject.logic.api.data.User,則contentType:應用/ xml at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:780) at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:494) at org.apache .cxf.jaxrs.client.WebClient $ BodyWriter.doWriteBody(WebClient.java:1217) ... 53更多

我也嘗試過使用「application/json」並得到相同的結果噸。

這裏是CXF配置:

@Bean 
@DependsOn("cxf") 
public Server jaxRsServer() { 
    JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); 
    List<Object> providers = new ArrayList<Object>(); 

    // get all the class annotated with @JaxrsService 
    List<Object> beans = configUtil.findBeans(JaxrsService.class); 

    if (beans.size() > 0) { 

     // add all the CXF service classes into the CXF stack 
     sf.setServiceBeans(beans); 
     sf.setAddress("http://localhost:8080/api"); 
     sf.setBus(springBus); 
     sf.setStart(true); 

     // set JSON as the response serializer 
     JacksonJsonProvider provider = new JacksonJsonProvider(); 
     providers.add(provider); 

    } 

    // add custom providers if any 
    sf.setProviders(providers); 

    return sf.create(); 
} 

端點:

@Path("/user") 
@PUT 
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, }) 
@Produces(MediaType.APPLICATION_JSON) 
public User updateUser(User user); 

端點IMPL:

@Override 
public User updateUser(User user) { 
    System.out.println("updateUser: " + user); 
    return user; 
} 

測試:

@Before 
public void setUp() throws Exception { 

    MockitoAnnotations.initMocks(this); 

    webClient = WebClient.create("http://localhost:8080/api"); 
    WebClient.getConfig(webClient).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE); 
    webClient.accept("application/json"); 

} 

@Test 
public void testPut() { 

    String apiUrl = "/user"; 
    webClient.path(apiUrl); 

    User user = createDummyAPIUser(); 

    try { 

     System.out.println("testUpdateUser: PUT request to " + apiUrl); 
     String response = webClient.type(MediaType.APPLICATION_JSON).put(user, String.class); 
     System.out.println("testUpdateUser: " + apiUrl + " response: " + response); 
     //updatedUser = (new ObjectMapper()).readValue(response, User.class); 

    } catch(Exception e) { 

     e.printStackTrace(); 
     fail(); 
     return; 

    } 

} 

首先,我如何確保fasterxml Jackson 2提供者實際上序列化消息正文?它沒有在堆棧中看到任何傑克遜,但我確實在提供者中設置了它。

我發現這個鏈接來演示一個自定義ContextProvider,這是獲得這個工作的唯一方法嗎?看起來完全是多餘的... http://www.blackpepper.co.uk/custom-context-providers-for-cxf-with-the-context-annotation/

任何想法?

謝謝!

回答

1

GEEEEEEZZZ ...

感覺像一個白癡,忘了相同傑克遜串行器(提供者)添加到客戶端。通過堆棧跟蹤再次找我注意到的方法,由客戶端僅是,如此明顯的客戶不知道如何消費,我在它扔POJO ...

更新的測試代碼:

@Before 
public void setUp() throws Exception { 

    MockitoAnnotations.initMocks(this); 

    final List<Object> providers = new ArrayList<Object>(); 
    JacksonJaxbJsonProvider jacksonJsonProvider = new JacksonJaxbJsonProvider(); 
    providers.add(jacksonJsonProvider); 

    webClient = WebClient.create("http://localhost:8080/api", providers); 
    WebClient.getConfig(webClient).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE); 
    webClient.accept("application/json"); 

}