• 类转换


    package zxc.utils;
    
    import java.lang.reflect.Member;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.SortedMap;
    import java.util.TreeMap;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    
    import org.springframework.util.StringUtils;
    
    import com.opensymphony.xwork2.inject.Inject;
    import com.opensymphony.xwork2.util.ObjectTypeDeterminer;
    import com.opensymphony.xwork2.util.XWorkBasicConverter;
    import com.opensymphony.xwork2.util.XWorkConverter;
    
    public class CustomShareConverter extends XWorkBasicConverter {
    	public static final String		SEQUENCE_SEPARATOR	= ",";
    
    	public static final String		MAP_SEPARATOR		= ":";
    
    	private ObjectTypeDeterminer	objectTypeDeterminer;
    
    	@Inject
    	public void setObjectTypeDeterminer(ObjectTypeDeterminer det) {
    		this.objectTypeDeterminer = det;
    	}
    
    	/**
    	 * 这里的toType一定是一个在配置文件将此转换器作为它的转换器的类或者是String类
    	 */
    	@SuppressWarnings("unchecked")
    	@Override
    	public Object convertValue(Map context, Object target, Member member, String property, Object value, Class toType) {
    		if (value == null || toType == String.class || ((String[]) value).length != 1) {
    			//注意第一个条比较怪,具体解释是:1.如果为null交给超类;2.如果向前台转,也交给超类;
    			//3.前台向后台转,且value不为null,但是前台传递同一个name多于一个值,则仍然使用超类转换
    			return super.convertValue(context, target, member, property, value, toType);
    		} 
    		String strValue = ((String[]) value)[0];//我现存在认为只要前台传值至少会有一个元素,放在这个表达式在这里确认一下
    		if (toType == Boolean.class) {
    			if (value == null || !StringUtils.hasText(strValue) || "null".equals(strValue)) {
    				return null;
    			} else if ("true".equals(strValue) || "1".equals(strValue)) {
    				return Boolean.TRUE;
    			} else {//注意:除去true,1,与null全部返回false
    				return Boolean.FALSE;
    			}
    		} else if (toType.isArray() || Collection.class.isAssignableFrom(toType)) {//向台向后台转,并且是单参数(即序列转数组)
    			String sequence = strValue;
    			if (!StringUtils.hasText(sequence)||"null".equals(sequence)) {
    				return null;//对序列情况的处理
    			}
    			//这里重写了拆分逻辑
    			value = new SequenceSplitor(sequence).split(SEQUENCE_SEPARATOR.charAt(0));
    			return super.convertValue(context, target, member, property, value, toType);
    		} else if (Map.class.isAssignableFrom(toType)) {
    			//超类并没有给出对map情况的处理,这里直接将它处理掉,但是map中的成员仍然是依赖超类处理
    			return convertToMap(context, target, member, property, value, toType);
    		}
    		
    		throw new RuntimeException("预期外的类型");
    	}
    
    	//将一个序列转换成一个Map
    	private Object convertToMap(Map<?, ?> context, Object target, Member member, String property, Object value, Class<?> toType) {
    		String sequence = ((String[]) value)[0];
    		String[] splitArray = new SequenceSplitor(sequence).split(SEQUENCE_SEPARATOR.charAt(0));
    
    		Class<?> keyClass = String.class;
    		Class<?> valueClass = String.class;
    		if (target != null) {
    			keyClass = this.objectTypeDeterminer.getKeyClass(target.getClass(), property);
    			valueClass = this.objectTypeDeterminer.getElementClass(target.getClass(), property, null);
    		}
    		Map<Object, Object> map = createMap(context, target, member, property, value, toType, splitArray.length);
    		for (int index = 0; index < splitArray.length; index++) {
    			String keyValue = splitArray[index];
    			//这里重写了拆分逻辑
    			String[] keyValuePair = new SequenceSplitor(keyValue).split(MAP_SEPARATOR.charAt(0));
    			//注意这个地方注入xworkConverter来进行转换,主要是怕遗漏Map中的键值有可能需要定制转换器,还有一点需要注意,传值使用字符串数组以模拟前台
    			Object key = XWorkConverter.getInstance().convertValue(context, null, null, null, new String[] { keyValuePair[0] }, keyClass);
    			Object val = XWorkConverter.getInstance().convertValue(context, null, null, null, new String[] { keyValuePair[1] }, valueClass);
    			map.put(key, val);
    		}
    
    		return map;
    	}
    
    	private Map<Object, Object> createMap(Map<?, ?> context, Object target, Member member, String property, Object value, Class<?> toType, int size) {
    		Map<Object, Object> map;
    		if (toType == ConcurrentMap.class) {
    			if (size > 0) {
    				map = new ConcurrentHashMap<Object, Object>(size);
    			} else {
    				map = new ConcurrentHashMap<Object, Object>();
    			}
    		} else if (toType == SortedMap.class) {
    			map = new TreeMap<Object, Object>();
    		} else {
    			if (size > 0) {
    				map = new HashMap<Object, Object>(size);
    			} else {
    				map = new HashMap<Object, Object>();
    			}
    		}
    
    		return map;
    	}
    
    }
    
  • 相关阅读:
    Python基础学习笔记(一)
    前端之jQuery
    JavaScript概述
    前端CSS
    前端HTML
    WIN10下Mysql安装使用
    python 创建线程
    Python 创建进程
    python day24模块
    python常用模块2(序列化,pickle,shelve,json,configparser)
  • 原文地址:https://www.cnblogs.com/qq1988627/p/6606890.html
Copyright © 2020-2023  润新知