SpringBoot 全局日期格式化(基于注解)

小Hub领读:

json数据中的时间格式化一直都是程序员头疼的问题,这里看作者怎么使用 @JsonComponent来处理日期。另外还可以根据时区动态展示不同时间,厉害了,你会吗?


作者:yizhiwazi

链接:https://www.jianshu.com/p/f4654d251104

学习目标

快速学会通过注解 @JsonComponent自定义日期格式化的序列化器。

快速查阅

专题阅读:《SpringBoot 布道系列》:https://www.jianshu.com/p/964370d9374e

源码下载:SpringBoot Date Format Anno:https://github.com/yizhiwazi/springboot-socks

--- Hey Man,Don't forget to Star or Fork . ---

使用教程

根据官方文档 Custom JSON Serializers and Deserializers ,想要接管Jackson的JSON的序列化和反序列化,只需通过注解 @JsonComponent来声明其静态内部类即可。

首先根据项目要求提供自定义的日期序列化器和反序列化器,其中包括:

  • DateJsonSerializerextendsJsonSerializer<Date> 表示将Date格式化为日期字符串。

  • DateJsonDeserializerextendsJsonDeserializer<Date> 表示将日期字符串解析为Date日期。

/**
 * 全局日期格式化
 */
@JsonComponent
public class DateFormatConfig {
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 日期格式化
     */
    public static class DateJsonSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(dateFormat.format(date));
        }
    }
    /**
     * 解析日期字符串
     */
    public static class DateJsonDeserializer extends JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            try {
                return dateFormat.parse(jsonParser.getText());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

然后提供相应的测试信息,这里以查询用户为例:

/**
 * 查询用户信息
 */
@RestController
public class UserController {
    @GetMapping("/")
    public User get() {
        return new User("1", "socks", "123456", new Date(), "GMT");
    }
}
/**
 * 用户信息
 */
public class User {
    private String userId;
    private String username;
    private String password;
    private Date createTime;
    private String timezone;
    public User(String userId, String username, String password, Date createTime, String timezone) {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.createTime = createTime;
        this.timezone = timezone;
    }
   //省略getters&setters
}

大功告成,接下来启动应用并访问 http://127.0.0.1:8080 ,可以拿到正确结果:

{
  "userId": "1",
  "username": "socks",
  "password": "123456",
  "createTime": "2018-12-26 01:03:25"
}

除了日期格式化解析之外,我们还可以在 DateFormatConfig 注入业务变量,例如根据当前登录人的所属时区(虽然 SimpleDateFormat默认读取了当地时区,但在实际的国际化系统中,用户的所属时区是指其在系统录入的所属时区,而不是指当地时区。例如Tony这个用户账号挂在GMT+0时区,但此时他出差在香港使用,系统仍需要按照GMT+0时区来显示时间),为了解决这个问题,此时我们可以在 DateFormatConfig 注入当前登录人然后改变日期工具类的 TimeZone来动态修改时区。

Github上最值得学习的100个Java开源项目,涵盖各种技术栈!

根据当前登录人动态展示时区:

/**
 * 全局日期格式化
 */
@JsonComponent
public class DateFormatConfig {
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z") {
        @Override
        public Date parse(String source) throws ParseException {
            try {
                if (StringUtils.isEmpty(source)) {
                    return null;
                }
                return super.parse(source);
            } catch (Exception e) {
                return new StdDateFormat().parse(source);
            }
        }
    };
    private static UserController userController;//这里是指获取当前登录人的工具类
    @Autowired
    public void setUserController(UserController userController) {
        DateFormatConfig.userController = userController;
    }
    /**
     * 日期格式化
     */
    public static class DateJsonSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            //获取当前登录人的所属时区
            dateFormat.setTimeZone(TimeZone.getTimeZone(userController.get().getTimezone()));
            //格式化日期
            jsonGenerator.writeString(dateFormat.format(date));
        }
    }
    /**
     * 解析日期字符串
     */
    public static class DateJsonDeserializer extends JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            try {
                //获取当前登录人的所属时区
                dateFormat.setTimeZone(TimeZone.getTimeZone(userController.get().getTimezone()));
                //解析日期
                return dateFormat.parse(jsonParser.getText());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

修改完后重新启动应用并访问 http://127.0.0.1:8080 ,可以拿到正确结果:

{
  "userId": "1",
  "username": "socks",
  "password": "123456",
  "createTime": "2018-12-25 17:35:50 +0000",
  "timezone": "GMT"
}

小结

1、使用注解 @JsonComponent 可以快速自定义日期格式化的序列化器,免除传统通过模块注册的烦恼。

2、使用注解 @JsonComponent 实现与当地无关的动态时区的精髓就在于将获取当前等人的方法写在解析日期和格式化日期的代码里。

3、使用注解 @JsonComponent 是直接处理String和Date的相互转换的,所以要注意空串问题。例如dateFormat.parse()要预防空串。


(完)

MarkerHub文章索引:(点击阅读原文直达)

https://github.com/MarkerHub/JavaIndex
【推荐阅读】
理解这9大内置过滤器,才算是精通Shiro
花30分钟,用Jenkins部署码云上的SpringBoot项目
只需要6个步骤,springboot集成shiro,并完成登录
eblog项目讲解视频上线啦,长达17个小时!!

好文!必须点赞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个快速构建Spring应用程序的开发框架。在Spring Boot中,可以轻松地使用注解和配置来进行日期格式化全局日期格式化可以确保应用程序中的所有日期在显示和解析时都遵循相同的格式。 要实现全局日期格式化,首先需要创建一个自定义的日期格式化器。可以通过创建一个继承自 WebMvcConfigurationSupport 的类,并覆盖其方法来实现自定义日期格式化器。在该类中,可以调用 setDateFormatter 方法来设置日期格式化器,将日期格式化模式作为参数传递给自定义日期格式化器。 例如,假设想在应用程序中将日期格式化为"yyyy-MM-dd"格式。可以创建一个 CustomDateFormatter 类,实现 DateFormatter 接口,并在实现类的 toFormatter 方法中设置日期格式化模式为"yyyy-MM-dd"。然后,在自定义的 WebMvcConfigurationSupport 类中,覆盖其 configureMessageConverters 方法,并在该方法中调用 setDateFormatter 方法来设置日期格式化器为 CustomDateFormatter。 在应用程序中任何地方,只需要使用 @DateTimeFormat 注解,并指定日期格式即可将日期解析为指定格式。同样地,使用该注解在返回对象上,可以将日期字段格式化为指定格式。 总而言之,Spring Boot 提供了全局日期格式化的机制,使得应用程序中的日期在显示和解析时都能遵循统一的格式。通过自定义日期格式化器,可以轻松地实现指定的日期格式,并在应用程序中使用 @DateTimeFormat 注解格式化和解析日期。这样,可以确保应用程序中的日期始终遵循相同的格式要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值