下面是详细讲解“SpringBoot基于HttpMessageConverter实现全局日期格式化”的完整攻略。
1. 什么是HttpMessageConverter
HttpMessageConverter 是 Spring 框架中的一个接口,用于将请求和响应的数据转换为特定的格式。它可以将浏览器提交的数据(如:application/json 、 application/xml、text/html等)转换成 Java 对象,并将 Java 对象转换成指定格式的数据。
在 SpringBoot 应用中,HttpMessageConverter 可以帮我们自动将返回结果序列化成 Json / XML格式,并通过 Jackson / Xstream 等自动配置转换。通过配置 HttpMessageConverter 可以非常方便地统一自定义转换器。
2. 全局日期格式化
在 SpringBoot 中,如果我们不指定日期格式,会默认返回 yyyy-MM-dd HH:mm:ss 格式的日期字符串,但是如果要统一规定一种日期格式,我们可以通过自定义 HttpMessageConverter 来实现。下面是具体的步骤:
2.1 自定义 DateConverter
我们需要先创建一个自定义的日期转换器 DateConverter,继承自 SpringMvc 提供的 WebMvcConfigurerAdapter类,然后在其中重写 configureMessageConverters()方法,并在该方法中设置我们的日期格式。
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class DateConverter extends WebMvcConfigurerAdapter {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 调用父类的configureMessageConverters方法,保留默认的转换器
super.configureMessageConverters(converters);
// 设置日期格式化
DateFormatter formatter = new DateFormatter();
formatter.setPattern(DATE_FORMAT);
// 创建 MappingJackson2HttpMessageConverter 作为默认的JSON转换器
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
jackson2HttpMessageConverter.setObjectMapper(new ObjectMapper().setDateFormat(formatter));
// 创建 MappingJackson2XmlHttpMessageConverter 作为默认的XML转换器
MappingJackson2XmlHttpMessageConverter jackson2XmlHttpMessageConverter = new MappingJackson2XmlHttpMessageConverter();
jackson2XmlHttpMessageConverter.setObjectMapper(new ObjectMapper().setDateFormat(formatter));
// 创建 MarshallingHttpMessageConverter 对象,作为默认的XML转换器
MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
// 注意:在使用 XStreamMarshaller 对象对 XML 数据进行转换时,必须先调用 setSupportedMediaTypes 方法设置媒体类型
xmlConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_XML));
// 创建 XStreamMarshaller 对象用于 XML 数据的转换
XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
xstreamMarshaller.setConverters(new DateConverter(new SimpleDateFormat(DATE_FORMAT)));
xmlConverter.setMarshaller(xstreamMarshaller);
xmlConverter.setUnmarshaller(xstreamMarshaller);
// 新增字符串支持
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converters.add(jackson2HttpMessageConverter);
converters.add(jackson2XmlHttpMessageConverter);
converters.add(xmlConverter);
converters.add(stringHttpMessageConverter);
}
private class DateFormatter extends DateFormat {
private static final long serialVersionUID = 1L;
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
return new SimpleDateFormat(DATE_FORMAT).format(date, toAppendTo, fieldPosition);
}
public Date parse(String source, ParsePosition pos) {
try {
return new SimpleDateFormat(DATE_FORMAT).parse(source); // source->date
} catch (Exception e) {
return null;
}
}
public Date parse(String source) throws ParseException {
return new SimpleDateFormat(DATE_FORMAT).parse(source);
}
}
}
2.2 配置自定义 DateConverter
我们还需将自定义的 DateConverter 注册到 SpringBoot 项目中,这里有两种方式:
- 将配置类 DateConverter 所在包扫描,让其注册到 SpringBoot 项目中:
@SpringBootApplication(scanBasePackages = {"com.example.demo"})
- 将配置类 DateConverter 在配置文件中注册到 SpringBoot 项目:
spring:
mvc:
messageConverters:
string:
charset: UTF-8
enabled: true
# HttpHeaders and those with MediaType.APPLICATION_OCTET_STREAM_VALUE are not affected
# by the JSON vulnerability protection, which can potentially cause a vulnerability
# on old browsers on the sites with mostly open attackers. Other defaults are still
# applied.
enable-buffering: false
writeAcceptCharset: false
jackson:
prettyPrint: false
writeDatesAsTimestamps: false
dateFormat: yyyy-MM-dd HH:mm:ss
jackson2:
prettyPrint: false
writeDatesAsTimestamps: false
dateFormat: yyyy-MM-dd HH:mm:ss
mappingJackson2Xml:
prettyPrint: false
writeDatesAsTimestamps: false
dateFormat: yyyy-MM-dd HH:mm:ss
xstream:
enabled: true
# HttpHeaders and those with MediaType.APPLICATION_OCTET_STREAM_VALUE are not affected
# by the JSON vulnerability protection, which can potentially cause a vulnerability
# on old browsers on the sites with mostly open attackers. Other defaults are still
# applied.
enable-buffering: false
writeAcceptCharset: false
supported-media-types: application/xml
marshaller: com.example.demo.converter.DateConverter
unmarshaller: com.example.demo.converter.DateConverter
这两种方式都可以帮我们完成自定义的日期格式化转换器的注册。
2.3 测试自定义日期格式化
现在我们已经完成了自定义的日期格式化转换器的编写,并成功将其注册到 SpringBoot 项目中,下面我们来测试一下自定义日期格式化能否正常工作。
以下是两个简单的控制器,分别返回日期类型的字符串和对象:
@RestController
public class DateController {
@GetMapping("/string")
public String testString() {
return "当前时间:" + new Date();
}
@GetMapping("/date")
public Date testDate() {
return new Date();
}
}
在访问控制器的时候,我们可以设置 Accept 头信息为 application/xml 或 application/json,在控制器返回响应时,我们就能看到在此情况下日期就会变成指定的格式了。
3. 总结
自定义 HttpMessageConverter 是 SpringBoot 框架中非常常见和重要的操作,可以方便地实现对请求和响应数据的统一处理。而在某些特定的场景中,自定义日期格式化转换器也是非常有必要的,这样能保证在整个项目中,日期输出格式是一致的,增加程序的可读性和可维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot基于HttpMessageConverter实现全局日期格式化 - Python技术站