【问题标题】:Content type 'application/json' not supported in Spring MVC and jacksonSpring MVC 和 jackson 不支持内容类型“application/json”
【发布时间】:2016-11-17 13:18:14
【问题描述】:

尝试使用 Spring MVC 接收发布请求时出现错误(处理程序执行导致异常:不支持内容类型 'application/json')。

我的 Json,只是为了测试,非常简单:

{ "test": "abc123" }

我的 pojo 课:

public class Request {

    String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

}

还有我的控制器:

@RequestMapping(value = "/testing", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
private void testing(@RequestBody Request body, @RequestHeader HttpHeaders headers, HttpServletRequest httpRequest) {
    System.out.println(body.getTest());
}

在我的 pom.xml 中,我添加了:

<dependencies>
    ...
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.8.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.4.3</version>
    </dependency>
</dependencies>

我认为json反序列化有问题,但是找不到。

欢迎任何帮助。谢谢。

【问题讨论】:

  • 为什么在produces 上使用MediaType.APPLICATION_JSON_VALUE,而在consumes 上使用字符串文字?当方法没有产生任何东西时,为什么你有produces@ResponseBody?这可能会混淆 Spring MVC 以防止映射工作。
  • @Andreas, MediaType.APPLICATION_JSON_VALUE 只是"application/json" 的常数,所以我不认为这是问题所在。无论如何,我删除了produces@ResponseBody,但我仍然遇到同样的问题。
  • @PedroH 为什么你需要这个consumes 属性?它仅用于使映射更具体。删除它,然后重试。
  • @Nikem,谢谢,但我删除了consumes,我遇到了同样的问题。
  • 不要混合不同版本的杰克逊组件。并确保您要使用的 jackson 版本与您使用的 Spring MVC 版本兼容。

标签: java json spring spring-mvc


【解决方案1】:

在我的情况下,问题是添加到属性的 dto 中,该属性的类型对于 Jackson 来说容易出错,它是 JsonObject 类型。由于该添加,Jackson 无法反序列化其他对象。
异常消息完全不准确!

【讨论】:

  • 这对我来说是一个很好的线索。您需要确保 1. 您的对象是可序列化的,以及 2. 所有 pojo getter/setter 均已正确实现
【解决方案2】:

这是我的工作示例:

@SpringBootApplication
@Controller
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class);
  }


  @RequestMapping(value = "/testing", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
  @ResponseBody
  private void testing(@RequestBody Request body, @RequestHeader HttpHeaders headers, HttpServletRequest httpRequest) {
    System.out.println(body.getTest());
  }
}

此项目只有 1 个依赖项:

org.springframework.boot:spring-boot-starter-web

当我这样调用网址时:

curl -XPOST -v -d '{ "test": "abc123" }' -H "Content-type: application/json" http://localhost:8080/testing

我在日志中看到了正确的 abc123。如果我删除 Content-type 标头,我会得到异常

org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'application/x-www-form-urlencoded' not supported

【讨论】:

    【解决方案3】:

    在你的 webconfig 类中添加这个 Bean

    @Bean
    public ContentNegotiatingViewResolver contentViewResolver() {
        ContentNegotiationManagerFactoryBean contentNegotiationManager = new ContentNegotiationManagerFactoryBean();
        contentNegotiationManager.addMediaType("json", MediaType.APPLICATION_JSON);
    
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
    
        MappingJackson2JsonView defaultView = new MappingJackson2JsonView();
        defaultView.setExtractValueFromSingleKeyModel(true);
    
        ContentNegotiatingViewResolver contentViewResolver = new ContentNegotiatingViewResolver();
        contentViewResolver.setContentNegotiationManager(contentNegotiationManager.getObject());
        contentViewResolver.setViewResolvers(Arrays.<ViewResolver> asList(viewResolver));
        contentViewResolver.setDefaultViews(Arrays.<View> asList(defaultView));
        return contentViewResolver;
    }
    

    更新

    来自 cmets 的人是对的,这不能解决你的问题,但我注意到了一些事情。

    如果我设置了 consumes = MediaType.APPLICATION_JSON_VALUE 并且在请求中我没有指定内容类型,它将引发异常,那么如果我设置了内容类型,问题就解决了。

    现在,问题似乎与您的依赖关系有关。

    我的 pom 依赖项:

     <properties>
         <springframework.version>4.1.9.RELEASE</springframework.version>
         <springframework.security.oauth.version>2.0.9.RELEASE</springframework.security.oauth.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    
        ...
    
    </properties>
    
    <dependencies>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</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-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>${springframework.security.oauth.version}</version>
        </dependency>
    
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.3.1</version>
        </dependency>
    
        ...
    
    </dependencies>
    

    【讨论】:

    • 我认为我不需要这个。我什至没有使用 jsp 文件。
    • 他们为什么需要这个?这个 bean 贡献了哪些配置中缺少的内容?
    • 还没有工作。我有你所有的依赖,我在我的请求头上设置 Content-Type “application/json”。
    • 你能去掉消耗吗?尝试仅使用 com.fasterxml.jackson.core 依赖项并评论其他人
    • 我也有同样的问题,依赖jackson-databind解决了我的问题
    【解决方案4】:

    对于寻找这个问题的其他人,我必须在我的 Pojo 类上至少有一个公共变量或一个 getter。

    【讨论】:

      【解决方案5】:

      对于那些使用Spring Framework没有 Spring Boot,并遇到这个问题的人。

      这个问题的根源是:

      • Spring需要①识别“Content-Type”,②转换 将内容添加到我们在方法中声明的参数类型 签名。

      • 不支持“application/json”,因为默认情况下, Spring 找不到合适的 HttpMessageConverter 来完成转换工作,这是第②步。

      解决方案

      • 我们手动将适当的 HttpMessageConverter 添加到 我们的应用程序Spring配置

      步骤:

      1. 选择我们要使用的 HttpMessageConverter 的类。对于 Json,我们 可以选择 "org.springframework.http.converter.json.JsonbHttpMessageConverter", "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter", 和等等

      2. 添加 JsonbHttpMessageConverter 对象(或其他类型的 Json HttpMessageConverter object) 到 Spring 的配置,通过调用 “公共空白 configureMessageConverters(List> converters)" "WebMvcConfigurer" 实现类的方法 在我们的应用程序中。在方法内部,我们可以添加任何 HttpMessageConverter 对象 根据需要使用“converters.add()”。

      3. 对应的依赖项添加到“pom.xml”文件中。例如,如果您 使用“JsonbHttpMessageConverter”,那么你需要添加 “javax.json.bind-api”和“yasson”的依赖关系。

      【讨论】:

        【解决方案6】:

        我有同样的问题。最后我解决了。实际错误在 jackson lib 中。这是位置和代码sn-p。

        /* \.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.6.5\jackson-databind-2.6.5-sources.jar!\com\fasterxml\jackson\databind\DeserializationContext.java  406 */
        
        
        public boolean hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause) {
                try {
                    return _cache.hasValueDeserializerFor(this, _factory, type);
                } catch (JsonMappingException e) {
                    if (cause != null) {
                        cause.set(e);
                    }
                } catch (RuntimeException e) {
                    if (cause == null) { // earlier behavior
                        throw e;
                    }
                    cause.set(e);
                }
                return false;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-06
          • 2017-10-21
          • 2022-12-22
          • 2015-06-21
          • 2019-02-20
          • 2020-08-02
          • 2018-10-27
          相关资源
          最近更新 更多