论坛首页 入门技术论坛

java web将前台传递的request数据转换成指定对象

浏览 8410 次
该帖已经被评为新手帖
作者 正文
   发表时间:2012-11-08  
如在spring mvc中,获取前台传递的参数值并没有struts2那么方便,需要从request.getParameter来获取,比较麻烦,这里提供一个比较方便一点的方法(该方法经过一般性测试,还是可以使用的)

1、定义一个JsonRequest对象,包含三个成员变量,pageIndex、pageSize和Data,如下
public class JsonRequest<T> {
    /** 当前页 */
    private int pageIndex;
    
    /** 页面大小 */
    private int pageSize;
    
    /** 请求数据 */
    private T data;
    
    /**
     * 获取当前页
     * @return
     */
    public int getPageIndex() {
        return pageIndex;
    }
    
    /**
     * 设置当前页
     * @param pageIndex
     */
    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }
    
    /**
     * 获取页面大小
     * @return
     */
    public int getPageSize() {
        return pageSize;
    }
    
    /**
     * 设置页面大小
     * @param pageSize
     */
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    
    /**
     * 获取请求数据
     * @return
     */
    public T getData() {
        return data;
    }
    
    /**
     * 设置请求数据
     * @param data
     */
    public void setData(T data) {
        this.data = data;
    }
}


2、定义一个Conver转换器接口和ConverFactory,用来将String类型转换成其他指定的类型。定义如下:
public interface Conver<T> {
    /**
     * 将Object转换成对象,且转换过程中不会抛出异常
     * @param str
     * @return
     */
    public T conver(Object obj);
    
    /**
     * 将Object转换成对象,若该对象为null或转换过程中出现异常,则使用默认值
     * @param obj
     * @param defvalue
     * @return
     */
    public T conver(Object obj, T defvalue);
    
    /**
     * 将Object对象转换成数组
     * @param obj
     * @return
     */
    public T[] converArray(Object obj);
}


public final class ConverFactory {
    /** 转换器Map集合 */
    private static Map<Class<?>, Conver<?>> CONVER_MAP = new ConcurrentHashMap<Class<?>, Conver<?>>();
    
    /**
     * 静态语句块,设置Class与转换器的映射关系
     */
    static {
        CONVER_MAP.put(boolean.class, new BooleanConver(false));
        CONVER_MAP.put(Boolean.class, new BooleanConver());
        CONVER_MAP.put(byte.class, new ByteConver((byte) 0));
        CONVER_MAP.put(Byte.class, new ByteConver());
        CONVER_MAP.put(char.class, new CharacterConver((char) 0));
        CONVER_MAP.put(Character.class, new CharacterConver());
        CONVER_MAP.put(double.class, new DoubleConver(0.0));
        CONVER_MAP.put(Double.class, new DoubleConver());
        CONVER_MAP.put(float.class, new FloatConver(0f));
        CONVER_MAP.put(Float.class, new FloatConver());
        CONVER_MAP.put(int.class, new IntegerConver(0));
        CONVER_MAP.put(Integer.class, new IntegerConver());
        CONVER_MAP.put(long.class, new LongConver(0l));
        CONVER_MAP.put(Long.class, new LongConver());
        CONVER_MAP.put(short.class, new ShortConver((short) 0));
        CONVER_MAP.put(Short.class, new ShortConver());
        CONVER_MAP.put(String.class, new StringConver());
        CONVER_MAP.put(Date.class, new DateConver());
    }
    
    /**
     * 根据Class类型获取相应的类型转换器
     * @param clazz
     * @return
     */
    public static Conver<?> getConver(Class<?> clazz) {
        Conver<?> conver = CONVER_MAP.get(clazz);
        if (conver == null) {
            conver = new DefaultConver();
        }
        return conver;
    }
    
    /**
     * 私有构造方法
     */
    private ConverFactory() {
        
    }
}


3、将从request中获取的parameterMap转换成指定类型的对象,代码如下
public static <T> T toJavaBean(Map<?, ?> map, T object, Class<T> clazz) {
        T t = object;
        try {
            if (t == null) {
                t = clazz.newInstance();
            }
            
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                Type[] types = method.getGenericParameterTypes();
                if (methodName.startsWith("set") && methodName.length() > 3 && types != null && types.length == 1) {
                    try {
                        Class<?> pclass = (Class<?>) types[0];
                        String fieldName = methodName.toLowerCase().charAt(3) + methodName.substring(4);
                        Object value = map.get(fieldName);
                        
                        if (value != null) {
                            Class<?> _clazz = pclass;
                            Object _value = null;
                            Conver<?> conver = ConverFactory.getConver(_clazz);
                            if (pclass.isArray()) {
                                _value = conver.converArray(value);
                            }
                            else {
                                _value = conver.conver(value);
                            }
                            method.invoke(t, _value);
                        }
                    }
                    catch (Exception ex) {
                        
                    }
                }
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        
        return t;
    }


4、外部封装,调用3的toJavaBean方法,可以在BaseAction中实现,这样所有Action方法继承它就可以使用了,另外这里还提供了一个支持接送数据的方式。代码如下:
@SuppressWarnings("unchecked")
    public <T> JsonRequest<T> getRequestBody(HttpServletRequest request, Class<T> clazz) throws Exception {
        T t = null;
        JsonRequest<T> jsonRequest = null;
        boolean jsonAuth = Boolean.parseBoolean(request.getHeader("JsonAuthenticationFilter"));
        if (jsonAuth) {
            String jsonString = readRequestBody(request);
            try {
                jsonRequest = JSON.parseObject(jsonString, JsonRequest.class);
                t = JSON.parseObject(jsonString, clazz);
            }
            catch (Exception ex) {
                logger.warn("Unable to get a json data from request body");
            }
        }
        else {
            Map<?, ?> parameters = request.getParameterMap();
            t = (T) ReflectTools.toJavaBean(parameters, t, clazz);
            jsonRequest = ReflectTools.toJavaBean(parameters, jsonRequest, JsonRequest.class);
        }
        
        jsonRequest.setData(t);
        return jsonRequest;
    }

public static final String readRequestBody(ServletRequest request) throws UnsupportedEncodingException, IOException {
        String charset = request.getCharacterEncoding();
        if (charset == null) {
            charset = "utf-8";
        }
        
        BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), charset));
        CharArrayWriter data = new CharArrayWriter();
        char[] buf = new char[8192];
        int ret;
        while ((ret = in.read(buf, 0, 8192)) != -1) {
            data.write(buf, 0, ret);
        }
        
        return data.toString();
    }


5、实现Conver类,这里面可以定义IntegerConver、StringConver等等,代码如下

public abstract class AbstractConver<T> implements Conver<T> {
    /** 实体Class类型 */
    private Class<T> entityClass;
    
    /** 默认返回值,当转换后值为null则默认返回该值 */
    private T defvalue;
    
    @SuppressWarnings("unchecked")
    public AbstractConver() {
        ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
        entityClass = (Class<T>) type.getActualTypeArguments()[0];
    }
    
    public T conver(Object obj) {
        Object _obj = this.array2Object(obj);
        T result = this.converObject(_obj);
        if (result == null) {
            result = this.defvalue;
        }
        return result;
    }
    
    public T conver(Object obj, T defvalue) {
        Object _obj = this.array2Object(obj);
        T result = this.converObject(_obj);
        if (result == null) {
            result = defvalue;
        }
        return result;
    }
    
    public T[] converArray(Object obj) {
        T[] result = null;
        if (obj != null) {
            if (obj.getClass().isArray()) {
                Object[] _array = (Object[]) obj;
                result = getArray(_array.length);
                for (int i = 0; i < _array.length; i++) {
                    result[i] = this.converObject(_array[i]);
                }
            }
            else {
                result = getArray(1);
                result[0] = this.converObject(obj);
            }
        }
        return result;
    }
    
    /**
     * 在进行数据转换时,可能传入的是一个数组,这时在转换成JavaBean对象时,就需要把数组转换成对象<br>
     * 目前的处理方式是获取数组的第一个值
     * @param obj
     * @return
     */
    protected Object array2Object(Object obj) {
        if (obj != null && obj.getClass().isArray()) {
            if (((Object[]) obj).length > 0) {
                obj = ((Object[]) obj)[0];
            }
            else {
                obj = null;
            }
        }
        return obj;
    }
    
    /**
     * 将Object类型数据转换成指定类型值
     * @param obj
     * @return
     */
    protected abstract T converObject(Object obj);
    
    /**
     * 由于T类型不可new,且不能使用Class.newInstance()方式创建对象,所以需要每一个实现类各自new一个T类型的数组
     * @param length
     * @return
     */
    protected abstract T[] getArray(int length);
    
    /**
     * 获取泛型的实体Class类型
     * @return
     */
    public Class<T> getEntityClass() {
        return entityClass;
    }
    
    /**
     * 获取默认返回值,当转换后值为null则默认返回该值
     * @return
     */
    public T getDefvalue() {
        return defvalue;
    }
    
    /**
     * 设置默认返回值,当转换后值为null则默认返回该值
     * @param defvalue
     */
    public void setDefvalue(T defvalue) {
        this.defvalue = defvalue;
    }
}

public class IntegerConver extends AbstractConver<Integer> {
    /**
     * 默认的构造方法
     */
    public IntegerConver() {
        
    }
    
    /**
     * 具有指定默认值的构造方法
     * @param defvalue
     */
    public IntegerConver(Integer defvalue) {
        super.setDefvalue(defvalue);
    }
    
    protected Integer converObject(Object obj) {
        Integer result = null;
        try {
            if (obj != null) {
                if (obj instanceof Integer) {
                    result = (Integer) obj;
                }
                else {
                    result = Integer.parseInt(obj.toString());
                }
            }
        }
        catch (Exception ex) {
            
        }
        return result;
    }
    
    protected Integer[] getArray(int length) {
        return new Integer[length];
    }
}

public abstract class DatetimeConver<T extends Date> extends AbstractConver<T> {
    /** 默认的日期样式 */
    public static String DEFAULT_STYLE = "yyyyMMddHHmmss";
    
    /** 日期时间格式 */
    protected static List<String> dateStyles;
    
    /**
     * 静态语句块
     */
    static {
        dateStyles = new ArrayList<String>();
        dateStyles.add("yyyyMMdd");
        dateStyles.add("yyyyMMddHHmmss");
        dateStyles.add("yyyy-MM-dd");
        dateStyles.add("yyyy-MM-dd HH:mm:ss");
    }
    
    /**
     * 根据指定的日期时间字符串转换
     * @param value
     * @return
     */
    protected Date converDate(String value) {
        Date result = null;
        result = DateTools.getTime(value, DEFAULT_STYLE);
        if (result == null) {
            for (String style : dateStyles) {
                if (!DEFAULT_STYLE.equals(style)) {
                    result = DateTools.getTime(value, style);
                    if (result != null) {
                        break;
                    }
                }
            }
        }
        return result;
    }
    
    /**
     * 获取日期时间格式
     * @return
     */
    public static List<String> getDateStyles() {
        return dateStyles;
    }
    
    /**
     * 设置日期时间格式
     * @param dateStyles
     */
    public static void setDateStyles(List<String> dateStyles) {
        DatetimeConver.dateStyles = dateStyles;
    }
}

public class DateConver extends DatetimeConver<Date> {
    /**
     * 默认的构造方法
     */
    public DateConver() {
        
    }
    
    /**
     * 具有指定默认值的构造方法
     * @param defvalue
     */
    public DateConver(Date defvalue) {
        super.setDefvalue(defvalue);
    }
    
    protected Date converObject(Object obj) {
        Date result = null;
        try {
            if (obj != null) {
                if (obj instanceof Date) {
                    result = (Date) obj;
                }
                else {
                    result = super.converDate(obj.toString());
                }
            }
        }
        catch (Exception ex) {
            
        }
        return result;
    }
    
    protected Date[] getArray(int length) {
        return new Date[length];
    }
}
   发表时间:2012-11-08  
springmvc数据绑定已经很强大了,不知道哪方面没满足你的需求,能给个案例不
0 请登录后投票
   发表时间:2012-11-09  
最新的spring可以支持对象绑定了
0 请登录后投票
   发表时间:2012-11-09  
spring mvc现在还需要 用req.getParameter获取参数,我的神啊,太落伍了!!
0 请登录后投票
   发表时间:2012-11-09   最后修改:2012-11-09
引用

如在spring mvc中,获取前台传递的参数值并没有struts2那么方便,需要从request.getParameter来获取,比较麻烦


恳请楼主把这句话删除!建议楼主看些 SpringMVC入门级 的文章,磨刀不误砍柴工!
0 请登录后投票
   发表时间:2012-11-09  
-_-b 看来楼主得多看看 SpringMVC的文档。。。
0 请登录后投票
   发表时间:2012-11-12  
jinnianshilongnian 写道
springmvc数据绑定已经很强大了,不知道哪方面没满足你的需求,能给个案例不


如果应用程序就没用Spring框架,如何是好?

可有时间,做个研究完成 request到form bean的转换,以及 用tag库来完成 form的显示?
0 请登录后投票
   发表时间:2012-11-12  
xzcgeorge 写道
jinnianshilongnian 写道
springmvc数据绑定已经很强大了,不知道哪方面没满足你的需求,能给个案例不


如果应用程序就没用Spring框架,如何是好?

可有时间,做个研究完成 request到form bean的转换,以及 用tag库来完成 form的显示?

很多BeanUtils,如orika、common-beanutils(struts1使用该组件做绑定), tag的话如jstl等也有许多。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics