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 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
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
How to Retrieve Value from Jtextfield in Java Swing
Why Does This Go into an Infinite Loop
Why Do We Need Immutable Class
Return Generated PDF Using Spring MVC
How to Open a File with the Default Associated Program
Intellij Idea Java Classes Not Auto Compiling on Save
Print "Hello World" Every X Seconds
How to Customise the Jackson JSON Mapper Implicitly Used by Spring Boot
Java.Util.Date Format Ssssss: If Not Microseconds What Are the Last 3 Digits
How to Convert a String to Double in Java Using a Specific Locale
Embed a Jre in a Windows Executable
Java.Lang.Illegalaccesserror: Tried to Access Method
Java Regular Expression to Extract Content Within Square Brackets
Spring Java Config: How to Create a Prototype-Scoped @Bean with Runtime Arguments