2012-02-10 59 views
0

我有以下的Web服務:澤西島:如何返回列表<MyType<K,V>>作爲迴應?

@Path("/storage-dirs/{user}") 
    @GET 
    @Produces(MediaType.APPLICATION_XML) 
    public JResponse<List<MarshalledMapEntry<String, Integer>>> getStorageDirs(@PathParam("user") String user) { 


     //List<MarshalledMapEntry<String, Integer>> 
     List<MarshalledMapEntry<String, Integer>> myEntries = new ArrayList<MarshalledMapEntry<String, Integer>>(); 
     Map<String, Integer> originalEntries = DBAccessor.getStorageDirsForUser(user); 

     for (Map.Entry<String, Integer> en : originalEntries.entrySet()) { 

      myEntries.add(new MarshalledMapEntry<String, Integer>(en.getKey(), en.getValue().intValue())); 
     } 

     //GenericEntity<List<MarshalledMapEntry<String, Integer>>> entity = new GenericEntity<List<MarshalledMapEntry<String, Integer>>> {}; 
     return JResponse.ok(myEntries).build(); 
    } 

這是我MarshalledMapEntry:

@XmlRootElement 
    public class MarshalledMapEntry<K, V> { 

    @XmlElement 
    private K key; 
    @XmlElement 
    private V value; 

    MarshalledMapEntry() {} //JAXB requires it 

    public MarshalledMapEntry(K key, V value) { 
     this.key = key; 
     this.value = value; 
    } 

    public K getKey() { 
     return key; 
    } 

    public V getValue() { 
     return value; 
    } 

} 

因爲JAXB不支持集合作爲頂級元素我寫了一個簡單的類,它封裝了一個地圖。但我得到以下異常:

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type java.util.List<silverline.MarshalledMapEntry<java.lang.String, java.lang.Integer>>, and MIME media type application/xml was not found 
    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) 
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

可以明顯看出我曾嘗試使用JResponse避免列表<的類型擦除>但因爲我有我的鎧類仿製藥,我相信這會導致一個問題。那麼,如果我想能夠返回Generic Maps,我可以實現什麼解決方案。如果我更改MarshalledMapEntry,以便不使用泛型,而是將String,String作爲類型使用,但我可以使用多種不同的Map類型,並且不希望僅使用更改的類型創建此類的副本?

回答

0

你需要實現

@Provider 
@Produces(MediaType.APPLICATION_XML) 
public class ASDFWriter implements MessageBodyWriter<String> 
{ 

    @Override 
    public long getSize(String arg0, Class<?> arg1, Type arg2, 
      Annotation[] arg3, MediaType arg4) 
    { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2, 
      MediaType arg3) 
    { 
     // TODO Auto-generated method stub 
     return false; 
    } 

    @Override 
    public void writeTo(String arg0, Class<?> arg1, Type arg2, 
      Annotation[] arg3, MediaType arg4, 
      MultivaluedMap<String, Object> arg5, OutputStream arg6) 
      throws IOException, WebApplicationException 
    { 
     // TODO Auto-generated method stub 

    } 

} 

,並將其註冊到web.xml中

<web-app> 
    <servlet> 
      <init-param> 
       <param-name>com.sun.jersey.config.property.packages</param-name> 
       <param-value> 
        your.package.with.providers 
       </param-value> 
      </init-param> 
     </servlet> 
    </web-app>