spring - restful - 415 MediaType no soportado para solicitud POST en aplicación de primavera
spring web service example (3)
Tengo una aplicación de Spring
muy simple (NO de arranque de primavera). Implementé métodos de control GET y POST. el método GET
funciona bien. Pero el POST
arroja 415 Unsupported MediaType
. Los pasos para reproducir están disponibles a continuación
ServiceController. java
package com.example.myApp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/service/example")
public class ServiceController {
@RequestMapping(value="sample", method = RequestMethod.GET)
@ResponseBody
public String getResp() {
return "DONE";
}
@RequestMapping(value="sample2", method = RequestMethod.POST, consumes = "application/json")
@ResponseBody
public String getResponse2(@RequestBody Person person) {
return "id is " + person.getId();
}
}
class Person {
private int id;
private String name;
public Person(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
AppConfig.java
package com.example.myApp.app.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@ComponentScan("com.example.myApp")
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**").addResourceLocations("/test/").setCachePeriod(0);
registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(0);
registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(0);
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(0);
}
}
AppInitializer.java
package com.example.myApp.app.config;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Create the ''root'' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
El código está disponible aquí:
git clone https://bitbucket.org/SpringDevSeattle/springrestcontroller.git
./gradlew clean build tomatrunwar
Esto hace girar tomcat incrustado.
Ahora puedes enrollar lo siguiente
curl -X GET -H "Content-Type: application/json" "http://localhost:8095/myApp/service/example/sample"
funciona bien
Pero
curl -X POST -H "Content-Type: application/json" ''{
"id":1,
"name":"sai"
}'' "http://localhost:8095/myApp/service/example/sample2"
Lanza 415 tipos de medios no admitidos
<body>
<h1>HTTP Status 415 - </h1>
<HR size="1" noshade="noshade">
<p>
<b>type</b> Status report
</p>
<p>
<b>message</b>
<u></u>
</p>
<p>
<b>description</b>
<u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.</u>
</p>
<HR size="1" noshade="noshade">
<h3>Apache Tomcat/7.0.54</h3>
</body>
Aceptar encabezado podría ser el problema. Por lo que recuerdo, cuando envías una solicitud por curl, agrega un encabezado predeterminado accept : */*
Pero en el caso de JSON, debes mencionar el encabezado de aceptación
como accept : application/json
de manera similar, ha mencionado el tipo de contenido.
Y poco más, no sé qué es eso, pero ¿no crees que tienes que colocar "mapeos de solicitudes" como ese?
@RequestMapping(value="/sample" ...
@RequestMapping(value="/sample2" ...
Puede que este no sea el caso, pero aceptar el encabezado es la cosa, creo que es el problema principal.
Solución 2
Como tienes este código
public String getResponse2(@RequestBody Person person)
Ya he enfrentado este problema antes y la solución dos puede ayudar aquí
FormHttpMessageConverter que se utiliza para los parámetros @ RequestBody-anotada cuando el tipo de contenido es application / x-www-form-urlencoded no puede vincular clases de destino como @ModelAttribute puede). Por lo tanto, necesitas @ModelAttribute en lugar de @RequestBody
Utilice la anotación @ModelAttribute en lugar de @RequestBody como este
public String getResponse2(@ModelAttribute Person person)
Le di la misma respuesta a alguien y me ayudó. aquí está esa respuesta mía
Encontré la solución y quiero publicarla aquí para que beneficie a los demás.
En primer lugar, debo incluir a jackson en mi classpath, que agregué en build.gradle de la siguiente manera:
compile ''com.fasterxml.jackson.core:jackson-databind:2.7.5''
compile ''com.fasterxml.jackson.core:jackson-annotations:2.7.5''
compile ''com.fasterxml.jackson.core:jackson-core:2.7.5''
A continuación, tengo que cambiar mi AppConfig
que extiende WebMvcConfigurerAdapter
siguiente manera:
@Configuration
@EnableWebMvc
@ComponentScan("com.example.myApp")
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**").addResourceLocations("/test/").setCachePeriod(0);
registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(0);
registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(0);
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(0);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
}
Eso es todo y todo funcionó bien
puedes intentar usar la opción -d en curl
curl -H "Content-Type: application/json" -X POST -d
''{"id":"1,"name":"sai"}''
http://localhost:8095/myApp/service/example/sample2
Además, si usa Windows, debe evitar las comillas dobles
-d "{ /"id/": 1, /"name/":/"sai/" }"