J'ai une application Spring
très simple (PAS de démarrage à ressort). J'ai implémenté des méthodes de contrôleur GET et POST. la méthode GET
fonctionne bien. Mais la POST
jette 415 Unsupported MediaType
. Les étapes pour reproduire sont disponibles ci-dessous
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("/");
}
}
Le code est disponible ici:
git clone https://bitbucket.org/SpringDevSeattle/springrestcontroller.git
./gradlew clean build tomatrunwar
Cela accélère Tomcat intégré.
Maintenant, vous pouvez curl le suivant
curl -X GET -H "Content-Type: application/json" "http://localhost:8095/myApp/service/example/sample"
fonctionne bien
Mais
curl -X POST -H "Content-Type: application/json" '{
"id":1,
"name":"sai"
}' "http://localhost:8095/myApp/service/example/sample2"
Lance 415 MediaType non pris en charge
<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>
J'ai trouvé la solution et je veux poster ici pour en faire profiter les autres.
Tout d'abord, je dois inclure jackson dans mon classpath, que j'ai ajouté dans build.gradle comme suit:
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'
Ensuite, je dois changer ma AppConfig
qui étend WebMvcConfigurerAdapter
comme suit:
@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);
}
}
C'est tout et tout a bien fonctionné
Accepter en-tête pourrait être le problème . Pour autant que je m'en souvienne, lorsque vous envoyez une demande via curl, il ajoute un en-tête par défaut accept : */*
Mais dans le cas de JSON, vous devez mentionner l'en-tête accept
comme accept : application/json
de même, vous avez mentionné le type de contenu.
Et un peu plus, je ne sais pas ce que c'est, mais vous ne pensez pas que vous devez placer des "requêtes de mappages" comme ça
@RequestMapping(value="/sample" ...
@RequestMapping(value="/sample2" ...
Ce n'est peut-être pas le cas, mais accepter l'en-tête est la chose, je pense que c'est le problème principal .
Solution 2
Depuis que vous avez ce code
public String getResponse2(@RequestBody Person person)
J'ai déjà fait face à ce problème avant et la solution deux peut aider ici
FormHttpMessageConverter qui est utilisé pour les paramètres annotés @ RequestBody lorsque le type de contenu est application/x-www-form-urlencoded ne peut pas lier les classes cibles de la même manière que @ModelAttribute. Par conséquent, vous avez besoin de @ModelAttribute au lieu de @RequestBody
Utilisez soit l'annotation @ModelAttribute au lieu de @RequestBody comme ceci
public String getResponse2(@ModelAttribute Person person)
J'ai fourni la même réponse à quelqu'un et cela a aidé… .. voici ce que répondre à moi
pouvez-vous essayer d'utiliser l'option -d dans curl
curl -H "Content-Type: application/json" -X POST -d
'{"id":"1,"name":"sai"}'
http://localhost:8095/myApp/service/example/sample2
En outre, si vous utilisez Windows, vous devez éviter les guillemets doubles.
-d "{ \"id\": 1, \"name\":\"sai\" }"