使用JAX-RS消耗JSON字符串

时间:2016-06-30 14:14:15

标签: java json jax-rs

由于RFC 7159,字符串可以是有效的JSON文档:

JSON-text = ws value ws
...
value = false / null / true / object / array / number / string
...
string = quotation-mark *char quotation-mark

因此,有效的JSON可以是"Hello World"

是否可以使用JAX-RS消耗这样的JSON字符串?

3 个答案:

答案 0 :(得分:7)

JAX-RS具有@Consumes注释,用于指定客户端发送的资源可以使用的MIME媒体类型。

以下是接受application/json媒体类型的请求的示例:

@Path("/foo")
public class FooResource {

    @POST
    @Consumes("application/json")
    public Response bar(InputStream entity) {
        return Response.ok.build();
    }

}

如果您发送标头为Content-Type: application/json的请求,则状态为200 OK的回复将返回给您。但是,如果您发送标头为Content-Type: application/xml的请求,则会返回406 Not Acceptable的回复。这是因为@Consumes指定使用JSON的请求是可接受的而不是其他的。

您可以观察到@Consumes注意到如何解析请求实体,但指定应接受哪种媒体类型。

您可以看到上面的示例的参数为InputStream entity。它实际上是请求实体。您可以使用JSON解析器库解析bar的资源方法,例如Jackson

@POST
@Consumes("application/json")
public Response bar(InputStream entity) {
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.readValue(inputStream, String.class);
    System.out.println(json);
    return Response.ok.build();
}

如果您发送带有“Hello World”主体的请求,您将在控制台中看到“Hello World”。这是因为Jackson知道如何解析RFC 7159中指定的JSON文档,而不是JAX-RS。

事实上,像RESTEasy这样的JAX-RS实现已经对流行的JSON解析器库提供了JSON支持。因此,您可以按如下方式创建资源方法:

@POST
@Consumes("application/json")
public Response bar(String json) {
    System.out.println(json);
    return Response.ok.build();
}

你应该得到相同的结果。

在幕后,JAX-RS有MessageBodyReader将HTTP请求主体转换为Java对象。它是类提供从表示到相应Java类型的映射服务。例如,jackson-jaxrs-providers为JSON数据格式实现了JAX-RS MessageBodyReaderMessageBodyWriter处理程序。

有关JAX-RS的更多详细信息,您可以查看JSR-000339 JAX-RS 2.0 Specification

答案 1 :(得分:3)

是的,有可能:

@Path("foo")
public class Foo {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response biz(String json) {
        return Response.ok(json).build();
    }
}

您的请求就像:

curl -X POST --header 'Content-Type: application/json' \
             --header 'Accept: application/json' \
             -d '"Hello World"' 'http://localhost:8080/api/foo'

答案 2 :(得分:0)

是的,这是可能的。

在JAX-RS上将您的方法定义为:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public void example(String s) { ... }

在客户端,将没有编码的有效负载发送到json,例如:

var payload = "helloworld"; // OK
...

而不是:

var payload = JSON.stringify("helloworld"); // KO
...