Java Jersey/JAX-RS:以 XML/JSON 形式返回地图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18926505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:34:01  来源:igfitidea点击:

Jersey/JAX-RS: Return a Map as XML/JSON

javajerseyjax-rs

提问by ktm5124

It's not so obvious how to return a Mapas an XML/JSON document using the Jersey/JAX-RS framework. It already has support for Lists, but when it comes to Maps, there is no MessageBodyWriter. And even if I were to embed the Mainto a wrapper class, there is no maptype in XML schema.

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

Any practical advice on how to marshal a Map into an XML/JSON document in Jersey?

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

采纳答案by NoisyBoy

I know its very late to reply, but I'm hoping it will help somebody someday :) The easiest and quickest fix I applied is

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

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

Output: { "1": "abc", "2": "def", "3": "ghi" }

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

This should definitely help you solve your trouble.

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

回答by ktm5124

It is very easy to do this in Java EE 7.

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

The REST Resource class:

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;
    }
}

The Application:

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.Hymanson.HymansonFeature");
            // 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);
    }
}

As you can see, you can configure different classes as jsonProvider:

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

Class.forName("org.glassfish.jersey.Hymanson.HymansonFeature");

or

或者

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

or

或者

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

回答by AdamL

I know it's been a while already, but maybe someone will find it useful.

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

I am having a similar problem and to me it looks like, that only Hymansoncurrently supports this sort of direct Map to JSON mapping.

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

In Jersey, it is as easy as returning the map from the resource method:

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;
  }
}

and accessing it from the client as:

并从客户端访问它:

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

With Hymanson(as opposed to MOXy), you need to register the HymansonFeaturemanually, e.g. in your javax.ws.rs.core.Applicationsubclass (or ResourceConfigin Jersey):

随着Hyman逊(而不是莫西),您需要注册HymansonFeature您的手工,如javax.ws.rs.core.Application子类(或ResourceConfig泽西):

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

And be sure to have Jersey Hymanson moduleon classpath. In maven, simply add:

并确保在类路径上有Jersey Hymanson 模块。在 maven 中,只需添加:

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

without maven, it might be a bit more tricky to add all the dependencies. And that's all, this should work. At least with Hymansonprovider.

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

It did not work for me in Jettisonand id does not work in MOXyyet (there's an issueopen).

它在Jettison 中对我不起作用,而 id 在MOXy中也不起作用(有一个问题未解决)。

Hope this helps.

希望这可以帮助。

回答by Benav

The solution that worked for me (Using 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();
}

回答by Anudeep Abraham

By default, Jersey uses MOXy XML/JSON provider. So if you want to use MOXy, you need to add separate adapter. The simple solution is, remove MOXy dependency from pom.xml and add Hymanson dependency. Hymanson will take care of everything.

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

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

Sorry,I'm not sure why MOXy is the default provider in Jeresey.

抱歉,我不确定为什么 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();
}

Thanks,

谢谢,