Jersey 415 Unsupported Media Type

2019-01-02 21:43发布

问题:

I have been trying since hours to correct http error 415 Unsupported Media Type but it is still showing media unsupported page. I am adding headers application/json in Postman.

Here is my Java Code

package lostLove;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;  
import javax.ws.rs.POST;
import javax.ws.rs.Path;  
import javax.ws.rs.PathParam;  
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; 

import org.json.JSONObject;


@Path("/Story") 
public class Story {

      @POST
      @Consumes({"application/json"})
      @Produces(MediaType.APPLICATION_JSON)
    //  @Consumes(MediaType.APPLICATION_JSON)
    //  @Path("/Story") 
      public JSONObject sayJsonTextHello(JSONObject inputJsonObj) throws Exception {

        String input = (String) inputJsonObj.get("input");
        String output = "The input you sent is :" + input;
        JSONObject outputJsonObj = new JSONObject();
        outputJsonObj.put("output", output);

        return outputJsonObj;
      }

      @GET  
      @Produces(MediaType.TEXT_PLAIN)  

      public String sayPlainTextHello() {  
        return "hello";
      }

}

here is my web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>LostLove</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
 <servlet>  
    <servlet-name>Jersey REST Service</servlet-name>  
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>  
    <init-param>  
        <param-name>jersey.config.server.provider.packages</param-name>  
        <param-value>lostLove</param-value>  
    </init-param>  
    <load-on-startup>1</load-on-startup>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>Jersey REST Service</servlet-name>  
    <url-pattern>/rest/*</url-pattern>  
  </servlet-mapping>
</web-app>

回答1:

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


回答2:

Its because of following issue:

JAX-RS does not support default Jackson mapping conversion. So if you have the ajax request as below(Post):

 jQuery.ajax({
           url: "http://localhost:8081/EmailAutomated/rest/service/save",
            type: "POST",
            dataType: "JSON",
            contentType: "application/JSON",
            data: JSON.stringify(data),
            cache: false,
            context: this,
            success: function(resp){  
                 // we have the response  
                 alert("Server said123:\n '" + resp.name + "'");  
               },  
               error: function(e){  
                 alert('Error121212: ' + e);  
               }  
        });

and in JAX-RS controller side you need to do like below:

@Path("/save")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String saveDetailsUser(String userStr) {

    Gson gson = new Gson();
    UserDetailDTO userDetailDTO = gson.fromJson(userStr, UserDetailDTO.class);

    String vemail = userDetailDTO.getEMAIL();

    return "userDetailDTO";
}

Here please make sure on parameter. service is accepting json as String not the POJO.

Surely It will work. Thanks!



标签: