java Jersey 415 不支持的媒体类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30692221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:31:03  来源:igfitidea点击:

Jersey 415 Unsupported Media Type

javajsonrestjerseyjax-rs

提问by cham3333

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

我几个小时以来一直在尝试纠正 http 错误,415 Unsupported Media Type但它仍然显示媒体不受支持的页面。我正在application/jsonPostman 中添加标题。

Here is my Java Code

这是我的 Java 代码

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.xmlfile

这是我的web.xml文件

<?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>

回答by Paul Samsotha

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

我们的对象如何在响应流和请求流之间进行序列化和反序列化,是通过MessageBodyWritersMessageBodyReaders

What will happens is that a search will be done from the registry of providers, for one that can handle JSONObjectand 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.

将会发生的是,将从提供者的注册表中进行搜索,寻找可以处理JSONObject和媒体类型的提供者application/json。如果找不到,则 Jersey 无法处理该请求,并将发送 415 Unsupported Media Type。您通常也应该在服务器端记录异常。不确定您是否有机会查看日志。

Jersey doesn't have any standard reader/writer for the org.jsonobjects. 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.

Jersey 没有任何标准的org.json对象读取器/写入器。您必须在网络上搜索实现或自己编写一个,然后注册它。您可以在此处阅读有关如何实施它的更多信息。

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

或者,您可以接受一个字符串并返回一个字符串。只需JSONObject使用字符串参数构造,并JSONObject.toString()在返回时调用。

@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 Hymanson, which can handle serializing and deserializing to and from out model objects (simple POJOs). For instance you can have a class like

我的建议是使用像 Hymanson 这样的数据绑定框架,它可以处理与模型对象(简单 POJO)之间的序列化和反序列化。例如,你可以有一个类

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

You could have the Modelas a method parameter

您可以将Model作为方法参数

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 JavaBeanproperty names (getters/setters following the naming convention shown above).

对于ReturnType. 只需为您想要返回的类型创建一个 POJO。JSON 属性基于JavaBean属性名称(遵循上述命名约定的 getter/setter)。

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

要获得此支持,您可以添加此 Maven 依赖项:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-Hymanson</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.

或者如果你没有使用Maven,你可以看到这个帖子,对于jars你可以独立下载。

Some resources:

一些资源:

回答by Aman Goel

Its because of following issue:

这是因为以下问题:

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

JAX-RS 不支持默认的 Hymanson 映射转换。因此,如果您有如下所示的 ajax 请求(发布):

 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:

在 JAX-RS 控制器端,您需要执行以下操作:

@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.

这里请确定参数。服务接受 json 作为字符串而不是 POJO。

Surely It will work. Thanks!

它肯定会起作用。谢谢!

回答by Ross Z

I have seen the same problem when using Jersey with HTTP/2, if the client send HTTP/1.1 request,e.g. using Jersey client, then it works fine.

我在使用 Jersey 和 HTTP/2 时遇到了同样的问题,如果客户端发送 HTTP/1.1 请求,例如使用 Jersey 客户端,那么它工作正常。

If I switch to Jetty HTTP2 Client to send the same content, I get 415.

如果我切换到 Jetty HTTP2 客户端发送相同的内容,我得到 415。

The temp solution I use is the alternative described by Paul Samsotha, i.e. "accept a String and return a String", then manually deserialize the String to POJO.

我使用的临时解决方案是 Paul Samsotha 描述的替代方案,即“接受一个字符串并返回一个字符串”,然后手动将字符串反序列化为 POJO。