I am using REST-Jersey
in my project. All the POST data is send in JSON
format and unmarshalled at server-side into respective beans. Something lik
You can get the POST Body from the Requests Input Stream. Try something like this:
@Override
public ContainerRequest filter(ContainerRequest req) {
try{
StringWriter writer = new StringWriter();
IOUtils.copy(req.getEntityInputStream(), writer, "UTF-8");
//This is your POST Body as String
String body = writer.toString();
}
catch (IOException e) {}
return req; }
You can only read the content once, because it's an input stream. If you pick it up in the interceptor then you won't be able to provide it in the main parsing.
What you need to do is to create a filter which reads the data and makes it available to anyone else who needs it. Basic steps are:
Here is one way you can implement, very similar to how Jersey implements its logging filters. You can read the entity and stick it back to the request, so you accidentally do not consume it in your filter.
import com.sun.jersey.api.container.ContainerException;
import com.sun.jersey.core.util.ReaderWriter;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class JerseyFilter implements ContainerRequestFilter {
@Override
public ContainerRequest filter(ContainerRequest request) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = request.getEntityInputStream();
final StringBuilder b = new StringBuilder();
try {
if (in.available() > 0) {
ReaderWriter.writeTo(in, out);
byte[] requestEntity = out.toByteArray();
printEntity(b, requestEntity);
request.setEntityInputStream(new ByteArrayInputStream(requestEntity));
}
return request;
} catch (IOException ex) {
throw new ContainerException(ex);
}
}
private void printEntity(StringBuilder b, byte[] entity) throws IOException {
if (entity.length == 0)
return;
b.append(new String(entity)).append("\n");
System.out.println("#### Intercepted Entity ####");
System.out.println(b.toString());
}
}
Do not use in.available()
method to check the total bytes of Inputstream. Some clients does not set this value. And in this case it will be foul eventhough the message body input stream exists.
InputStream in = request.getEntityInputStream();
final StringBuilder b = new StringBuilder();
try {
if (in.available() > 0)
Use below code
String json = IOUtils.toString(requestContext.getEntityStream(), Charsets.UTF_8);
messageBody = json;
InputStream in = IOUtils.toInputStream(json);
requestContext.setEntityStream(in);