【问题标题】:Jersey/JAX-RS: Return a Map as XML/JSONJersey/JAX-RS:以 XML/JSON 格式返回地图
【发布时间】:2013-09-20 21:56:43
【问题描述】:

如何使用 Jersey/JAX-RS 框架将Map 作为 XML/JSON 文档返回并不那么明显。它已经支持Lists,但是当涉及到Maps 时,没有MessageBodyWriter。即使我将Ma 嵌入到包装类中,XML 模式中也没有map 类型。

关于如何在 Jersey 中将 Map 编组为 XML/JSON 文档的任何实用建议?

【问题讨论】:

标签: java jersey jax-rs


【解决方案1】:

我知道现在回复很晚,但我希望有一天它会对某人有所帮助:) 我应用的最简单和最快的修复方法是

@GET
@Path("/{messageId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getMessage(@PathParam("messageId") long id) {
    Map<String, String> map = new HashMap<>();
    map.put("1", "abc");
    map.put("2", "def");
    map.put("3", "ghi");

    return Response.status(Status.OK).entity(map).build();
}

输出: { “1”:“ABC”, “2”:“定义”, “3”:“吉” }

这绝对可以帮助您解决问题。

【讨论】:

    【解决方案2】:

    在 Java EE 7 中很容易做到这一点。

    REST 资源类:

    package com.mycompany.maptojson.rest;
    
    import java.util.HashMap;
    import java.util.Map;
    import javax.ws.rs.Path;
    import javax.ws.rs.GET;
    import javax.ws.rs.Produces;
    import javax.enterprise.context.RequestScoped;
    
    @Path("maps")
    @RequestScoped
    public class MapToJson {
    
        @GET
        @Produces("application/json")
        public Map getJson() {
           Map<String, String> theMap = new HashMap<>();
           theMap.put("foo", "bar");
           return theMap;
        }
    }
    

    Application:

    package com.mycompany.maptojson.rest;
    
    import java.util.Set;
    import javax.ws.rs.core.Application;
    
    @javax.ws.rs.ApplicationPath("webresources")
    public class ApplicationConfig extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> resources = new java.util.HashSet<>();
            // following code can be used to customize Jersey 2.0 JSON provider:
            try {
                Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
                // Class jsonProvider = Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
                // Class jsonProvider = Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
                resources.add(jsonProvider);
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            addRestResourceClasses(resources);
            return resources;
        }
    
        private void addRestResourceClasses(Set<Class<?>> resources) {
            resources.add(com.mycompany.maptojson.rest.MapToJson.class);
        }
    }
    

    如您所见,您可以将不同的类配置为jsonProvider

    Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
    

    Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
    

    Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
    

    【讨论】:

      【解决方案3】:

      我知道这已经有一段时间了,但也许有人会觉得它有用。

      我遇到了类似的问题,在我看来,目前只有 Jackson 支持这种直接 Map 到 JSON 的映射。

      Jersey中,就像从资源方法返回地图一样简单:

      @Path("myResource")
      public class MyResource {
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Map<String, String> getMap() {
            Map<String, String> map = new HashMap<String, String>();
            map.put("some key", "some value");
            return map;
        }
      }
      

      并从客户端访问它:

      // ... (client initialization)
      Map<String, String> map = client.target().path("myResource").request("application/json").get(Map.class);
      

      使用 Jackson(相对于 MOXy),您需要手动注册 JacksonFeature,例如在您的 javax.ws.rs.core.Application 子类中(或 Jersey 中的 ResourceConfig):

      public class MyApp extends ResourceConfig {
        public MyApp() {
          super(MyResource.class, JacksonFeature.class);
        }
      }
      

      并确保在类路径中有 Jersey Jackson 模块。在 Maven 中,只需添加:

      <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>...</version>
      </dependency>
      

      如果没有 maven,添加所有依赖项可能会有点棘手。 就是这样,这应该有效。至少与 Jackson 供应商合作。

      它在 Jettison 中对我不起作用,并且 id 在 MOXy 中也不起作用(有一个 issue 打开)。

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        对我有用的解决方案(使用 jettison):

        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Response getJson() {
            Map<String, String> testMap = new HashMap<>();
            testMap.put("Key1", "value1");
            testMap.put("key2", "value2");
            JSONObject obj = new JSONObject(testMap);
        
            return Response.status(200).entity(obj).build();
        }
        

        【讨论】:

          【解决方案5】:

          默认情况下,Jersey 使用 MOXy XML/JSON 提供程序。所以如果你想使用 MOXy,你需要添加单独的适配器。 简单的解决方案是,从 pom.xml 中删除 MOXy 依赖项并添加 Jackson 依赖项。杰克逊会照顾好一切。

          <dependency>
              <groupId>org.glassfish.jersey.media</groupId>
              <artifactId>jersey-media-json-jackson</artifactId>
              <version>{latest version}</version>
          </dependency>
          

          抱歉,我不确定为什么 MOXy 是 Jeresey 的默认提供程序。

          public class BeanClass{
              private int duration, Id;
              private String description;
              private User user = new User();
              Map<String, String> map = new HashMap<>();
           }
          
          
          @GET
          @Produces({ MediaType.APPLICATION_JSON }) // , MediaType.APPLICATION_XML
          public Response getAll() {
                  List<BeanClass> lstBean = ...
                  return Response.ok().entity(lstBean).build();
          }
          

          谢谢,

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-07
            • 2023-03-14
            • 1970-01-01
            • 1970-01-01
            • 2016-07-27
            • 2011-04-22
            相关资源
            最近更新 更多