Джерси 415 Неподдерживаемый тип материала

Я пытаюсь с часами исправлять ошибку http 415 Unsupported Media Type, но он по-прежнему демонстрирует неподдерживаемую страницу. Я добавляю заголовки application/json в Postman.

Вот мой код 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";
      }

}

вот мой 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>

Ответ 1

Как наши объекты сериализуются и десериализуются в поток ответов и поток запросов и из него, через MessageBodyWriter s и MessageBodyReader s.

Что произойдет, так это то, что поиск будет производиться из реестра поставщиков, для тех, которые могут обрабатывать JSONObject и application/json type application/json. Если невозможно найти, то Джерси не сможет обработать запрос и отправит 415 неподдерживаемый тип носителя. Обычно вы должны регистрировать исключение на стороне сервера. Не уверен, что у вас еще есть возможность просмотреть журнал.

У Джерси нет стандартного устройства чтения/записи для объектов org.json. Вам нужно будет искать в Интернете для реализации или написать один, а затем зарегистрировать его. Вы можете узнать больше о том, как его реализовать здесь.

Кроме того, вы можете принять строку и вернуть строку. Просто JSONObject со строковым параметром и вызовите JSONObject.toString() при возврате.

@POST
@Consumes("application/json")
@Produces("application/json")
public String post(String jsonRequest) {
    JSONObject jsonObject = new JSONObject(jsonRequest);
    return jsonObject.toString();
}

Вместо этого я хотел бы использовать структуру привязки данных, такую как Jackson, которая может обрабатывать сериализацию и десериализацию на объектах модели и без нее (простые POJO). Например, у вас может быть класс вроде

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

Вы могли бы использовать Model как параметр метода

public ReturnType sayJsonTextHello(Model model)

То же самое для ReturnType. Просто создайте POJO для типа, который вы хотите вернуть. Свойства JSON основаны на именах свойств JavaBean (getters/seters в соответствии с приведенным выше соглашением об именах).

Чтобы получить эту поддержку, вы можете добавить эту зависимость от Maven:

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

Или, если вы не используете Maven, вы можете увидеть этот пост, поскольку банки можно загружать самостоятельно.

Некоторые ресурсы:

Ответ 2

Из-за следующей проблемы:

JAX-RS не поддерживает преобразование отображения Джексона по умолчанию. Поэтому, если у вас есть запрос ajax, как показано ниже (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);  
               }  
        });

а в контроллере 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";
}

Здесь обязательно проверьте параметр. служба принимает json как String, а не POJO.

Конечно, это сработает. Спасибо!

Ответ 3

Я видел ту же проблему при использовании Джерси с HTTP/2, если клиент отправляет запрос HTTP/1.1, например, с помощью клиента Джерси, то он работает нормально.

Если я переключаюсь на Jetty HTTP2 Client для отправки того же контента, я получаю 415.

Временное решение, которое я использую, - это альтернатива, описанная Полом Самсотой, то есть "принять строку и вернуть строку", а затем вручную десериализовать строку в POJO.