作者:微信小助手
发布时间:2022-03-08T17:01
写接口时经常碰到要把某个枚举值返回给前端展示,然后前端要把这个枚举值显示成文本。在没有典文本映射功能之前前端就需要把这些枚举值和文本对应起来然后做展示,或者后台直接把枚举值转换成文本然后返回给前端。 如果后端能直接把枚举值的文本自动的设置到返回实体的某个属性上,这样就能解决了枚举值文体的转换问题了,话不多说开整。 字典本身并不复杂,所以设计实体也比较简洁: 各项属性说明如下: 上面的字典设计是非常直观的一个字典项对应数据库中的一行,相同的字典项由类型(type)来标识。 比如下面的响应就是经过字典文本映射的: 下面来一起看看如何利用 注解属性说明: 在 实现可以使用 大致的实现思路: 篇幅有限,省略了一些代码,利用 上面的代码已经实现了字典文本映射的功能,但还有一些可以优化一下:实体设计
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;
}
字典文本映射
{
"code": "SUCCESS",
"success": true,
"message": "操作成功",
"data": {
"id": "1496108440362811394",
"status": "DISABLE",
"statusDesc": "禁用",
...
}
}status
是一个字典值,statusDesc
是status
的文本表示。Spring
来实现字典文本映射的。定义字典属性注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DictProperty {
/**
* 字典类型
* @return
*/
String type();
/**
* 字典数据值属性名称
* @return
*/
String 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
返回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;
}
}SpringMV
C 提供扩展接口与Java反射
就可以轻松实现字典的文本映射。后续考虑
ResponseBodyAdvice
也能实现字典映射,只需要传入对象就能实现字典映射功能。