非常に単純なSpring
アプリケーションがあります(スプリングブートではありません)。 GETとPOSTコントローラメソッドを実装しました。GET
メソッドは正常に動作します。しかし、POST
は415 Unsupported MediaType
。再現手順は以下にあります
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("/");
}
}
コードは次の場所にあります。
git clone https://bitbucket.org/SpringDevSeattle/springrestcontroller.git
./gradlew clean build tomatrunwar
これにより、埋め込みTomcatが起動します。
今、あなたは以下をカールすることができます
curl -X GET -H "Content-Type: application/json" "http://localhost:8095/myApp/service/example/sample"
正常に動作します
しかし
curl -X POST -H "Content-Type: application/json" '{
"id":1,
"name":"sai"
}' "http://localhost:8095/myApp/service/example/sample2"
415サポートされていないMediaTypeをスローします
<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>
私は解決策を見つけたので、他の人に利益をもたらすようにここに投稿したいと思います。
最初に、次のようにbuild.gradleに追加したクラスパスにjacksonを含める必要があります。
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'
次に、AppConfig
を拡張する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);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
}
それがすべてであり、すべてがうまく機能しました
Accept Headerが問題になる場合があります。私が覚えている限り、curl経由でリクエストを送信すると、デフォルトのヘッダーaccept : */*
ただし、JSONの場合は、acceptヘッダーに言及する必要があります
as accept : application/json
同様に、コンテンツタイプに言及しました。
そしてもう少し、私はそれが何であるか知りませんが、あなたはそのような「リクエストマッピング」を配置しなければならないと思いませんか
@RequestMapping(value="/sample" ...
@RequestMapping(value="/sample2" ...
これは当てはまらないかもしれませんが、ヘッダーを受け入れることが重要です。主な問題だと思います。
ソリューション2
このコードがあるので
public String getResponse2(@RequestBody Person person)
私はすでにこの問題に直面しており、解決策2がここで役立つかもしれません
コンテンツタイプがapplication/x-www-form-urlencodedの場合に@RequestBodyアノテーション付きパラメーターに使用されるFormHttpMessageConverterは、@ ModelAttributeのようにターゲットクラスをバインドできません。したがって、@ RequestBodyの代わりに@ModelAttributeが必要です
このように@RequestBodyの代わりに@ModelAttributeアノテーションを使用する
public String getResponse2(@ModelAttribute Person person)
私は誰かに同じ答えを提供し、それが助けました。ここにあります answer 私の
curlで-dオプションを使用してみてください
curl -H "Content-Type: application/json" -X POST -d
'{"id":"1,"name":"sai"}'
http://localhost:8095/myApp/service/example/sample2
また、ウィンドウを使用する場合は、二重引用符をエスケープする必要があります
-d "{ \"id\": 1, \"name\":\"sai\" }"