如何使用 Java 通过 Web 服务以 JSON 格式公开数据?

Posted

技术标签:

【中文标题】如何使用 Java 通过 Web 服务以 JSON 格式公开数据?【英文标题】:How do I expose data in a JSON format through a web service using Java? 【发布时间】:2010-09-08 15:10:22 【问题描述】:

有没有一种简单的方法可以使用 java 以 JSON 格式将数据返回给 Web 服务客户端?我可以使用 servlet、spring 等。

【问题讨论】:

由于这是一个投票率很高的 java+json 问题,总结一下答案可能会很好;特别是因为这是一个相当老的问题,并且许多新选项已经可用(Spring MVC、Jersey/RESTeasy/CXF/Restlet;Gson/Jackson/FlexJSON) 在JSON output of a JAX-WS webservice中查看更多现代答案 【参考方案1】:

可能值得研究Jersey。 Jersey 可以轻松地将 restful web 服务公开为 xml 和/或 JSON。

一个例子...从一个简单的类开始

@XmlType(name = "", propOrder =  "id", "text" )
@XmlRootElement(name = "blah")
public class Blah implements Serializable 
    private Integer id;
    private String text;

    public Blah(Integer id, String text) 
        this.id = id;
        this.text = text;
        

    @XmlElement
    public Integer getId()  return id; 
    public void setId(Integer id)  this.id = id; 

    @XmlElement
    public String getText()  return text; 
    public void setText(String value)  this.text = value; 

然后创建一个资源

@Path("/blah")
public class BlahResource 
    private Set<Blah> blahs = new HashSet<Blah>();

    @Context
    private UriInfo context;

    public BlahResource() 
        blahs.add(new Blah(1, "blah the first"));
        blahs.add(new Blah(2, "blah the second"));
    

    @GET
    @Path("/id")
    @ProduceMime("application/json", "application/xml")
    public Blah getBlah(@PathParam("id") Integer id) 
        for (Blah blah : blahs) 
            if (blah.getId().equals(id)) 
                return blah;
            
        
        throw new NotFoundException("not found");
    

并暴露它。有很多方法可以做到这一点,例如使用 Jersey 的 ServletContainer。 (web.xml)

<servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

这就是您需要做的一切...弹出浏览器并浏览到http://localhost/blah/1。默认情况下,您将看到 XML 输出。如果您使用的是 FireFox,请安装 TamperData 并将您的 accept 标头更改为 application/json 以查看 JSON 输出。

显然还有更多内容,但Jersey 让所有这些事情变得非常简单。

祝你好运!

【讨论】:

绝对:Jersey 是用于基于 JSON/感知的 Web 服务的东西。【参考方案2】:

我们一直在使用 Flexjson 将 Java 对象转换为 JSON,并且发现它非常易于使用。 http://flexjson.sourceforge.net

这里有一些例子:

public String searchCars() 
  List<Car> cars = carsService.getCars(manufacturerId);
  return new JSONSerializer().serialize(cars);

它有一些很酷的功能,比如 deepSerialize 可以发送整个图,并且不会中断双向关系。

new JSONSerializer().deepSerialize(user); 

在服务器端格式化日期通常也很方便

new JSONSerializer().transform(
  new DateTransformer("dd/MM/yyyy"),"startDate","endDate"
).serialize(contract);

【讨论】:

FlexJSON 看起来是我见过的最好的 Java->JSON 序列化选项。但是我在另一端收到了 Java ......对反序列化有什么建议吗? 可以使用 flexjson JSONDeserializer 来完成这项工作。我正在使用这两种方式都没有问题。【参考方案3】:

对我来说,the best Java <-> JSON parser is XStream(是的,我说的是 json,而不是 xml)。 XStream 已经处理了循环依赖,并且有一个简单而强大的 api,您可以在其中编写自己的驱动程序、转换器等。

亲切的问候

【讨论】:

小问题:XStream 不是 JSON 解析器。它是一个对象序列化器,可以使用 Jettison 读取/写入 JSON,它使用 json.org 解析器并使用 Stax XML API 进行装饰。【参考方案4】:

http://www.json.org/java/index.html 有你需要的。

【讨论】:

【参考方案5】:

是的!查看json-lib

这是一个来自我自己的代码的简化代码 sn-p,它发送一组我的域对象:

private String getJsonDocumenent(Object myObj) (
    String result = "oops";
    try 
        JSONArray jsonArray = JSONArray.fromObject(myObj);

        result = jsonArray.toString(2);  //indent = 2

     catch (net.sf.json.JSONException je) 

        throw je;
    
    return result;

【讨论】:

出于好奇...是否有任何理由将结果初始化为“哎呀”?该方法永远无法返回该值,不是吗? 我只是为 sn-p 做的——我的生产代码实际上是从中获取的,它实际上并没有抛出异常,而是一个字符串 constance json 文档供客户端应用程序很好地消化。 【参考方案6】:

我发现 google-gson 很有吸引力。它转换为 JSON 并返回。 http://code.google.com/p/google-gson/ 它非常灵活,可以直接处理对象的复杂性。我喜欢它对泛型的支持。

/*
* we're looking for results in the form
* "id":123,"name":thename,"id":456,"name":theOtherName,...
*
* TypeToken is Gson--allows us to tell Gson the data we're dealing with
* for easier serialization.
*/
Type mapType = new TypeToken<List<Map<String, String>>>().getType();

List<Map<String, String>> resultList = new LinkedList<Map<String, String>>();

for (Map.Entry<String, String> pair : sortedMap.entrySet()) 
    Map<String, String> idNameMap = new HashMap<String, String>();
    idNameMap.put("id", pair.getKey());
    idNameMap.put("name", pair.getValue());
    resultList.add(idNameMap);


return (new Gson()).toJson(resultList, mapType);

【讨论】:

【参考方案7】:

对于 Java 中的 RESTful Web 服务,还可以查看 Restlet API,它为 REST Web 服务(服务器和客户端,在容器中或独立)提供了非常强大和灵活的抽象,并且还与 Spring 和 JSON 很好地集成.

【讨论】:

【参考方案8】:

如前所述,Jersey (JAX-RS impl) 是要使用的框架;但对于 Java 对象与 JSON 的基本映射,Tutorial 很好。与许多替代方案不同,它不使用奇怪的 XML 兼容性约定,而是读取和写入直接映射到对象和从对象映射的干净 JSON。它对于 null(缺少条目和具有 null 的条目之间存在差异)、空列表或字符串(两者都与 null 不同)也没有问题。

Jackson 也可以很好地与 Jersey 配合使用,可以使用 JAX-RS 提供程序 jar,甚至可以手动操作。 同样,它也很容易与普通的旧 servlet 一起使用;只需获取输入/输出流,调用 ObjectMapper.readValue() 和 .writeValue() 即可。

【讨论】:

【参考方案9】:

我一直在使用 jaxws-json,用于提供 JSON 格式的 Web 服务。你可以查看项目https://jax-ws-commons.dev.java.net/json/。

这是一个不错的项目,一旦你上手,你就会发现它有多迷人。

【讨论】:

你能提供更多的细节吗?特别是如果我们只想通过更改端点将现有的 jaxb(SOAP) 服务转换为 JSON? 它是对现有 jaxws 的扩展。它不会像启用 SOAP 那样发布 Web 服务,而是让 Web 服务理解 JSON(只需添加 @BindingType(JSONBindingID.JSON_BINDING))。 对于客户端,应该使用JSON而不是通过SOAP进行通信。您可能会发现编译源代码有点乏味。但是,在正确生成 JAR 之后,使用它变得相当容易。他们在那里做得非常好。实际上,这是我找到的唯一“真正”的 JSON 绑定解决方案。

以上是关于如何使用 Java 通过 Web 服务以 JSON 格式公开数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作一个 web 服务(最好使用 PHP),它可以被 android 应用程序请求以获取 JSON 对象

在 Web 服务 java 中返回 json 结果

如何通过 Rails 中的 JSON 接口上传文件

如何在 .NET WCF 中保护 HTTP JSON Web 服务

如何通过 AFNetWorking 2.0 将 JSON 格式的数据发送到 Web? [复制]

如何对 Zend Web 应用程序和 Zend JSON-RPC 服务器使用相同的“后端”代码?