POST JSON falla con 415 Tipo de medio no compatible, Spring 3 mvc


Estoy tratando de enviar una solicitud POST a un servlet. La solicitud se envía a través de jQuery de esta manera:

var productCategory = new Object();
productCategory.idProductCategory = 1;
productCategory.description = "Descrizione2";
newCategory(productCategory);

Donde newCategory es

function newCategory(productCategory)
{
  $.postJSON("ajax/newproductcategory", productCategory, function(
      idProductCategory)
  {
    console.debug("Inserted: " + idProductCategory);
  });
}

Y postJSON es

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

Con firebug veo que JSON se envía correctamente:

{"idProductCategory":1,"description":"Descrizione2"}

Pero obtengo 415 Tipos de medios no soportados. Spring mvc controlador tiene firma

    @RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
        @RequestBody ProductCategory productCategory)

Hace unos días funcionó, ahora no lo es. Te mostraré más código si es necesario. Gracias

Author: gc5, 2012-07-15

11 answers

He tenido esto antes con Spring @ResponseBody y fue porque no había ningún encabezado accept enviado con la solicitud. Aceptar encabezado puede ser una molestia para establecer con jQuery, pero esto funcionó para mí source

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    headers: { 
        'Accept': 'application/json',
        'Content-Type': 'application/json' 
    },
    'type': 'POST',
    'url': url,
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

El encabezado Content-Type es utilizado por @RequestBody para determinar el formato de los datos que se envían desde el cliente en la solicitud. El encabezado accept es utilizado por @ResponseBody para determinar qué formato enviar los datos al cliente en la respuesta. Por eso necesitas ambos encabezados.

 206
Author: theon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:28

Tuve un problema similar pero descubrí que el problema era que había descuidado proporcionar un constructor predeterminado para el DTO que estaba anotado con @RequestBody.

 16
Author: John Shepherd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-03 06:45:34

Creo que me encontré exactamente con el mismo problema. Después de incontables horas de lucha con el JSON, el JavaScript y el Servidor, encontré al culpable: En mi caso tenía un objeto Date en el DTO, este objeto Date se convirtió en una Cadena para que pudiéramos mostrarlo en la vista con el formato: HH: mm.

Cuando la información JSON se enviaba de vuelta, este objeto de Cadena de fecha tenía que ser convertido de nuevo en un objeto de Fecha completa, por lo tanto también necesitamos un método para establecerlo en el DTO. El gran PERO eres tú no se pueden tener 2 métodos con el mismo nombre (Sobrecarga) en el DTO incluso si tienen un tipo diferente de parámetro (Cadena vs Fecha) porque esto le dará también el error de tipo de medio no compatible 415.

Este fue mi método controlador

  @RequestMapping(value = "/alarmdownload/update", produces = "application/json", method = RequestMethod.POST)
  public @ResponseBody
  StatusResponse update(@RequestBody AlarmDownloadDTO[] rowList) {
    System.out.println("hola");
    return new StatusResponse();
  }

Este fue mi ejemplo de DTO (los métodos id get/set y preAlarm get no se incluyen para la brevedad del código):

@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmDownloadDTO implements Serializable {

  private static final SimpleDateFormat formatHHmm = new SimpleDateFormat("HH:mm");

  private String id;
  private Date preAlarm;

  public void setPreAlarm(Date date) { 
    this.preAlarm == date;
  }
  public void setPreAlarm(String date) {    
    try {
      this.preAlarm = formatHHmm.parse(date);
    } catch (ParseException e) {
      this.preAlarm = null;
    } catch (NullPointerException e){
      this.preAlarm = null;
    }
  }
}

Para que todo funcione, debe eliminar el método con el parámetro Tipo Fecha. Este error es muy frustrante. Espero que esto pueda ahorre a alguien horas de depuración.

 11
Author: will824,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-02 21:28:16

Agregar el tipo de contenido a la solicitud como application/json resolvió el problema

 10
Author: uiroshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-02 10:47:10

Me enfrenté a este problema cuando integré spring boot con spring mvc. Lo resolví simplemente agregando estas dependencias.

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
 8
Author: deep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-03 05:54:33

Me enfrenté a un problema similar y así es como lo arreglé,

El problema se debe al proceso de conversión de JSON a Java, uno necesita tener el tiempo de ejecución correcto de las bibliotecas Jackson para que la conversión ocurra correctamente.

Agregue los siguientes jars (a través de la dependencia o descargando y agregando al classpath.

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>

Esto debería solucionar el problema.

Código completo:

function() {
  $.ajax({
    type: "POST",
    url: "saveUserDetails.do",
    data: JSON.stringify({
      name: "Gerry",
      ity: "Sydney"
    }),
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    success: function(data) {
      if (data.status == 'OK')
        alert('Person has been added');
      else
        alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
}

Y la firma del controlador se ve así:

@RequestMapping(value = "/saveUserDetails.do", method = RequestMethod.POST)
public @ResponseBody Person addPerson( @RequestBody final  Person person) {

Espero que esto ayuda

 8
Author: vinSan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 13:03:20

Una pequeña nota al margen - tropezó con este mismo error al desarrollar una aplicación web. El error que encontramos, al jugar con el servicio con Firefox Poster, fue que tanto los campos como los valores en el Json deben estar rodeados de comillas dobles. Por ejemplo..

[ {"idProductCategory" : "1" , "description":"Descrizione1"}, 
  {"idProductCategory" : "2" , "description":"Descrizione2"} ]

En nuestro caso, llenamos el json a través de javascript, lo que puede ser un poco confuso cuando se trata de tratar con comillas simples/dobles, por lo que he oído.

Lo que se ha dicho antes en este y otros posts, como incluye los encabezados' Accept 'y' Content-Type'.

Hope t'helps.

 5
Author: Carlos Romero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-16 10:37:00

Me las arreglé para hacer que funcione. Dímelo en caso de que me equivoque. Usé solo una forma de serializar / deserializar: Eliminé todas las anotaciones con respecto a esto (@JSONSerialize y @JSONDeserialize) y registré Serializadores y Deserializadores en la clase CustomObjectMapper. No encontré un artículo que explicara este comportamiento, pero lo resolví de esta manera. Espero que sea útil.

 3
Author: gc5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-26 16:19:08

Yo tenía el mismo problema. Tuve que seguir estos pasos para resolver el problema:

1. Asegúrese de tener las siguientes dependencias:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>

2. Cree el siguiente filtro:

    public class CORSFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {

            String origin = request.getHeader("origin");
            origin = (origin == null || origin.equals("")) ? "null" : origin;
            response.addHeader("Access-Control-Allow-Origin", origin);
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers",
                    "Authorization, origin, content-type, accept, x-requested-with");

            filterChain.doFilter(request, response);
        }
    }

3. Aplique el filtro anterior para las solicitudes en web.xml

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.your.package.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Espero que esto sea útil para alguien.

 1
Author: Manoj Shrestha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-16 04:17:27

Resolví este problema agregando el enlace de datos jackson-json a mi pom.

<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.6.3</version>
</dependency>
 0
Author: Lingasamy Bagavathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-24 10:43:27

1.a. Agregue lo siguiente en ApplicationContext-mvc.xml

Xmlns: mvc = "http://www.springframework.org/schema/mvc" xsi: schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc

  1. añadir biblioteca jackson
 -1
Author: Victor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-01 05:27:31