数据字典以及业务标识字段,利用dozer和拦截器统一翻译回显页面

利用dozer与拦截器做字段翻译映射回显页面

通常任何系统做设计的时候,都会用到数据字典,复杂的系统可能还会有N多业务字段的标识,甚至树结构,而这些相关联的业务表中,存储的字段,都是只存一个id或者一个标识,但我们在页面给客户展示的时候,却是给客户展示这个标识所表达的完整意思。 比如一张个人信息表,可能会涉及,居住区域,性别,状态等等,在个人信息表,我们存储居住区域1,性别1,状态1,展示在页面的时候,却想要展示居住区域:北京,性别:男,状态:良好。
1.通常我们要实现上述功能,一种在查询的时候,用sql解决,但是这样,如果业务逻辑比较复杂,涉及的表多,关联查询的性能是很大问题。
2.另一种,会在程序端进行控制,遍历集合,然后处理,甚至更有在页面进行处理,这样整个的代码的通用性低,维护成本高,耦合度高。

这里我提供一种解决方案,如果页面返回的vo需要转换,只需一个在controller方法中增加一个注解,就可以解决,废话不多说,开始:

1.所属jar包,(默认是使用spring的了,spring的相关jar包都已经引好。)

<dependency>
			<groupId>net.sf.dozer</groupId>
			<artifactId>dozer</artifactId>
			<version>5.5.1</version>
		</dependency>

2.思路:dozer是一个对象转换的利器,只需要简单的配置,就可以进行对象间的映射,所以我们利用dozer进行对象映射,但是这样,每次需要需要转换都需要去调用dozer,所以在利用aop的方法拦截,做统一处理。

spring与dozer配置

<bean class="com.utils.dozer.service.DozerBeanMapperFactory">
		<property name="mappingFiles">
			<list>
				<value>classpath:dozer/**/dozer*.xml</value><!--这里指的是相关实体类转换的配置文件 -->
			</list>
		</property>
		<property name="customConvertersWithId">
			<map>
				<entry key="dict" value-ref="dictConverter" />
				<entry key="genericIntegerString" value-ref="genericIntegerStringConverter" />
				<entry key="genericStringString" value-ref="genericStringStringConverter" />
				<entry key="user" value-ref="userConverter" />
				<entry key="genericArrayString" value-ref="genericArrayStringConverter" />
				<entry key="yearsBetString" value-ref="yearsBetStringConverter" />
				<!-- 这里这些是指自定义的转换器,比如dictConverter就是数据字典的转换器
 -->
			</map>
		</property>
	</bean>
	<!-- <bean id="genericIntegerStringConverter" class="com.utils.dozer.converter.GenericIntegerStringConverter"/>
	<bean id="dictConverter" class="com.utils.dozer.converter.DictConverter"/> -->
	
	<context:component-scan base-package="com.utils.dozer" />


entry指的是自定义的转换器,key指和id对应,value-ref指的是对应转换器的class

dozer的
<mapping type="one-way">
		<class-a>com.facede.user.model.User</class-a>
		<class-b>com.web.portal.process.input.UserCondition</class-b>
		<field custom-converter-id="dict" custom-converter-param="1000001">
			<a>lDstate</a>
			<b>lDstateName</b>
		</field>
		
		<field custom-converter-id="genericStringString" 
			custom-converter-param="[A:我是A][B:我是B]">
			<a>cType</a>
			<b>cTypeName</b>
		</field>
		
	</mapping>

这里主要举例数据字典翻译器和一个通用的string转string的翻译器.这里user和userCondtion是映射的实体类,你可以,详情可以去dozer的官网看一下。
需要讲一下的是,custom-converter-id 和custom-converter-param的配合使用,官方文档里可能也没有这样使用。
custom-converter-id指的就是上面spring配置中entry的key,custom-converter-param指的是,在转换器中需要使用的参数


getParameter()获取custom-converter-param传递参数

我这里是在项目启动的时候 ,就把数据字典全都加载到了redis缓存中了,然后数据字典直接缓存取,当然可能出现新增的情况,缓存当中没有,如果缓存中没有,再去数据库取就是了
package com.utils.dozer.converter;


import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dozer.DozerConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.utils.redis.RedisCommonDao;


/**
 * 数据字典项目翻译
 * genius
 */
@Component
public class DictConverter extends DozerConverter<Integer, String> {

	private static final Log logger = LogFactory.getLog(DictConverter.class);
	
	@Autowired
	RedisCommonDao redisCommonDao;
	
	public DictConverter() {
		super(Integer.class, String.class);
	}

	@Override
	public String convertTo(Integer dictId , String destination) {
		if (null == dictId  || null == getParameter()) {
			return null;
		}
		String result = null;
		try {
			Integer dictModeId = NumberUtils.toInt(getParameter(), 0);//
			JSONObject value = (JSONObject) redisCommonDao.getValue("FY-"+dictModeId+"-"+dictId);
			result = value.getString("vcDataName");
		} catch (RuntimeException e) {
			logger.error("根据字典编号获取字典名称错误:" + e.getMessage());
		} catch (Exception e) {
			logger.error("根据字典编号获取字典名称错误:" + e.getMessage());
		}

		return result;
	}

	@Override
	public Integer convertFrom(String arg0, Integer arg1) {
		return null;
	}

}

然后自定义注解,这个这里就不贴代码了,如果有不明白的,可以百度一下spring自定义注解

拦截器中

这个地方配置的MethodInterceptor拦截器与原理,也不做讲解了,提供一个思路,需要用到拦截器
<!-- 翻译拦截器 -->
	<bean id="dozerCustomInterceptor" class="com.common.web.interceptor.DozerCustomInterceptor"></bean>
	<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<list>
				<value>*Controller</value>
			</list>
		</property>
		<property name="interceptorNames">
			<list>
				<value>dozerCustomInterceptor</value>
			</list>
		</property>
	</bean>	

public class DozerCustomInterceptor implements MethodInterceptor{
	
	@Autowired
	DozerMapperService dozerMapperService;

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object result = invocation.proceed();
		Method method = invocation.getMethod();
		Object[] arguments = invocation.getArguments();
		DozerCustomConverter dozerCustomConverter = AnnotationUtils.findAnnotation(method, DozerCustomConverter.class);
		if(dozerCustomConverter!=null && result!=null) {
			//进行dozer转换处理,如果有自定义注解,那么就需要做翻译处理,然后根据注解的类型,选择不同的转换处理,因为不同的类型返回的结果值存放的位置可能不同>
			Class<?> entryClass = (Class<?>)AnnotationUtils.getAnnotationAttributes(dozerCustomConverter).get("entryClass");
			DozerCustomConverterTYPE type = (DozerCustomConverterTYPE) AnnotationUtils.getAnnotationAttributes(dozerCustomConverter).get("value");
			
			if(type==DozerCustomConverterTYPE.SIMPLE) {
				result = this.resolveSimple(result,entryClass);
			} else if(type==DozerCustomConverterTYPE.JSONRESULT) {
				result = this.resolveJsonResult(result,entryClass);
			} else if(type==DozerCustomConverterTYPE.MODELANDVIEW) {
				result = this.resolveModelAndView(result,entryClass);
			} else if(type==DozerCustomConverterTYPE.VIEW && (result instanceof String || result instanceof View)) {
				this.resolveView(arguments,entryClass);
			} else if(type==DozerCustomConverterTYPE.JSONOFJSONRESULT) {
				result = this.resolveJsonofjsonResult(result,entryClass);
			}
		}
		return result;
	}



dozerService


package com.utils.dozer.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.dozer.BeanFactory;
import org.dozer.CustomConverter;
import org.dozer.DozerBeanMapper;
import org.dozer.DozerEventListener;
import org.dozer.Mapper;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;

/**
 * 
 * @author genius
 * 
 */
public class DozerBeanMapperFactory implements FactoryBean<Mapper>, InitializingBean, DisposableBean {

    private DozerBeanMapper beanMapper;
    private Resource[] mappingFiles;
    private List<CustomConverter> customConverters;
    private List<DozerEventListener> eventListeners;
    private Map<String, BeanFactory> factories;
    private Map<String, CustomConverter> customConvertersWithId;

    /**
     * @param mappingFiles
     *            Spring resource definition
     */
    public final void setMappingFiles(final Resource[] mappingFiles) {
        this.mappingFiles = mappingFiles;
    }

    public final void setCustomConverters(final List<CustomConverter> customConverters) {
        this.customConverters = customConverters;
    }

    public final void setEventListeners(final List<DozerEventListener> eventListeners) {
        this.eventListeners = eventListeners;
    }

    public final void setFactories(final Map<String, BeanFactory> factories) {
        this.factories = factories;
    }

    public final void setCustomConvertersWithId(Map<String, CustomConverter> customConvertersWithId) {
        this.customConvertersWithId = customConvertersWithId;
    }

    // ==================================================================================================================================
    // interface 'FactoryBean'
    // ==================================================================================================================================
    public final Mapper getObject() throws Exception {
        return this.beanMapper;
    }

    public final Class<Mapper> getObjectType() {
        return Mapper.class;
    }

    public final boolean isSingleton() {
        return true;
    }

    // ==================================================================================================================================
    // interface 'InitializingBean'
    // ==================================================================================================================================
    public final void afterPropertiesSet() throws Exception {
        this.beanMapper = new DozerBeanMapper();

        if (this.mappingFiles != null) {
            final List<String> mappings = new ArrayList<String>(this.mappingFiles.length);
            for (Resource mappingFile : this.mappingFiles) {
                mappings.add(mappingFile.getURL().toString());
            }
            this.beanMapper.setMappingFiles(mappings);
        }
        if (this.customConverters != null) {
            this.beanMapper.setCustomConverters(this.customConverters);
        }
        if (this.eventListeners != null) {
            this.beanMapper.setEventListeners(this.eventListeners);
        }
        if (this.factories != null) {
            this.beanMapper.setFactories(this.factories);
        }
        if (this.customConvertersWithId != null) {
            this.beanMapper.setCustomConvertersWithId(this.customConvertersWithId);
        }
    }

    /**
     * 
     * @throws Exception
     */
    public void destroy() throws Exception {
        if (this.beanMapper != null) {
            this.beanMapper.destroy();
        }
    }

}



package com.utils.dozer.service;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.dozer.Mapper;

/**
 * 翻译实现类
 * @author genius
 *
 */
@Singleton
@Named
public class DozerMapperService implements MapperService {

    @Inject
    private Mapper mapper;

    public <T> T map(Object source, Class<T> destinationClass) {
        return mapper.map(source, destinationClass);
    }

    public void map(Object source, Object destination) {
        mapper.map(source, destination);

    }

    public <T> T map(Object source, Class<T> destinationClass, String mapId) {
        return mapper.map(source, destinationClass, mapId);
    }

    public void map(Object source, Object destination, String mapId) {
        mapper.map(source, destination, mapId);
    }

    public <T> List<T> mapList(List<?> source, Class<T> destinationClass) {
        List<T> list = new ArrayList<T>();
        for (Object obj : source) {
            list.add(mapper.map(obj, destinationClass));
        }
        return list;
    }

    public <T> List<T> mapList(List<?> source, Class<T> destinationClass, String mapId) {
        List<T> list = new ArrayList<T>();
        for (Object obj : source) {
            list.add(mapper.map(obj, destinationClass, mapId));
        }
        return list;
    }

}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值