Jersey :如何返回List>作为回应?

发布于 2025-01-04 03:59:17 字数 4593 浏览 1 评论 0 原文

我有以下 Web 服务:

 @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 来避免 List<> 的类型擦除。但由于我的编组类中有泛型,我相信这会导致问题。那么,如果我希望能够返回通用地图,我可以实施什么解决方案。如果我更改 MarshalledMapEntry 以便不使用泛型,而是使用 String、String 作为它可以工作的类型,但我可以有几种不同的 Map 类型,并且我不想仅使用更改的类型创建此类的副本?

I have the following web-service:

 @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();
    }

And this is my 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;
    }

}

Since JAXB doesn't support collection as top level elements I wrote a simple class which wraps a map. But I get the following exception:

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)

As evident I have tried to use the JResponse to avoid the type erasure of the List<> but since I have generics in my Marshalled class I believe this causes a problem. So what solution can I implement if I want to be able to return Generic Maps. If I change my MarshalledMapEntry so that I don't use generics but instead have String, String as types it work, but I can have several different Map types and I don't want to create copies of this class with only changed types?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不甘平庸 2025-01-11 03:59:18

你需要实现

@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>

you need to implements

@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

    }

}

And register it into 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文