【问题标题】:415 Unsupported MediaType for POST request in spring application415 Spring 应用程序中的 POST 请求不支持 MediaType
【发布时间】:2016-10-30 05:07:02
【问题描述】:

我有一个非常简单的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 unsupported 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>

【问题讨论】:

    标签: spring spring-mvc spring-restcontroller


    【解决方案1】:

    接受标头可能是问题所在。 据我记得,当您通过 curl 发送请求时,它会添加一个默认标头 accept : */*
    但在 JSON 的情况下,您必须将接受标头
    提及为accept : application/json
    同样您已经提及内容类型。

    还有一点,我不知道那是什么,但你不认为你必须像那样放置“请求映射”

    @RequestMapping(value="/sample" ...
    @RequestMapping(value="/sample2" ...
    

    情况可能并非如此,但接受标头是问题,我认为这是主要问题。
    解决方案 2
    既然你有这个代码

    public String getResponse2(@RequestBody Person person)
    

    我之前已经遇到过这个问题,解决方案二可能会有所帮助

    FormHttpMessageConverter 在内容类型为 application/x-www-form-urlencoded 时用于 @RequestBody 注释的参数,不能像 @ModelAttribute 那样绑定目标类)。因此你需要@ModelAttribute 而不是@RequestBody

    要么像这样使用@ModelAttribute注解而不是@RequestBody

    public String getResponse2(@ModelAttribute Person person)
    

    我向某人提供了相同的答案,这很有帮助。 这是我的answer

    【讨论】:

    • 不,不是。我添加了接受标头,它也不起作用
    • 嘿!我更新了我的答案,我相信这是问题所在。请检查 sloution 2 @brainstorm
    • @TahirHussainMir,嘿,我添加了@ModelAttribute annotation.Control 正在访问该方法,但我的对象数据显示为 null...??任何建议
    • 检查对象的变量名称和html中的名称字段。他们应该是一样的。就像是否有变量 String myName;然后在 html 中,输入字段应该有属性 name="myName"
    【解决方案2】:

    我找到了解决方案,我想在这里发帖,以便其他人受益。

    首先我需要在我的类路径中包含 jackson,我在 build.gradle 中添加如下:

     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'
    

    接下来,我必须更改扩展 WebMvcConfigurerAdapterAppConfig,如下所示:

    @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);
        }
    }
    

    就是这样,一切都很好

    【讨论】:

      【解决方案3】:

      你能尝试在 curl 中使用 -d 选项吗

      curl -H "Content-Type: application/json" -X POST -d
       '{"id":"1,"name":"sai"}'
       http://localhost:8095/myApp/service/example/sample2
      

      另外,如果你使用 windows,你应该转义双引号

      -d "{ \"id\": 1, \"name\":\"sai\" }" 
      

      【讨论】:

        猜你喜欢
        • 2015-06-17
        • 1970-01-01
        • 2015-03-30
        • 1970-01-01
        • 2016-11-21
        • 2016-08-28
        • 2016-09-13
        • 1970-01-01
        相关资源
        最近更新 更多