Reputation: 439
I know this question has been asked several times but I am still stuck even after doing all what have been provided on those answers. I am new to java EE and before working with Spring framework I would like to have a solid foundation. So my issue is I am not able to accept/process the json request sent to a simple Java Rest API. I have a front end webpage calling the java rest API. But even through "PostMan" I am getting the same error
"HTTP Status 415 – Unsupported Media Type"
I have a simple controller class with two methods. The Get method which accepts String is working fine. But the issue is with the Post method. I have header value as "content-type:application/json"
. But still the issue remains same
I just want to understand few things. I have a java class with exact field names as of json request. But my understanding is @Consumes(MediaType.APPLICATION_JSON) annotation is enough for Jax RS to parse the json request to java object. Or do I need to have any other annotation on my class level ? here is my whole project.
I am also not sure about the dependencies I have defined in pom.xml
.
A help would be greatly appreciated. Thanks in advance.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thomsoncodes</groupId>
<artifactId>demobank</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>demobank</name>
<build>
<finalName>demobank</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
-->
</dependencies>
<properties>
<jersey.version>2.16</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
My Controller Class
@Path("/customerinfo")
public class CustomerInfoController {
@POST
@Path("/greeting")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public String greetings(String message) {
return "Hello " + message;
}
@POST
@Path("/newcustomer")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createNewCustomer(Customer customer) {
String result = "New customer is created : " + customer;
return Response.status(201).entity(result).build();
}
}
My Object Class
public class Customer {
private String firstName;
private String midName;
private String lastName;
private String citizenship;
private String dob;
private String ssn;
private String city;
private String state;
private String country;
private String email;
private String phone;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMidName() {
return midName;
}
public void setMidName(String midName) {
this.midName = midName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCitizenship() {
return citizenship;
}
public void setCitizenship(String citizenship) {
this.citizenship = citizenship;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Here is the Postman request body
Method - POST
Header - content-type:application/json
Body - {
"firstName" : "John",
"midName" : "Null",
"lastName" : "Doe",
"citizenship" : "USA",
"dob" : "MM/DD/YYYY",
"ssn" : "1868138163",
"city" : "City",
"state" : "State","country" : "USA",
"email":"[email protected]",
"phone" : "1234567890"
}
Upvotes: 1
Views: 2974
Reputation: 209092
But my understanding is @Consumes(MediaType.APPLICATION_JSON) annotation is enough for Jax RS to parse the json request to java object
No. That's not what it does. It's purpose is for content negotiation, as mentioned in this post.
What actually does the (de)serialization is the Entity provider (or MessageBodyReader/Wrider). And if a provider is not found to handle the conversion, you will get a 415 error. In your case, the JSON provider you are using is MOXy, you can see it in your dependencies
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
-->
The thing with MOXy is that it is built on top of JAXB, and as such, it requires usage of the same annotations. With JAXB, we need to annotate our models with @XmlRootElement
. So if you add that to your model class, it should work.
If you don't want to have to use the annotation, you can use Jackson instead of MOXy, which I would recommend anyway. Just changed the above artifactId to jersey-media-json-jackson
.
Upvotes: 2