使用Java、hibernate validator注解校验入参,格式化出参(出参)

很多时候,后台通过ORM框架从数据库拿到表数据,需要对数据进行一些处理才抛给前端,常见的如格式化时间,在业务代码new一个SimpleDateFormat进行时间格式化处理。下面介绍以一种优雅的方式格式化出参,做一个贴心的后台程序员

出参改造前

数据库映射实体(省略get,set)

public class User {
    //id主键
    private Integer id;
    //名称
    private String name;
    //生日
    private Date birthday;
}

Controller

@ResponseBody
@RequestMapping("/get_users")
public List<User> getUsers() {
    //模拟读取数据库数据 begin
    List<User> result = new ArrayList<User>(2);
    User xiaoHua = new User();
    xiaoHua.setName("小花");
    xiaoHua.setBirthday(new Date());
    xiaoHua.setId(1);
    result.add(xiaoHua);
    User xiaoMing = new User();
    xiaoMing.setName("小明");
    xiaoMing.setBirthday(new Date());
    xiaoMing.setId(2);
    result.add(xiaoMing);
    //模拟读取数据库数据 end
    return result;
}

通过ORM框架获取两个用户对象,没有做数据格式处理,直接抛给前端

Json结果:

[
    {
        "birthday": 1505181715009,
        "id": 1,
        "name": "小花"
    },
    {
        "birthday": 1505181715009,
        "id": 2,
        "name": "小明"
    }
]

前端看见这个返回结果,我猜10个前端8个都黑脸,怎么说?生日(birthday)字段抛出去的是一个时间戳long类型,如果前端要显示友好标准时间格式(yyyy-MM-dd HH:mm:ss),需要做两步,1:通过时间戳new一个时间对象 2:格式化时间

格式化出参(一)

对User实体字段追加格式化注解

public class User {
    // id主键
    @JsonProperty(value = "objId")
    private Integer id;
    // 名称
    private String name;
    // 生日
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthday;
}

一些前端框架对id这一字段名比较敏感,所以这追加JsonProperty(com.fasterxml.jackson.annotation包)注解,进行别名处理;对birthday字段追加JsonFormat(com.fasterxml.jackson.annotation包)注解,对时间戳进行格式化

注:格式化注解针对出参类型为json适用,如果通过HttpServletRequest设值,需要手动转换

Json结果:

[
    {
        "birthday": "2017-09-12 21:55:17",
        "name": "小花",
        "objId": 1
    },
    {
        "birthday": "2017-09-12 21:55:17",
        "name": "小明",
        "objId": 2
    }
]

前端看到后台开发帮他们格式化好时间,想必忍不住要点赞

格式化出参(二)

刚才通过对映射实体追加格式化注解,达到出参格式化的目的,但此处还有需要完善的地方。假如获取用户详情API,生日birthday字段要的是yyyy-MM-dd格式的时间呢?此时@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)则不满足具体的业务场景了。此时我一般的做法是新建一个BO(Browse Object),不去“污染”映射实体

映射实体

public class User {
    private Integer id;
    // 名称
    private String name;
    // 生日
    private Date birthday;
}

BO

public class UserBO {
    // 名称
    private String name;
    // 生日
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date birthday;
}

Controller

@ResponseBody
@RequestMapping("/get_users")
public List<UserBO> getUsers() {
    // 模拟读取数据库数据 begin
    List<User> ormResult = new ArrayList<User>(2);
    User xiaoHua = new User();
    xiaoHua.setName("小花");
    xiaoHua.setBirthday(new Date());
    xiaoHua.setId(1);
    ormResult.add(xiaoHua);
    User xiaoMing = new User();
    xiaoMing.setName("小明");
    xiaoMing.setBirthday(new Date());
    xiaoMing.setId(2);
    ormResult.add(xiaoMing);
    // 模拟读取数据库数据 end

    // 返回结果
    List<UserBO> result = new ArrayList<UserBO>(ormResult.size());
    for (User item : ormResult) {
        UserBO bo = new UserBO();
        // org.springframework.beans.BeanUtils 复制对象属性值(名称,类型一致)
        BeanUtils.copyProperties(item, bo);
        result.add(bo);
    }
    return result;
}

json结果

[
    {
        "birthday": "2017-09-12",
        "name": "小花"
    },
    {
        "birthday": "2017-09-12",
        "name": "小明"
    }
]

增加一个BO层,出参跟映射实体就解耦了,BO对象可以根据具体的业务情景选择性的返回前端所需字段(以此UserBO为例,前端可能只需显示名称,跟生日;此时id值抛出去则多余了,所以BO剔除id字段)

聊一聊
后台跟前端一直都在争议这种数据处理到底归谁来做,毕竟大家都能处理是吧。刚一开始工作,我也很“懒”不作数据的处理直接抛出前端;但逐渐地我“控制欲”越来越强,无论是数据处理还是业务的处理,能够后台做的一般都不让前端来做,怎么说?

比如安卓,IOS各一开发调用一个后台API,如果让前端自行处理,安卓跟IOS都要处理一遍,而且处理的结果可能不一致,如果让后台来做,仅仅是处理一遍,且保证处理结果一致。所以,我主张数据能够后台处理的,尽量后台处理

使用Java、hibernate validator注解校验入参,格式化出参(入参)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值