1.前言
在处理完数据返回前端时,通常需要做字典翻译,此时就需要一个好用的处理工具,但是依然不方便,对此,再次封装了一次。
原理 在接口返回时拦截 --- 反射获取对应字典信息 -- 查询字典值 --- 再次塞入对象里面 --- 返回信息
2.代码
字典类型处理
import java.lang.annotation.*;
/**
* 字典类型处理 拦截
* <p>常用返回类型处理,不进行四层深层处理</p>
*
* @author wbw
* @date 2020/11/10 11:40
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DictTypeSensible {
/**
* 实体类字段
*/
String value();
/**
* 字典code,默认使用 value 转下划线形式
*/
String code() default "";
}
多个字典值
import java.lang.annotation.*;
/**
* 多个字典值
*
* @author wbw
* @date 2020/11/1316:53
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DictTypeSensibles {
/**
* 多个字典值
*
* @return 多个值
*/
DictTypeSensible[] value();
}
字典拦截转换处理
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gl.common.core.domain.AjaxResult;
import com.gl.common.data.page.TableDataInfo;
import com.gl.common.data.vo.R;
import com.gl.core.annotation.DictTypeSensible;
import com.gl.core.annotation.DictTypeSensibles;
import com.gl.system.service.ISysDictDataService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 字典拦截转换处理
*
* @author wbw
* @date 2020/11/10 17:55
*/
@ControllerAdvice
@AllArgsConstructor
@Slf4j
public class DictTypeSensibleAspect implements ResponseBodyAdvice<Object> {
private final ISysDictDataService dictDataService;
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return methodParameter.hasMethodAnnotation(DictTypeSensible.class)
|| methodParameter.hasMethodAnnotation(DictTypeSensibles.class);
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType
, Class clazz, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (ObjectUtil.isEmpty(o)) {
return null;
}
// 获取方法 注解参数
Method method = methodParameter.getMethod();
final String methodName = method == null ? ""
: (method.getDeclaringClass().getSimpleName() + "." + method.getName());
DictTypeSensible[] sensibles;
if (methodParameter.hasMethodAnnotation(DictTypeSensible.class)) {
DictTypeSensible sensible = methodParameter.getMethodAnnotation(DictTypeSensible.class);
sensibles = new DictTypeSensible[]{sensible};
} else {
DictTypeSensibles typeSensibles = methodParameter.getMethodAnnotation(DictTypeSensibles.class);
sensibles = typeSensibles == null ? new DictTypeSensible[]{} : typeSensibles.value();
}
// 处理返回值
this.dis(o, sensibles, methodName);
return o;
}
/**
* 处理返回数据
*
* @param obj 对象
* @param sensibles 字典类型
*/
private void dis(Object obj, DictTypeSensible[] sensibles, String methodName) {
// 处理返回类型
if (obj instanceof TableDataInfo) {
this.dis(((TableDataInfo) obj).getRows(), sensibles, methodName);
return;
}
if (obj instanceof AjaxResult) {
this.dis(((AjaxResult) obj).get(AjaxResult.DATA_TAG), sensibles, methodName);
return;
}
if (obj instanceof R) {
this.dis(((R) obj).getData(), sensibles, methodName);
return;
}
if (obj instanceof IPage) {
((IPage) obj).getRecords().forEach(e -> this.dis(e, sensibles, methodName));
return;
}
if (obj instanceof Iterable) {
((Iterable) obj).forEach(e -> this.dis(e, sensibles, methodName));
return;
}
if (obj instanceof Map) {
Map<String, Object> map = (Map<String, Object>) obj;
for (DictTypeSensible sensible : sensibles) {
if (!map.containsKey(sensible.value())) {
log.warn("--- 方法 {},字典 {} 进行忽略,不存在 ------", methodName, sensible.value());
continue;
}
Object o = map.get(sensible.value());
if (o instanceof Iterable) {
this.dis(o, sensibles, methodName);
continue;
}
String code = StrUtil.isEmpty(sensible.code())
? StrUtil.toUnderlineCase(sensible.value()) : sensible.code();
String label = dictDataService.selectDictLabel(code, String.valueOf(o));
map.put(sensible.value(), label);
}
return;
}
Class<?> clazz = obj.getClass();
for (DictTypeSensible sensible : sensibles) {
try {
Field field = ReflectUtil.getField(clazz, sensible.value());
if (field == null || !field.getType().getSimpleName().contains("String")) {
log.warn("--- 方法 {},字典 {} 进行忽略,不存在 || 非String类型 ------", methodName, sensible.value());
continue;
}
Object val = ReflectUtil.getFieldValue(obj, field);
if (ObjectUtil.isEmpty(val)) {
continue;
}
String code = StrUtil.isEmpty(sensible.code())
? StrUtil.toUnderlineCase(sensible.value()) : sensible.code();
String label = dictDataService.selectDictLabel(code, String.valueOf(val));
ReflectUtil.setFieldValue(obj, field, label);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}