如何在Spring Boot中为@RequestParam参数使用@JsonDeserialize



我尝试使用Jackson来反序列化LocalDateTime参数,但是当我使用@RequestParam时,它不起作用,'反序列化'方法从未被调用过。

这是我的@RequestParam方法:

@GetMapping("/search")
public String search(
@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
@RequestParam(value = "startTime", required = false) LocalDateTime startTime,
@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
@RequestParam(value = "endTime", required = false) LocalDateTime endTime
)

代替@RequestParam,当我使用@RequestBody接受参数时,'deserialize'方法将被调用,那么,我可以为@RequestParam使用'deserialize'方法做些什么呢?

这是我的@RequestBody方法:
@PostMapping("/test")
public LocalDateTime getBillingListByDate(@RequestBody SearchQuery searchQuery) {
return searchQuery.getStartTime();
}

SearchQuery:

public class SearchQuery {
@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
private LocalDateTime startTime;
@JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
private LocalDateTime endTime;
// getter and setter
}

这是我的反序列化类:

public class CustomLocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
private final DateTimeFormatter FORMATTER1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private final DateTimeFormatter FORMATTER2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public CustomLocalDateTimeDeserializer() {
this(LocalDateTime.class);
}

CustomLocalDateTimeDeserializer(Class<LocalDateTime> deserializer) {
super(deserializer);
}
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
String text = jsonParser.getText().trim();
if (ObjectUtils.isEmpty(text)) {
return null;
}
LocalDateTime localDateTime = null;
try {
localDateTime = LocalDateTime.parse(text, FORMATTER1);
} catch (Exception e) {
try {
LocalDate parse = LocalDate.parse(text, FORMATTER2);
LocalTime time = LocalTime.of(0, 0, 0);
localDateTime = LocalDateTime.of(parse, time);
} catch (Exception ignore) {
}
}
return localDateTime;
}
}

和配置:

@Configuration
public class GlobalDateConfig {
private final String formatter = "yyyy-MM-dd HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
builder.deserializerByType(LocalDateTime.class, new CustomLocalDateTimeDeserializer());
};
}
}

这是我的依赖版本:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.2</version>
</dependency>

使用转换器

首先,创建一个转换器类
@Component
public class LocalDateTimeConverter implements Converter<String, LocalDateTime> {
@Override
public LocalDateTime convert(String value) {
try {
return LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
} catch (DateTimeParseException e1) {
try {
return LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} catch (DateTimeParseException ignored) {
}
}
return null;
}
}

然后配置

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new LocalDateTimeConverter());
}
}

你可以用这些

进行测试
/search?startTime=2023-03-31 03:10:02
/search?startTime=2023-03-31

最新更新