java - 从属性文件将外部日期格式模式设置为 @JsonFormat
问题描述
我们正在尝试使用 @JSONFormat 将 bean 中的日期格式外部化,以便使其可配置。
@JsonFormat(pattern = "${application.date.format}")
private Date creationtime;
或者
@JsonFormat(pattern = "yyyy-MM-DD")
private Date creationtime;
当我给出标准字符串值时,它会起作用。但是,当我们将第一个值中显示的值外部化时,我收到一个异常消息:
java.lang.IllegalArgumentException: Illegal pattern character 'p'
要将变量值分配给第二种方法,我们需要一个作为常量表达式的最终字符串。如何使模式可配置?
解决方案
Jackson
使用JacksonAnnotationIntrospector处理标准注释。我们可以扩展这个机制,提供我们额外的自省器和默认值。为此,我们可以使用pair方法。
简单的自定义实现可能如下所示:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import java.util.Objects;
public class SpringJacksonAnnotationIntrospector extends AnnotationIntrospector {
private final ApplicationContext context;
@Autowired
public SpringJacksonAnnotationIntrospector(ApplicationContext context) {
this.context = Objects.requireNonNull(context);
}
@Override
public JsonFormat.Value findFormat(Annotated memberOrClass) {
JsonFormat annotation = _findAnnotation(memberOrClass, JsonFormat.class);
if (annotation == null) {
return null;
}
String basePattern = annotation.pattern();
if (basePattern.startsWith("$")) {
String pattern = context.getEnvironment().getProperty(basePattern.substring(2, basePattern.length() - 1));
return JsonFormat.Value.forPattern(pattern);
}
return null;
}
@Override
public Version version() {
return new Version(1, 0, 0, "", "org.company", "spring-jackson");
}
}
上面的实现重用JsonFormat
了注解,但我们可以引入新的注解以避免混淆。我们需要注册我们的自定义内省器。有许多不同的方法可以做到这一点,这取决于您的Spring
配置。例如,我们可以这样做,如下所示:
import com.example.jackson.SpringJacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private ApplicationContext context;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//JSON
AnnotationIntrospector pairedIntrospectors = AnnotationIntrospector.pair(springJacksonAnnotationIntrospector(),
new JacksonAnnotationIntrospector());
converters.add(new MappingJackson2HttpMessageConverter(
Jackson2ObjectMapperBuilder.json()
.annotationIntrospector(pairedIntrospectors)
.build()));
}
@Bean
public SpringJacksonAnnotationIntrospector springJacksonAnnotationIntrospector() {
return new SpringJacksonAnnotationIntrospector(context);
}
}
从现在开始,Spring
应该使用 的全局配置来覆盖日期格式。
也可以看看:
推荐阅读
- python - Ren'py的地图和热点
- r - caret train 错误:至少一个类级别不是有效的 R 变量名
- azure - Azure 搜索 - 使用拆分技能翻译完整文档
- r - lmer 模型未能与随机效应结构收敛
- reporting-services - 尝试为 YTD 值创建计算列
- javascript - 映射运算符返回整数作为输出,数组作为输入
- wordpress - 如何在 WordPress 中设置此永久链接结构:/custom-taxonomy/custom-post-type/post-name
- java - 在 Docker 中运行 Python 和 Java
- android - 如何使用 NDK 17 为 64 位 Android 构建 OpenSSL 1.1.1
- opencv - OpenCV - RTSP 流未打开