-
Notifications
You must be signed in to change notification settings - Fork 540
Closed
Labels
Milestone
Description
问题描述
简要描述您碰到的问题。
在枚举的某个字段中加入了@JSONField(value = true)注解,序列化没问题,但反序列华的时候,只能序列化@RequestBody的参数类型,query参数 (示例:http://127.0.0.1:8080/demo/get?name=张三丰&gender=1) 无法反序列化。
环境信息
请填写以下信息:
- OS信息: [e.g.:Windows 11 家庭中文版 22H2]
- JDK信息: [e.g.:OracleJdk-20.0.1]
- 版本信息:[e.g.:Fastjson2 2.0.33]
重现步骤
如何操作可以重现该问题:
1、引入fastjson2的spring依赖包,测试工程的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>20</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension-spring6</artifactId>
<version>2.0.33</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、编写枚举和测试用的model类
枚举代码如下:
package com.example.demo.model;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum GenderEnum {
UNKNOWN(0, "未知"),
MALE(1, "男"),
FEMALE(2, "女");
@JSONField(value = true)
private final Integer code;
private final String name;
}
测试的model代码如下:
package com.example.demo.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class User {
private String name;
private GenderEnum gender;
}
3、编写测试的Controller
package com.example.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.User;
@RestController
@RequestMapping("/demo")
public class DemoController {
private static final Logger logger = LoggerFactory.getLogger(DemoController.class);
@GetMapping("/get")
public User get(User user) {
logger.info("get请求获取到的参数信息:\n{}", user);
return user;
}
@PostMapping("/post")
public User post(@RequestBody User user) {
logger.info("post请求获取到的参数信息:\n{}", user);
return user;
}
}
4、通过启动服务,并通过postman提交请求,观察参数输出。
期待的正确结果
不论请求是通过GET提交还是POST提交,又或者更多的方式提交。不论传的参数是query参数还是body参数,都能正确地反序列化
相关日志输出
GET请求中,通过枚举某一字段(这里是code)的值传参时的日志输出(不正常):
2023-06-17T00:17:30.842+08:00 [0;39m [33m WARN [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-2] [0;39m [36m.w.s.m.s.DefaultHandlerExceptionResolver [0;39m : [0;39m Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.example.demo.model.User com.example.demo.controller.DemoController.get(com.example.demo.model.User): [Field error in object 'user' on field 'gender': rejected value [1]; codes [typeMismatch.user.gender,typeMismatch.gender,typeMismatch.com.example.demo.model.GenderEnum,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.gender,gender]; arguments []; default message [gender]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.example.demo.model.GenderEnum' for property 'gender'; Failed to convert from type [java.lang.String] to type [com.example.demo.model.GenderEnum] for value [1]]] ]
GET请求中,通过枚举名称传参时的日志输出(正常):
2023-06-17T00:22:11.845+08:00 [0;39m [32m INFO [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-4] [0;39m [36mc.e.demo.controller.DemoController [0;39m : [0;39m get请求获取到的参数信息:
User(name=张三丰, gender=MALE)
POST请求的日志输出(正常):
2023-06-17T00:14:04.408+08:00 [0;39m [32m INFO [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-1] [0;39m [36mo.a.c.c.C.[Tomcat].[localhost].[/] [0;39m : [0;39m Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-17T00:14:04.408+08:00 [0;39m [32m INFO [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-1] [0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m : [0;39m Initializing Servlet 'dispatcherServlet'
2023-06-17T00:14:04.412+08:00 [0;39m [32m INFO [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-1] [0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m : [0;39m Completed initialization in 3 ms
2023-06-17T00:14:04.797+08:00 [0;39m [32m INFO [0;39m [35m14224 [0;39m --- [0;39m [nio-8080-exec-1] [0;39m [36mc.e.demo.controller.DemoController [0;39m : [0;39m post请求获取到的参数信息:
User(name=张三丰, gender=MALE)
附加信息
以下是提交请求时候的Postman工具截图
GET请求中,通过枚举某一字段(这里是code)的值传参时的截图(不正常):
其他测试
不通过springmvc,直接反序列化测试,Java代码如下:
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson2.JSON;
import com.example.demo.model.User;
class FastjsonTest {
private static final Logger logger = LoggerFactory.getLogger(FastjsonTest.class);
@Test
void test() {
// json串,gender为整数型
String text = """
{
"name":"张三丰",
"gender":1
}
""";
logger.info("gender为整数型时的,用户对象:\n{}", JSON.parseObject(text, User.class));
// json串,gender为字符串
text = """
{
"name":"张三丰",
"gender":"1"
}
""";
logger.info("gender为字符串时的用户对象:\n{}", JSON.parseObject(text, User.class));
}
}
输出的日志如下(第一个正常,第二个不正常,如果是jackson则两个都正常,当然,这个不算太重要):
00:29:31.785 [main] INFO com.example.demo.FastjsonTest -- gender为整数型时的,用户对象:
User(name=张三丰, gender=MALE)
00:29:31.788 [main] INFO com.example.demo.FastjsonTest -- gender为字符串时的用户对象:
User(name=张三丰, gender=null)