Spring 尝试反序列化为 LinkedHashMap 而不是 POJO
Posted
技术标签:
【中文标题】Spring 尝试反序列化为 LinkedHashMap 而不是 POJO【英文标题】:Spring tries to deserialize to LinkedHashMap instead of POJO 【发布时间】:2018-12-26 22:20:44 【问题描述】:我正在使用 Spring Boot 和 Web 依赖项创建一个简单的休息控制器。我正在尝试将 JSON 正文反序列化为只有 3 个字段的测试 POJO,但是当我尝试发出 POST 请求时,服务器响应 500 错误,我在控制台中得到的错误是:
.w.s.m.s.DefaultHandlerExceptionResolver : Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class java.util.LinkedHashMap
我写的所有代码如下:
EmailApplication.java:
package com.test.email.app;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.test.email" )
public class EmailApplication
public static void main(String[] args)
SpringApplication.run(EmailApplication.class, args);
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx)
return args ->
System.out.println("----- You're up and running with test-email-app! -----");
;
EmailController.java:
package com.test.email.controller;
import com.test.email.entity.TestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import java.net.URI;
@RestController
public class EmailController
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index()
TestEntity entity = new TestEntity();
return "test-email-app index";
@RequestMapping(value = "/poster", method = RequestMethod.POST)
public ResponseEntity<String> poster(@RequestBody TestEntity testEntity)
URI location = URI.create("/poster");
return ResponseEntity.created(location).body(testEntity.getUrl());
TestEntity.java
package com.test.email.entity;
/**
* An entity for serialization/deserialization testing
*/
public class TestEntity
public String url;
public int count;
public double height;
public TestEntity()
public TestEntity(String url, int count, double height)
this.url = url;
this.count = count;
this.height = height;
public String getUrl()
return url;
public void setUrl(String url)
this.url = url;
public int getCount()
return count;
public void setCount(int count)
this.count = count;
public double getHeight()
return height;
public void setHeight(double height)
this.height = height;
我只使用标头 Content-Type: application/json
和正文向 Postman 发出 POST 请求:
"url": "http://google.com", "count": 3, "height": 2.4
我不知道为什么 Spring 不能从 LinkedHashMap 转换为我的 POJO。任何帮助将不胜感激。
编辑:
我的pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.email</groupId>
<artifactId>test-email-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test-email-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
【问题讨论】:
询问异常时,请务必发布异常的准确和完整的堆栈跟踪。 我没有看到您的代码在任何地方返回LinkedHashMap
,那么为什么错误消息会显示“类型的返回值:class java.util.LinkedHashMap
”?我认为您对它抱怨的方法感到困惑。
与您的请求无关,但您的 Getter/Setter 无用,因为您的类属性的范围是“public”。为什么?
@JBNizet 在 intellij 运行控制台中,没有生成堆栈跟踪,只有一个错误行。我会尝试从终端运行它,看看是否产生了更大的堆栈跟踪。
有趣。谷歌发现了这个问题。现在像您一样打开相同的问题,但使用不同的程序。我认为还有一个更大的问题。
【参考方案1】:
分析您的问题后,我发现了一些可能会出现此问题的情况。 这些在下面给出:
-
内部类:
如果您的类 TestEntity
是端点的内部类。
只需将您的 TestEntity
从 Inner class 转移到一个单独的类并运行您的代码,它就可以工作了。
-
支持内部类:
如果你想支持一个 RequestBody 内部类然后将TestEntity
类设为static,这将解决你的问题。
-
Spring依赖配置:
如果仍未解决您的问题,请检查您对 pom.xml
的依赖关系。可能是您没有添加对正确方式的依赖。为此,您可以查看this answer。或者,您可以在 pom.xml
文件中显式添加 jackson
。
依赖项是:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
希望这能解决你的问题:)
如果仍然没有解决您的问题,请查看一些 youtube 视频或一些博客站点或从 github 下载一些开源项目。
谢谢:)
相关链接: Spring @Requestbody not mapping to inner class
【讨论】:
【参考方案2】:尝试指定您的方法使用 JSON。更改您的注释:@RequestMapping(value = "/poster", method = RequestMethod.POST)
到
@PostMapping(value = "/poster",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
produces = MediaType.TEXT_html)
这里的主要部分是您指定您接受 JSON 格式的输入。不确定您返回什么类型,但您可以指定适当的类型或删除“生产”部分。主要部分是指定您的输入是什么
【讨论】:
【参考方案3】:理想情况下,这段代码应该可以工作,但请尝试在 pom.xml 中添加以下依赖项
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
【讨论】:
以上是关于Spring 尝试反序列化为 LinkedHashMap 而不是 POJO的主要内容,如果未能解决你的问题,请参考以下文章
使用spring boot将JSON反序列化为带有通用对象列表的POJO
如何在 Spring 将其反序列化为 POJO 之前访问原始请求有效负载? [复制]
spring mvc接收ajax提交的JSON数据,并反序列化为对象
在spring mvc控制器接收json并反序列化为对象列表
使用 Jackson 和 Spring 将 JavaScript 数组反序列化为 Java LinkedHashSet 不会删除重复项