首页 > IT职业 > IT图书 > 自定义注解自动化翻译项目中的字典值
背景:
项目中经常会遇到需要把某些字典值翻译给前端,我们所有的字典值往往存在一个单独的表里,在业务表中只存储对应的code码,需要使用时则根据code码去查找对应字典项的名称。例如:我们的字典表为dict,表结构如下:

其中code就是字典项code码,name是字典项对应的名称,type是该字典值类型。
我们在业务表person中有个字段sex,代表性别,我们在该表中只存储其code值,需要用时才会根据code 值和type值查询其对应的名称,如下所示:
person表

dict表:

如果每次都手动查询dict表返回给前端太麻烦,有时项目中会缓存全量的字典值,需要用时从缓存中取值,这样做一方面会损耗系统性能,另一方面也不具有实时性。所以,我们需要对其进行改造,实现以下效果:
1、每次返回给前端code值时会自动去数据库查询对应的name值,而不需要手动处理。
2、支持通过注解设置返回给前端的字段名。
3、可以指定配置生效的controller,而对于未配置的controller不会生效。
解决方案:
1、创建自定义注解@DictField,
@JacksonAnnotationsInside
@JsonSerialize(using = DictSerializer.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictField {
//返回字段的字段名
String name() default "";
//字段在字典表中的类型
String value();
}
2、编写序列化处理逻辑
public class DictSerializer extends JsonSerializerimplements ContextualSerializer { private DictField dictField; private BeanProperty beanProperty; public DictSerializer(DictField dictField, BeanProperty beanProperty) { this.dictField = dictField; this.beanProperty = beanProperty; } public DictSerializer() { } public static String getDictName(String code,String type) { TransitSupportDictService transitSupportDictService = ApplicationContextUtil.getBean(TransitSupportDictService.class); return transitSupportDictService.getTypeName(code,type); } @Override //数据序列化时,会执行此方法,value是标注@DictField注解的字段值,即code码,通过getDictName(value,dictField.value())方法 //根据字段类型dictField.value()和code码查询出该字段名称,设置到字段名dictField.name()上。 public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { jsonGenerator.writeString(value); String dictName = getDictName(value,dictField.value()); if (StringUtils.isNotEmpty(dictName)) { String name = dictField.name(); if (name.length() == 0) { name = beanProperty.getName() + "_mc"; } jsonGenerator.writeStringField(name, dictName); } } @Override public JsonSerializer> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { if (beanProperty != null) { DictField dictField = beanProperty.getAnnotation(DictField.class); if (dictField != null) { return new DictSerializer(dictField, beanProperty); } else { return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty); } } return serializerProvider.findNullValueSerializer(null); } }
3、使用自定义注解

4.指定生效controller
由于我们项目中底层做了重写,默认使用fastjson,所以需要重新做拦截,针对指定的controller 改用jackjson我们之前的配置才会生效。
@ControllerAdvice public class TransitSupportDictResponseBodyAdvice implements ResponseBodyAdvice
5、最终效果

至此,即可实现自动化翻译项目中的字典值。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4571/viewspace-2797214/ ,如需转载,请注明出处,否则将追究法律责任。