QUESTION:
Is it possible to extract the original message body string (i.e., XML string or JSON string) - within the "post()" method - of a REST service?
Environment
Java 8
WebLogic 12.1.3 (w/ jax-rs(2.0,2.5.1) deployable library)
(The "request.getInputStream()" yields nothing... Seems that "read()" has already been applied "internally". Also, "mark()" or "reset()" is not supported)
"post()" method...
package aaa.bbb.ccc;
import javax.ejb.Stateless;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import aaa.bbb.ccc.fieldslist.FieldsList;
import java.io.*;
import java.net.URI;
import javax.ws.rs.core.*;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Stateless
@Path("/fieldsList")
public class Testws {
private static final Logger LOG = LogManager.getLogger(Testws.class);
public Testws() {
}
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response post(@Context UriInfo uriInfo, @Context javax.servlet.http.HttpServletRequest request, FieldsList fieldsList) throws IOException, JAXBException, Exception {
try {
//...returns empty string...
String s = IOUtils.toString(request.getInputStream(), "UTF-8");
LOG.info("message string from request.getInputStream()=" + s); <== empty string...
} catch (Exception e) {
e.printStackTrace();
}
URI uri = UriBuilder.fromUri(uriInfo.getRequestUri()).build();
Response response = Response.created(uri).build();
return response;
}
}
I've tried using an interceptor (see "aroundReadFrom()" method) to manipulate the InputStream before it is used by the post() method, but, to no effect... -That is, in the REST service's post() method, the request.getInputStream() continues to yield nothing...
"aroundReadFrom()" method...
package aaa.bbb.ccc;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Provider
public class MyReaderInterceptor implements ReaderInterceptor {
static final Logger LOG = LogManager.getLogger(MyReaderInterceptor.class);
@Override
public Object aroundReadFrom(ReaderInterceptorContext ctx) throws IOException {
try {
InputStream is = ctx.getInputStream();
byte[] content = IOUtils.toByteArray(is);
is.close();
ctx.setInputStream(new ByteArrayInputStream(content));
return ctx.proceed();
} catch (IOException | WebApplicationException e) {
e.printStackTrace();
}
return null;
}
}
Here is the test xml message...:
<?xml version="1.0" encoding="UTF-8"?>
<FieldsList xmlns="http://aaa.bbb.ccc.ws/testws">
<Fields>
<FieldA>fieldA_value</FieldA>
<FieldB>fieldB_value</FieldB>
<FieldC>fieldC_value</FieldC>
</Fields>
</FieldsList>
Here is the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
targetNamespace="http://aaa.bbb.ccc.ws/testws"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:tw="http://aaa.bbb.ccc.ws/testws"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="FieldsType">
<xs:all>
<xs:element name="FieldA" type="xs:string" minOccurs="0" />
<xs:element name="FieldB" type="xs:string" minOccurs="0" />
<xs:element name="FieldC" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
<xs:element name="FieldsList">
<xs:complexType>
<xs:sequence>
<xs:element name="Fields" type="tw:FieldsType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
UPDATE:
Within the post() method I've only been able to reconstruct message string using this technique...
StringWriter sw = new StringWriter();
JAXBContext.newInstance(FieldsList.class).createMarshaller().marshal(fieldsList, sw);
System.out.println("posted xml string=" + sw.toString());
...However, this would not help if the same data is posted in JSON format. To clarify, it will reconstruct the JSON post message as an XML string rather than the original JSON string
Again, I what I'm trying to do is access the original posted XML/JSON message string within the post() method