11

我有两个问题:

1.我可以创建一个类,用 JAXB 注释(用于 XML 支持)注释它并声明web.xml

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

JSON(杰克逊库)支持?或者我需要为 JSON 和 XML 分别创建两个类?

或者可能存在一些更优雅的方式来导致 REST 服务返回 JSON 和 XML?

2.如何以编程方式选择要返回的类型(JSON 或 XML)?

谢谢。

4

3 回答 3

9

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。


我可以创建一个类,使用 JAXB 注释(用于 XML 支持)对其进行注释并在 web.xml 中声明以支持 JSON(杰克逊库)吗?

您始终可以使用Application类来为 JSON 绑定指定MessageBodyReader/ MessageBodyWriter。我相信杰克逊在其 jar 中提供了一个实现。下面是一个将ApplicationMOXy 指定为 JSON 提供程序的类的示例:

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(2);
        set.add(MOXyJsonProvider.class);
        set.add(CustomerService.class);
        return set;
    }

}

或者我需要为 JSON 和 XML 分别创建两个类?

EclipseLink JAXB (MOXy) 提供原生 XML 绑定,旨在使您能够对 JSON 和 XML 使用相同的对象模型。您可以使用以下类将其集成到您的 JAX-RS 应用程序中MOXyJsonProvider


如何以编程方式选择要返回的类型(JSON 或 XML)?

服务器端

@Produces您可以使用注释指定您的服务同时提供 XML 和 JSON 消息。

@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("{id}")
public Customer read(@PathParam("id") long id) {
    return entityManager.find(Customer.class, id);
}

了解更多信息

客户端

您可以使用 MediaType 来指示消息的类型。下面是一个使用 Jersey 客户端 API 的示例。注意 URL 是一样的,只是请求的媒体类型不同。

Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/CustomerService/rest/customers");

// Get XML response as a Customer
Customer customer = resource.path("1")
    .accept(MediaType.APPLICATION_XML)
        .get(Customer.class);
System.out.println(customer.getLastName() + ", "+ customer.getFirstName());

// Get JSON response as a Customer
Customer customer = resource.path("1")
    .accept(MediaType.APPLICATION_JSON)
        .get(Customer.class);
System.out.println(customer.getLastName() + ", "+ customer.getFirstName());

了解更多信息

于 2012-07-08T11:16:10.203 回答
7

如果您的客户端想要使用 URL 的一部分来配置响应类型,您可以使用 Servlet 过滤器。

实现覆盖表示(媒体类型)的简单方法可以使用 URL 查询参数:

/resources/todo?format=json

Servlet 过滤器解析 URL 查询参数,如果 format=json 存在,则替换或添加接受标头“application/json”。

于 2012-07-08T11:09:22.210 回答
4

不需要单独的类,您需要的是单独的方法:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Todo getXML() {
    Todo todo = new Todo();
    todo.setSummary("This is my first todo");
    todo.setDescription("This is my first todo");
    return todo;
}

然后在客户端,当您请求服务时,您需要以什么格式指示它:

// Get XML
System.out.println(service.path("rest").path("todo").accept(MediaType.TEXT_XML).get(String.class));
// Get XML for application
System.out.println(service.path("rest").path("todo").accept(MediaType.APPLICATION_XML).get(String.class));
// Get JSON for application
System.out.println(service.path("rest").path("todo").accept(MediaType.APPLICATION_JSON).get(String.class));
于 2012-07-08T09:58:41.760 回答