Jersey/JAX-RS:将地图作为XML/JSON返回

ktm*_*124 20 java jax-rs jersey

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

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

小智 8

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

@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();
}
Run Code Online (Sandbox Code Playgroud)

输出:{"1":"abc","2":"def","3":"ghi"}

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


小智 7

在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
Run Code Online (Sandbox Code Playgroud)

要么

Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
Run Code Online (Sandbox Code Playgroud)

要么

Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
Run Code Online (Sandbox Code Playgroud)


Ada*_*amL 7

我知道它已经有一段时间了,但也许有人会发现它很有用.

我遇到了类似的问题,而且看起来,只有杰克逊目前支持这种直接映射到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;
  }
}
Run Code Online (Sandbox Code Playgroud)

并从客户端访问它:

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

使用Jackson(而不是MOXy),您需要JacksonFeature手动注册,例如在javax.ws.rs.core.Application子类中(或ResourceConfigJersey中):

public class MyApp extends ResourceConfig {
  public MyApp() {
    super(MyResource.class, JacksonFeature.class);
  }
}
Run Code Online (Sandbox Code Playgroud)

并且一定要在类路径上安装Jersey Jackson模块.在maven中,只需添加:

<dependency>
  <groupId>org.glassfish.jersey.media</groupId>
  <artifactId>jersey-media-json-jackson</artifactId>
  <version>...</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

没有maven,添加所有依赖项可能会有点棘手.这就是全部,这应该有效.至少与杰克逊提供商.

它在Jettison中对我不起作用,id在MOXy不起作用(打开了一个问题).

希望这可以帮助.