Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As already suggested, changing the <code>@Consumes</code> Content-Type to <code>text/plain</code> will work, but it doesn't seem right from an REST API point of view.</p> <p>Imagine your customer having to POST JSON to your API but needing to specify the Content-Type header as <code>text/plain</code>. It's not clean in my opinion. In simple terms, if your API accepts JSON then the request header should specify <code>Content-Type: application/json</code>.</p> <p>In order to accept JSON but serialize it into a <code>String</code> object rather than a POJO you can implement a custom <a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/MessageBodyReader.html" rel="noreferrer">MessageBodyReader</a>. Doing it this way is just as easy, and you won't have to compromise on your API spec.</p> <p>It's worth reading the docs for <a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/MessageBodyReader.html" rel="noreferrer">MessageBodyReader</a> so you know exactly how it works. This is how I did it:</p> <p><strong>Step 1. Implement a custom <a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/MessageBodyReader.html" rel="noreferrer">MessageBodyReader</a></strong></p> <pre><code>@Provider @Consumes("application/json") public class CustomJsonReader&lt;T&gt; implements MessageBodyReader&lt;T&gt; { @Override public boolean isReadable(Class&lt;?&gt; type, Type genericType, Annotation[] annotations,MediaType mediaType) { return true; } @Override public T readFrom(Class&lt;T&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap&lt;String, String&gt; httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { /* Copy the input stream to String. Do this however you like. * Here I use Commons IOUtils. */ StringWriter writer = new StringWriter(); IOUtils.copy(entityStream, writer, "UTF-8"); String json = writer.toString(); /* if the input stream is expected to be deserialized into a String, * then just cast it */ if (String.class == genericType) return type.cast(json); /* Otherwise, deserialize the JSON into a POJO type. * You can use whatever JSON library you want, here's * a simply example using GSON. */ return new Gson().fromJson(json, genericType); } }</code></pre> <p>The basic concept above is to check if the input stream is expected to be converted to a <code>String</code> (specified by <code>Type genericType</code>). If so, then simply cast the JSON into the specified <code>type</code> (which will be a <code>String</code>). If the expected type is some sort of POJO, then use a JSON library (e.g. Jackson or GSON) to deserialize it to a POJO.</p> <p><strong>Step 2. Bind your <a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/MessageBodyReader.html" rel="noreferrer">MessageBodyReader</a></strong></p> <p>This depends on what framework you're using. I find that Guice and Jersey work well together. Here's how I bind my <a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/MessageBodyReader.html" rel="noreferrer">MessageBodyReader</a> in Guice:</p> <p>In my <a href="http://jersey.java.net/nonav/apidocs/1.8/contribs/jersey-guice/com/sun/jersey/guice/JerseyServletModule.html" rel="noreferrer">JerseyServletModule</a> I bind the reader like so --</p> <pre><code>bind(CustomJsonReader.class).in(Scopes.SINGLETON);</code></pre> <p>The above <code>CustomJsonReader</code> will deserialize JSON payloads into POJOs as well as, if you simply want the raw JSON, <code>String</code> objects.</p> <p>The benefit of doing it this way is that it will accept <code>Content-Type: application/json</code>. In other words, your request handler can be set to consume JSON, which seems proper:</p> <pre><code>@POST @Path("/stuff") @Consumes("application/json") public void doStuff(String json) { /* do stuff with the json string */ return; }</code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload