Reputation: 4177
Due to RFC 7159, a string can be a valid JSON document:
JSON-text = ws value ws
...
value = false / null / true / object / array / number / string
...
string = quotation-mark *char quotation-mark
Thus, a valid JSON can be "Hello World"
.
Is it possible consume such a a JSON string with JAX-RS?
Upvotes: 10
Views: 24063
Reputation: 1
Yes, it's possible.
On JAX-RS define your method as:
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void example(String s) { ... }
On client side, send the payload without encoding to json, e.g:
var payload = "helloworld"; // OK
...
Rather than:
var payload = JSON.stringify("helloworld"); // KO
...
Upvotes: 0
Reputation: 11619
JAX-RS has a @Consumes
annotation to specify the MIME media types of representations a resource can consume that were sent by the client.
Following is an example to accept a request with a application/json
media type:
@Path("/foo")
public class FooResource {
@POST
@Consumes("application/json")
public Response bar(InputStream entity) {
return Response.ok.build();
}
}
If you send a request with a header of Content-Type: application/json
, a response with a 200 OK
status will return to you. But if you send a request with a header of Content-Type: application/xml
, a response with 406 Not Acceptable
will return. It is because @Consumes
specify that request with JSON is acceptable but not others.
You can observe that @Consumes
is noting about how to parse a request entity, but specify what media type should be accepted.
You can see that the above example has a parameter of InputStream entity
. It is in fact the request entity. You can parse in the resource method of bar
with a JSON parser library, e.g. 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();
}
If you send a request with a body of "Hello World", you will see "Hello World" in your console. This is because Jackson
know how to parse a JSON document specified in RFC 7159, but not JAX-RS.
In fact, JAX-RS implementation like RESTEasy already have JSON support with popular JSON parser library. Therefore you can simply create a resource method as follows:
@POST
@Consumes("application/json")
public Response bar(String json) {
System.out.println(json);
return Response.ok.build();
}
You should get the same result.
Behind the scenes, JAX-RS has MessageBodyReader to convert HTTP request body to Java object. It is the class provide mapping services from representation to a corresponding Java type. For example, jackson-jaxrs-providers implements JAX-RS MessageBodyReader
and MessageBodyWriter
handlers for JSON data formats.
For more details about JAX-RS, you can have a look to JSR-000339 JAX-RS 2.0 Specification
Upvotes: 16
Reputation: 130907
Yes, it's possible:
@Path("foo")
public class Foo {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response biz(String json) {
return Response.ok(json).build();
}
}
And your request would be like:
curl -X POST --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
-d '"Hello World"' 'http://localhost:8080/api/foo'
Upvotes: 3