As we saw in previous tutorials, JAX-RS supports extracting request values and mapping them into Java fields, properties and parameters using annotations such as @HeaderParam, @QueryParam, etc. JAX-RS also supports mapping of request body. In that case we don't have to use any JAX-RS annotations. such parameter is called entity parameter. Let's understand meaning of entity parameter with quick examples.
Examples
@Path("/")
public class ResourceExample {
@Path("/test1")
@POST
public String handle(String entityParam) {
System.out.println(entityParam);
return "entity parameter: " + entityParam;
}
.............
}
Note that we used @POST on our resource method, that's because a body message is only sent via HTTP POST OR PUT request.
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run
Sending plain text message body
Let's write a rest client with JAX-RS client API:
public class MyClient1 {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/test1");
String response = target.request()
.post(Entity.entity("test body", MediaType.TEXT_PLAIN_TYPE), String.class);
System.out.println(response);
}
} Outputentity parameter: test body
Note that in above client example, we used MediaType.TEXT_PLAIN_TYPE ; that is actually Content-Type header (specifies body content type). On server resource method, we didn't use any @Produces or @Consumes annotation, that's because by default all request/response media types are supported; check out our this tutorial for more details.
Sending XML message body
public class MyClient2 {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/test1");
String entity = "<myMsg><id>2</id><msg>hello</msg></myMsg>";
String response = target.request()
.post(Entity.entity(entity, MediaType.TEXT_XML), String.class);
System.out.println(response);
}
} Outputentity parameter: <myMsg><id>2</id><msg>hello</msg></myMsg>
Mapping message body to Java types
In JAX-RS, request and response bodies are automatically mapped to and from Java types. The conversion is done by the installed MessageBodyReader and MessageBodyWriter.
In the following example, we are still sending raw XML body from the client but on the server side we are mapping message body to our Java type MyMsg.
@XmlRootElement
public class MyMsg {
private int id;
private String msg;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "MyMsg{" +
"id=" + id +
", msg='" + msg + '\'' +
'}';
}
}
In above Java type, we used @XmlRootElement; that's JAXB specific annotation and necessary for XML to/from Java object conversion. Please check out this tutorial for details.
The resource method:
@Path("/")
public class ResourceExample {
.............
@Path("/test2")
@POST
public String handle2(MyMsg entityParam) {
System.out.println(entityParam);
return "entity parameter: " + entityParam;
}
}
The client:
public class MyClient3 {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/test2");
String entity = "<myMsg><id>2</id><msg>hello</msg></myMsg>";
String response = target.request()
.post(Entity.entity(entity, MediaType.TEXT_XML), String.class);
System.out.println(response);
}
} Outputentity parameter: MyMsg{id=2, msg='hello'}
We can also use our Java type on the client side:
public class MyClient4 {
public static void main(String[] args) {
//Preparing entity
MyMsg myMsg = new MyMsg();
myMsg.setId(5);
myMsg.setMsg("hello");
//sending requests
Client client = ClientBuilder.newClient();
//sending to test1
WebTarget target = client.target("http://localhost:8080/test1");
String response = target.request()
.post(Entity.entity(myMsg, MediaType.TEXT_XML), String.class);
System.out.println(response);
//sending to test2
WebTarget target2 = client.target("http://localhost:8080/test2");
String response2 = target2.request()
.post(Entity.entity(myMsg, MediaType.TEXT_XML), String.class);
System.out.println(response2);
}
} Outputentity parameter: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><myMsg><id>5</id><msg>hello</msg></myMsg> entity parameter: MyMsg{id=5, msg='hello'}
Sending JSON message body
For JSON to Java type conversion to work, we have to use extra dependency of jersey-media-moxy (included in pom.xml in project browser below). Also we have to use same JAXB annotations on our Java type.
In the following example, we are using same entity class MyMsg and same resource uri but a new client which sends JSON message body:
public class MyClient5 {
public static void main(String[] args) {
//Preparing json message
String entity = "{\"msg\": \"hello\", \"id\": 5}";
//sending requests
Client client = ClientBuilder.newClient();
//sending to test1
WebTarget target = client.target("http://localhost:8080/test1");
String response = target.request()
.post(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), String.class);
System.out.println(response);
//sending to test2
WebTarget target2 = client.target("http://localhost:8080/test2");
String response2 = target2.request()
.post(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), String.class);
System.out.println(response2);
}
} Outputentity parameter: {"msg": "hello", "id": 5} entity parameter: MyMsg{id=5, msg='hello'}
Other examples
We can also use HTML based client for entity parameter mapping. Additionally, we can also return Java based entities from a resource method, which can be automatically converted to JSON or XML depending on the requested 'Accept' header value. Please visits our example links provided in 'see also' section below.
For other/custom media types to Java type conversion, we can write our own MessageBodyReader and MessageBodyWriter.
Example ProjectDependencies and Technologies Used: - jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
- jersey-media-moxy 2.25.1:
Jersey JSON entity providers support module based on EclipseLink MOXy.
- JDK 1.8
- Maven 3.3.9
|