Jersey 415 Unsupported Media Type

POST to Jersey REST service getting error 415 Unsupported Media Type

The Jersey distribution doesn't come with JSON/POJO support out the box. You need to add the dependencies/jars.

Add all these

  • jersey-media-json-jackson-2.17
  • jackson-jaxrs-json-provider-2.3.2
  • jackson-core-2.3.2
  • jackson-databind-2.3.2
  • jackson-annotations-2.3.2
  • jackson-jaxrs-base-2.3.2
  • jackson-module-jaxb-annotations-2.3.2
  • jersey-entity-filtering-2.17

With Maven, below will pull all the above in

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.17</version>
</dependency>

For any future readers not using Jersey 2.17 (and using jars directly instead of Maven), you can go here to find the Jersey version you are using, and see what transitive dependency versions you need. The current version of this Jersey dependency uses Jackson 2.3.2. That's the main thing you need to look out for.

Jersey 415 Unsupported Media Type

How our objects are serialized and deserialized to and from the response stream and request stream, is through MessageBodyWriters and MessageBodyReaders.

What will happens is that a search will be done from the registry of providers, for one that can handle JSONObject and media type application/json. If one can't be found, then Jersey can't handle the request and will send out a 415 Unsupported Media Type. You should normally get an exception logged also on the server side. Not sure if you gotten a chance to view the log yet.

Jersey doesn't have any standard reader/writer for the org.json objects. You would have to search the web for an implementation or write one up yourself, then register it. You can read more about how to implement it here.

Alternatively, you could accept a String and return a String. Just construct the JSONObject with the string parameter, and call JSONObject.toString() when returning.

@POST
@Consumes("application/json")
@Produces("application/json")
public String post(String jsonRequest) {
JSONObject jsonObject = new JSONObject(jsonRequest);
return jsonObject.toString();
}

My suggestion instead would be to use a Data binding framework like Jackson, which can handle serializing and deserializing to and from out model objects (simple POJOs). For instance you can have a class like

public class Model {
private String input;
public String getInput() { return input; }
public void setInput(String input) { this.input = input; }
}

You could have the Model as a method parameter

public ReturnType sayJsonTextHello(Model model)

Same for the ReturnType. Just create a POJO for the type you wan to return. The JSON properties are based on the JavaBean property names (getters/setters following the naming convention shown above).

To get this support, you can add this Maven dependency:

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.17</version> <!-- make sure the jersey version
matches the one you are using -->
</dependency>

Or if you are not using Maven, you can see this post, for the jars you can download independently.

Some resources:

  • Jersey JSON support
  • Jackson documentation

POST with jersey Java return 415 unsupported media type

JSON providers

The org.json library doesn't integrate with Jersey. Hence the JSON won't be parsed automatically into a POJO and vice versa.

You'd better use one of the following modules to provide JSON support. All of them integrate with Jersey 2.x:

  • MOXy
  • Java API for JSON Processing (JSON-P)
  • Jackson
  • Jettison

Using Jackson as a JSON provider for Jersey

I would recommend Jackson. The steps to use Jackson as a JSON provider are fully described in this answer and they are summarized below:

Add the jersey-media-json-jackson module to your pom.xml:

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25.1</version>
</dependency>

If you're not using Maven make sure to have all the jersey-media-json-jackson dependencies on the classpath.

Then register the JacksonFeature in your Application / ResourceConfig subclass:

@ApplicationPath("/api")
public class MyApplication extends Application {

@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(JacksonFeature.class);
return classes;
}
}
@ApplicationPath("/api")
public class MyApplication extends ResourceConfig {

public MyApplication() {
register(JacksonFeature.class);
}
}

For more details, check the Jersey documentation.

Java Jersey Consume Response is giving back 415 (unsupported media type)

The Waypoint.java produces an xml and @Path("/waypoint") seems to consume a JSON as well as produce a JSON. I think thats why you are getting unsupported media type error

Jersey api return 415 unsupported media type when using MULTIPART_FORM_DATA

Use a different client that knows how to specifically send files as multipart. You generally don't want to manually create the request (or set the Content-Type header) when it comes to multipart as the it is a little more complicated than a normal request. For example, this a what a multipart request looks like

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

See more a W3c

One client you can use is Postman. Or if you are going to automate the test (in an integration test, you can use the Jersey client support for multipart

415 unsupported media type in java jersey

The problem is your method parameter type MultivaluedHashMap

public Activity createActivityParams(MultivaluedHashMap<String, String> formse){

The provider that handle application/x-www-form-urlencoded and MultivaluedMap, only supports MultivaluedMap or MultivaluedMap<String, String> injections. You can see in the source code

@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
// Only allow types MultivaluedMap<String, String> and MultivaluedMap.
return type == MultivaluedMap.class
&& (type == genericType || mapType.equals(genericType));
}

So just change the method parameter to MultivaluedMap<String, String>



Related Topics



Leave a reply



Submit