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.
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.
HTTP Error 415 Unsupported Media Type on REST service operation with an XML parameter (Jersey + Jetty )
There's a missconfiguration of the maven-shade plugin. Replacing it by
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
solves the problem
415 Unsupported media type on java rest service when uploading file
@RequestParam
and MultipartFile
are both things that are for Spring not Jersey. For Jersey what you want to use is the annotation @FormDataParam
and for the parameter, depending on the part type you can have a number of different type of parameters. If the part is a file, you could use an InputStream
, File
, or byte[]
parameter, or if the part is some plain text, you could have String parameter. If you want the filename, you can add a FormDataContentDisposition
parameter alongside the part entity parameters. Below is an example
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response upload(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fdcd,
@FormDataParam("file-detail") String fileDetail) {
}
To make this work, you need to register the MultiPartFeature
with your application. You can see this post for ways you can register it.
See also:
- File upload along with other object in Jersey restful web service
- Jersey documentation for Multipart support
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 415 Unsupported Media Type
How our objects are serialized and deserialized to and from the response stream and request stream, is through MessageBodyWriter
s and MessageBodyReader
s.
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
Related Topics
Setting Custom Actionbar Title from Fragment
Why Does the Jvm Consume Less Memory Than -Xms Specified
Post to Jersey Rest Service Getting Error 415 Unsupported Media Type
Why Does Hibernate Require No Argument Constructor
Java Count Occurrence of Each Item in an Array
Differencebetween Persist() and Merge() in JPA and Hibernate
How to Read the Value of a Annotation in Java
How to Understand Happens-Before Consistent
When Are Static Variables Initialized
Java Compiled Classes Contain Dollar Signs
How to Scroll a Scrollview Programmatically in Android
Java Embedded Databases Comparison
Recommended Jsf 2.0 Crud Frameworks
Why Does JPA Have a @Transient Annotation