SpringMVC + 反射轻松实现字典文本映射功能!

大家好,我是霸戈,好久没有写代码(文章)了, 闲下来整理了一篇文章,感谢大家的阅读和支持。

写接口时经常碰到要把某个枚举值返回给前端展示,然后前端要把这个枚举值显示成文本。在没有典文本映射功能之前前端就需要把这些枚举值和文本对应起来然后做展示,或者后台直接把枚举值转换成文本然后返回给前端。

如果后端能直接把枚举值的文本自动的设置到返回实体的某个属性上,这样就能解决了枚举值文体的转换问题了,话不多说开整。

实体设计

字典本身并不复杂,所以设计实体也比较简洁:

public class Dict {
    private String id;
    private String name;
    private String value;
    private String type;
    private String pid;
    private String status;
    private Integer sort;
    private String description;
}

各项属性说明如下:

  • id : 字典的id

  • name: 字典的名称,一般用于前端展示

  • value:字典的值

  • type:字典的类型

  • status: 字典的状态

  • sort: 排序

  • description: 字典的描述信息

  • pid: 上级字典id,有些特殊的字典有上下级关系,比如存放城市的时候

上面的字典设计是非常直观的一个字典项对应数据库中的一行,相同的字典项由类型(type)来标识。

字典文本映射

比如下面的响应就是经过字典文本映射的:

{
  "code": "SUCCESS",
  "success": true,
  "message": "操作成功",
  "data": {
    "id": "1496108440362811394",
    "status": "DISABLE",
    "statusDesc": "禁用",
    ...
  }
}

status是一个字典值,statusDescstatus的文本表示。

下面来一起看看如何利用Spring来实现字典文本映射的。

定义字典属性注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DictProperty {

    /**
     * 字典类型
     * @return
     */
    String type();

    /**
     * 字典数据值属性名称
     * @return
     */
    String value();
}

注解属性说明:

  • type:对应字典的类型属性

  • value: 字典数据值属性名称

如何使用?
@Data
public class UserDTO {

    private String status;
   
    @DictProperty(type = "user_status", value = "status")
    private String statusDesc;
}

UserDTO里面的status属性是字典的值, statusDesc是字典值的名字。

实现方式

实现可以使用aop,但我发现SpringMVC提供了个非常好的切入点:ResponseBodyAdvice,继承此接口就能对请求的响应做一些小修改。

public interface ResponseBodyAdvice<T> {

 boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

 @Nullable
 T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
   Class<? extends HttpMessageConverter<?>> selectedConverterType,
   ServerHttpRequest request, ServerHttpResponse response);

}
  • supports方法:判断实体类型是否能处理

  • beforeBodyWrite: 如果supports返回ture,就会执行这个方法,这个方法可以修改返回的实体。

大致的实现思路:

  • beforeBodyWrite方法利用Java反射来读取实体属性的DictPropty注解

  • 解析DictPropty注解的type的值,然后通过字典类型获取到对应的字典

  • 读取到对应类型的字典后,将字典的name写入到实体的属性上

@Slf4j
@ControllerAdvice
public class DictResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Autowired
    private IDictService dictService;

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    
        if(body instanceof Result){
            handleBody(((Result) body).getData());
        }else if(body instanceof IPage){
            handleBody(((IPage) body).getRecords());
        }else{
            handleBody(body);
        }
        return body;
    }
}

篇幅有限,省略了一些代码,利用 SpringMVC 提供扩展接口与Java反射就可以轻松实现字典的文本映射。

后续考虑

上面的代码已经实现了字典文本映射的功能,但还有一些可以优化一下:

  • 读取字典的时候要加缓存,防止数据量过大读取字典的字数过大,拖慢接口的响应速度

  • 可以不通过ResponseBodyAdvice也能实现字典映射,只需要传入对象就能实现字典映射功能。

  • ...


项目推荐
分享一套家庭理财系统(附源码)
推荐一套开源通用后台管理系统(附源码)
推荐一个酷炫的监控系统
从朋友那里搞了 20 个实战项目,速领!
推荐一个完善的停车管理系统,物联网项目springboot,附源码
推荐一个互联网企业级别的开源支付系统
一款神仙接私活儿软件,吊到不行!
推荐 10 款超实用的企业级开源应用!
开放平台 SDK 设计实践!
“淘宝” 开放平台接口设计思路
Spring中经典的9种设计模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值