通过自定义注解设置JSON属性

本文介绍了如何通过自定义注解@Dict和Jackson的AnnotationIntrospector来实现在序列化实体为JSON时自动将字典编码转换为字典名称,从而减少对业务代码的入侵。详细讲解了注解的定义、处理类的实现以及配置过程,并给出了实现效果。
摘要由CSDN通过智能技术生成

在项目中,我们经常会使用到字典,数据库中保存字典编码,前端展示时需要显示字典名称。有很多方式可以实现,最简单粗暴的就是通过SQL关联查询,这种方式相对简单,但表的关联会一定程度上影响性能;另外一种方式是查询后,通过代码获取字典名称,我们可以将字典信息进行缓存提高效率,但这种方式对业务代码的入侵太多;还有一种方式是前端缓存字典信息,后端返回字典编码后再翻译为字典名称,这种方式需要考虑字典信息的一致性问题。

本文介绍的方案是在第二种方案基础上做了调整,尽可能减少对业务代码的入侵。

1、思路

我们获取获取字典名称只是为了在前端展示,实际业务处理中并不需要字典名称,因此是否可以将字典编码转名称这个工作放到最后一步(即实体序列化为JSON的时候)?通过搜索相关资料发现fasterxml(本文针对的fasterxml JSON序列化工具)提供了 com.fasterxml.jackson.databind.AnnotationIntrospector 抽象类,可以对序列化实体中的注解进行拦截,实现对字典的翻译(编码转名称)。好了,不废话,直接上代码。

2、定义注解@Dict

自定义一个注解,@Dict

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.FIELD,ElementType.METHOD})
public @interface Dict {

    /**
     * 数据字典类型
     * @return
     */
    String value() default "";

    /**
     * 数据字典名称属性名,翻译后字典名称保存的属性名称
     * @return
     */
    String name() default "";
}

3、AnnotationIntrospector.java


import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author Even
 */
public class DefaultAnnotationIntrospector extends JacksonAnnotationIntrospector {
    private static final Logger logger =
            LoggerFactory.getLogger(DefaultAnnotationIntrospector.class);
    /**
     * <自定义注解类名,注解处理类>
     */
    private Map<String,AnnotationHandler> annotationHandlerMap;

    @Override
    public Object findSerializer(Annotated am) {
        //如果没有设置任何注解处理类,则直接返回
        if(annotationHandlerMap==null || annotationHandlerMap.isEmpty()) {
            return super.findSerializer(am);
        }
        Iterator<Map.Entry<String,AnnotationHandler>> it =
                annotationHandlerMap.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String,AnnotationHandler> entry = it.next();
            //获取注解
            Annotation an = getAnnotation(am,entry.getKey());
            if(an != null){
                String fieldName = am.getName();
                //获取属性名
                if(fieldName.startsWith("get")){
                    String first = String.valueOf(fieldName.charAt(3)).toLowerCase();
                    fieldName = first + fieldName.substring(4);
                }
                if(logger.isDebugEnabled()){
                    logger.debug("serialize {} by {}",fieldName,entry.getValue());
                }
                return new AnnotationJsonSerializer
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值