ajax - type - POST JSON falla con el tipo de medio 415 Unsupported, Spring 3 mvc
unsupported media type json (12)
Construcción mínima del servicio REST:
- probado con Wildfly
- las dependencias de jackson maven no requieren
pom.xml:
...
<properties>
<springframework.version>4.3.1.RELEASE</springframework.version>
</properties>
...
<packaging>war</packaging>
...
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<finalName>spring-rest-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
<webXml>${project.basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
...
src / main / java / webapp / WEB-INF / web.xml:
...
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>RestDemo</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RestDemo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
...
src / main / java / webapp / WEB-INF / RestDemo-servlet.xml:
...
<mvc:annotation-driven/>
<context:component-scan base-package="your.package.path" />
...
Controlador REST:
sin ningún control de datos, solo con fines educativos
@RestController
public class SpringRestServiceImpl implements SpringRestService {
@Autowired
private VideoGameDao videoGameDao;
...
@RequestMapping(value = "/rest/save", method = RequestMethod.POST, consumes = {"application/json"})
@Override
public ResponseEntity save(@RequestBody VideoGame videoGame) {
return ResponseEntity.ok(videoGameDao.save(videoGame));
}
...
}
Como revisar:
con rizo:
curl -i -POST -H "Content-Type: application/json" -d "your-json-here" http://yourserver:8080/spring-rest-demo/rest/save
o con la herramienta Postman
Estoy intentando 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 el tipo de medio 415 Unsupported. El controlador Spring mvc tiene firma
@RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
@RequestBody ProductCategory productCategory)
Hace algunos días funcionó, ahora no es así. Mostraré más código si es necesario. Gracias
1.a. Agregue los siguientes 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
- agregar la biblioteca de jackson
Creo que encontré exactamente el mismo problema. Después de innumerables horas de lucha con JSON, JavaScript y el Servidor, encontré al culpable: en mi caso tenía un objeto Date en el DTO, este objeto Date se convirtió a String 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 debía convertirse de nuevo en un objeto de fecha completo, por lo tanto, también necesitamos un método para establecerlo en el DTO. El gran PERO es que no puede tener 2 métodos con el mismo nombre (Sobrecarga) en el DTO, incluso si tienen un tipo diferente de parámetro (String vs Date), ya que esto le dará también el error 415 Tipo de medio no admitido.
Este era mi método de control
@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 (id get / set y preAlarm get Los métodos no están incluidos para la falta de 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 de fecha. Este error es muy frustrante. Espero que esto pueda ahorrarle a alguien horas de depuración.
Me enfrenté a este problema cuando intenté el arranque de muelles de muelles de primavera. 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>
Me enfrenté a un problema similar y así es como lo solucioné
El problema se debe al proceso de conversión de JSON a Java, uno necesita tener las bibliotecas correctas de tiempo de ejecución de jackson para que la conversión se realice correctamente.
Agregue los siguientes archivos jar (a través de la dependencia o descargando y agregando a 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 ayude
Me las arreglé para hacer que funcione. Dime en caso de que esté equivocado. Utilicé solo una forma de serializar / deserializar: @JSONSerialize
todas las anotaciones relacionadas con esto ( @JSONSerialize
y @JSONDeserialize
) y los serializadores y deserializadores registrados en la clase CustomObjectMapper
. No encontré un artículo que explicara este comportamiento, pero lo resolví de esta manera. Espero que sea útil.
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>
Tuve esto antes con Spring @ResponseBody y fue porque no se envió un encabezado de aceptación con la solicitud. Aceptar el encabezado puede ser difícil de configurar 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 qué formato son los datos que se envían desde el cliente en la solicitud. El encabezado de aceptación lo utiliza @ResponseBody para determinar qué formato devolverá los datos al cliente en la respuesta. Es por eso que necesitas ambos encabezados.
Tuve un problema similar pero me di cuenta de que había olvidado proporcionar un constructor predeterminado para el DTO anotado con @RequestBody.
Una pequeña nota al margen: tropecé 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 deberían estar rodeados por 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 escuchado.
Lo que se ha dicho antes en esta y otras publicaciones, como incluir los encabezados ''Aceptar'' y ''Tipo de contenido'', se aplica también.
Espero que ayudes.
Yo tuve el mismo problema. Tenía 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. Crea 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.
agregar tipo de contenido en la solicitud cuando application/json
resolvió el problema