首页 > 代码库 > request 请求的参数封装为model

request 请求的参数封装为model

在一些应用中使用较为方便,比如你插入一行数据,通过Post或Get请求得到所有参数,而在一些时候我们是要直接操作对于数据行的一个bean对象,下面的是一个扩展性较好的方法。

注:常规编程时可以简单操作,如下一个bean

[java] view plain copy
  1. public class Student implements java.io.Serializable{  
  2.     private static final long serialVersionUID = 1L;  
  3.       
  4.     private String studentid;  
  5.     private String studentname;  
  6.     private String studentbir;  
  7.     private String studentsex;  
  8.       
  9.     public String getStudentid() {  
  10.         return studentid;  
  11.     }  
  12.   
  13.     public void setStudentid(String studentid) {  
  14.         this.studentid = studentid;  
  15.     }  
  16.   
  17.     public String getStudentname() {  
  18.         return studentname;  
  19.     }  
  20.   
  21.     public void setStudentname(String studentname) {  
  22.         this.studentname = studentname;  
  23.     }  
  24.   
  25.     public String getStudentbir() {  
  26.         return studentbir;  
  27.     }  
  28.   
  29.     public void setStudentbir(String studentbir) {  
  30.         this.studentbir = studentbir;  
  31.     }  
  32.   
  33.     public String getStudentsex() {  
  34.         return studentsex;  
  35.     }  
  36.   
  37.     public void setStudentsex(String studentsex) {  
  38.         this.studentsex = studentsex;  
  39.     }  
  40.       
  41.       
  42. }  

假设视图层将通过Post表单提交一个这样的参数集合:studentid=001,studentname=‘xiaoli‘,studentbir=‘1992-1-27‘,studentsex=‘男‘

我们在控制层通过多个getParameter()得到对于数据,接下来new Student(),对象赋值得到一个Student的bean,后面再使用什么spring之类的Dao层就插入数据库中持久化了。

以上方法简单也比较好理解,但是扩展性不好,你要是有成百上千个bean,那代码量都是这样,可想而知,冗余,维修性差……

 

2、下面是在一个项目中借鉴的操作性较好的方法,将任何请求(Post/ Get),参数混乱中的情况下拿到bean:

面向对象好处在之一少不了封装:下面是将任何请求所有参数封装为一个Map<String ,Object>,直接在控制层执行Map<String, Object> m=RequestUtils.getQueryParams(request);就可以啦,下面就是在工具类RequestUtils实现这个静态方 法:

 

[java] view plain copy
  1. @SuppressWarnings("unchecked")  
  2.     public static Map<String, Object> getQueryParams(HttpServletRequest request) {  
  3.         Map<String, String[]> map;  
  4.         if (request.getMethod().equalsIgnoreCase(POST)) {  
  5.             map = request.getParameterMap();  
  6.         } else {  
  7.             //为GET请求时就获取其请求参数的那段信息  
  8.             String s = request.getQueryString();  
  9.             if (StringUtils.isBlank(s)) {  
  10.                 return new HashMap<String, Object>();  
  11.             }  
  12.             try {  
  13.                 //将得到的HTML数据用UTF-8转码  
  14.                 s = URLDecoder.decode(s, UTF8);  
  15.             } catch (UnsupportedEncodingException e) {  
  16.                 log.error("encoding " + UTF8 + " not support?", e);  
  17.             }  
  18.             map = parseQueryString(s);  
  19.         }  
  20.   
  21.         Map<String, Object> params = new HashMap<String, Object>(map.size());  
  22.         int len;  
  23.         for (Map.Entry<String, String[]> entry : map.entrySet()) {  
  24.             len = entry.getValue().length;  
  25.             if (len == 1) {  
  26.                 params.put(entry.getKey(), entry.getValue()[0]);  
  27.             } else if (len > 1) {  
  28.                 params.put(entry.getKey(), entry.getValue());  
  29.             }  
  30.         }  
  31.         return params;  
  32.     }  

上面看出,两种请求下做了不同处理,最后将所有参数键值转化为一个Map,

这样之后就可以在控制层用String action=m.get("action").toString();的形式得到各种参数;

前面说了一个项目bean成百个,所有将参数集转化为bean也进行封装,如调用时:Student s=(OrgList) BeanConverter.toJavaBean(new Student(), m,true);m为上面得到的Map参数映射表,具体实现要使用到了Java的反射机制处理,也就是根据传入的bean对象,得到这个对象所在类,并获 取到这个类的所有声明了的方法:Method[] methods = javabean.getClass().getDeclaredMethods();再循环得到打头为set的方法,拿到这个方法的名字如 setStudentsex转换为一个参数studentsex,然后将这个参数与map中的key做识别,有相同的key便将其value插入该 bean中,具体实现如下:

[java] view plain copy
  1. public static Object toJavaBean(Object javabean, Map<String, Object> m,Boolean zhuanma)   
  2.    {   
  3.     //System.out.println(m);  
  4.     //所有声明了的方法  
  5.        Method[] methods = javabean.getClass().getDeclaredMethods();   
  6.        for (Method method : methods)   
  7.        {   
  8.                if (method.getName().startsWith("set"))   
  9.                {   
  10.                 //得到该方法的参数类型  
  11.                 Class<?>[] params = method.getParameterTypes();  
  12.                    String field = method.getName();   
  13.                    field = field.substring(field.indexOf("set") + 3);   
  14.                    field = field.toLowerCase().charAt(0) + field.substring(1);   
  15.                    //System.out.println(field+"----"+m.get(field.toString()));  
  16.                    Object value=http://www.mamicode.com/m.get(field.toString());
  17.                    try {  
  18.                        // convert types for some popular ones  
  19.                        if (value != null&&!"".equals(value)) {  
  20.                         String pa=params[0].getName().toString();  
  21.                         //if (value instanceof java.util.Date) {  
  22.                                if (pa.equals("java.util.Date")) {  
  23.                                    value = new java.util.Date(((java.util.Date) value).getTime());  
  24.                                }  
  25. //                           }  
  26.                            else if(pa.equals("java.lang.String")){  
  27.                             //value=http://www.mamicode.com/ new java.lang.String(Function.PageToDb(value.toString()));  
  28.                             if(zhuanma)value=http://www.mamicode.com/ new java.lang.String(Function.PageToDb(value.toString()));  
  29.                            }  
  30.                            else if(pa.equals("java.lang.Integer")||pa.equals("int")){  
  31.                              value=http://www.mamicode.com/ new java.lang.Integer(value.toString());  
  32.                            }else if (pa.equals("java.lang.Long")) {  
  33.                                 value=http://www.mamicode.com/ new java.lang.Long(value.toString());  
  34.                            } else if (pa.equals("java.lang.Double")) {  
  35.                              value=http://www.mamicode.com/ new java.lang.Double(value.toString());  
  36.   
  37.                            } else if (pa.equals("java.lang.Float")) {  
  38.                              value=http://www.mamicode.com/ new java.lang.Float(value.toString());  
  39.   
  40.                            } else if (pa.equals("java.lang.Short")) {  
  41.                              value=http://www.mamicode.com/ new java.lang.Short(value.toString());  
  42.   
  43.                            } else if (pa.equals("java.lang.Byte")) {  
  44.                              value=http://www.mamicode.com/ new java.lang.Byte(value.toString());  
  45.   
  46.                            } else if (pa.equals("java.lang.Character")) {  
  47.                             // value=http://www.mamicode.com/ new java.lang.Character(value);  
  48.   
  49.                            } else if (pa.equals("java.lang.Boolean")) {  
  50.                              value=http://www.mamicode.com/ new java.lang.Boolean(value.toString());  
  51.   
  52.                            }   
  53.                                  
  54.                                // Don‘t call setter if the value object isn‘t the right type   
  55.                                if (isCompatibleType(value, params[0])) {  
  56.                                    method.invoke(javabean, new Object[] { value });  
  57.                                } else {  
  58.                                  throw new Exception(  
  59.                                      "Cannot set " + field.toString() + ": incompatible types.");  
  60.                                }  
  61.                        }  
  62.                } catch(Exception e){  
  63.                 e.printStackTrace();  
  64.                }  
  65.        }   
  66.                }  
  67.   
  68.        return javabean;   
  69.    }  
  70. /////////////
  71. 本文前提:参数名称与实体属性一致!

    Java的Web项目中,经常有servlet中接收参数赋值给实体,参数如果多了就很麻烦,这里提供两个简单通用的方法:

    比如实体为Student

    1.使用org.apache.commons.beanutils.BeanUtils:

    ?
    1
    2
    Student stu =newStudent();
    BeanUtils.populate(stu, request.getParameterMap());

    当然实际工作中,有些参数值为空或者参数类型与实体属性类型不匹配,这就会报异常,因此这个不太可靠,这时可以用方法3

    2.利用反射:

    获得所有set方法,排除掉Object基类本身的set方法,从get方法中可以得到属性名,而属性名即是request的参数名

    3.(最推荐,经过测试) 改装populate方法:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    importjava.lang.reflect.Method;
    importjava.util.Date;
     
    importjavax.servlet.http.HttpServletRequest;
     
    importorg.apache.commons.lang3.ArrayUtils;
    importorg.apache.commons.lang3.StringUtils;
    importorg.apache.commons.lang3.math.NumberUtils;
    importorg.apache.commons.lang3.time.DateUtils;
     
    /**Servlet业务中实体工具
     * @author LiuDing
     * 2014-2-16-下午08:10:06
     */
    publicclassServletBeanTools {
         
        /**自动匹配参数赋值到实体bean中
         * @author LiuDing
         * 2014-2-16 下午10:23:37
         * @param bean
         * @param request
         */
        publicstaticvoidpopulate(Object bean, HttpServletRequest request){
            Class<!--?extendsObject--> clazz = bean.getClass();
            Method ms[] = clazz.getDeclaredMethods();
            String mname;
            String field;
            String fieldType;
            String value;
            for(Method m : ms){
                mname = m.getName();
                if(!mname.startsWith("set")
                        || ArrayUtils.isEmpty(m.getParameterTypes())){
                    continue;
                }
                try{
                    field = mname.toLowerCase().charAt(3) + mname.substring(4, mname.length());
                    value = http://www.mamicode.com/request.getParameter(field); >
                    if(StringUtils.isEmpty(value)){
                        continue;
                    }
                    fieldType = m.getParameterTypes()[0].getName();
                    //以下可以确认value为String类型
                    if(String.class.getName().equals(fieldType)){
                        m.invoke(bean, (String)value);
                    }elseif(Integer.class.getName().equals(fieldType) && NumberUtils.isDigits((String)value)){
                        m.invoke(bean, Integer.valueOf((String)value));
                    }elseif(Short.class.getName().equals(fieldType) && NumberUtils.isDigits((String)value)){
                        m.invoke(bean, Short.valueOf((String)value));
                    }elseif(Float.class.getName().equals(fieldType) && NumberUtils.isNumber((String)value)){
                        m.invoke(bean, Float.valueOf((String)value));
                    }elseif(Double.class.getName().equals(fieldType) && NumberUtils.isNumber((String)value)){
                        m.invoke(bean, Double.valueOf((String)value));
                    }elseif(Date.class.getName().equals(fieldType)){
                        m.invoke(bean, DateUtils.parseDate((String)value,"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"));
                    }else{
                        m.invoke(bean, value);
                    }
                }catch(Exception e){
                    e.printStackTrace();
                    continue;
                }
            }
        }
    }
    将request中的所有参数设置到entityClass类型的对象上
    1. public class RequestUtil {  
    2.       
    3.     /** 
    4.      * 将request中的所有参数设置到entityClass类型的对象上 
    5.      * @param entityClass 
    6.      * @param request 
    7.      * @return 
    8.      */  
    9.     public static Object copyParam(Class entityClass,HttpServletRequest request){  
    10.           
    11.         try {  
    12.             Object entity = entityClass.newInstance();  
    13.               
    14.             //把请求中的参数取出  
    15.             Map allParams = request.getParameterMap();  
    16.             Set entries = allParams.entrySet();  
    17.             for (Iterator iterator = entries.iterator(); iterator.hasNext();) {  
    18.                 Map.Entry entry = (Map.Entry) iterator.next();  
    19.                 String name = (String)entry.getKey();  
    20.                 String[] value = (String[])entry.getValue();  
    21.                   
    22.                 if(value != null){  
    23.                     if(value.length == 1){  
    24.                         BeanUtils.copyProperty(entity, name, value[0]);  
    25.                     }else{  
    26.                         BeanUtils.copyProperty(entity, name, value);  
    27.                     }  
    28.                 }  
    29.             }  
    30.             return entity;  
    31.         } catch (Exception e) {  
    32.             e.printStackTrace();  
    33.         }  
    34.           
    35.         return null;  
    36.     }  

     在到servlet页面上就可以直接写 


    Java代码   收藏代码
    1. Article a = (Article)RequestUtil.copyParam(Article.class, request);  
     不用在通过 request.getparamter();的一个个获取 在插入到article中 ,大大的减少了代码量
  72. Jakarta-Commons- BeanUtils学习笔记:

    Author:Tony.zhang  Date:April 22, 2009 Mail:setpsw@gmail.com

    1.什么是BeanUtils

    BeanUtils主要提供了对于JavaBean进行各种操作。

     

    2.BeanUtils的作用:

    在一般的写bean组件的时候,都必须要写settergetter方法,当然假如我们事先已经知道bean的相关属性和方法,写bean是比较简单的,但是组件太多的时候,重复编写经常是枯燥乏味令人厌烦的。但当有些时候我么需要调用动态对象的属性的时候,我们应该怎么来设定和获取对象的属性呢?BeanUtils就可以帮助我们来解决这个问题。它需要Jakarta-Commons -Collections包和Jakarta-Commons -logging包的支持。

     

    3. org.apache.commons.beanutils

    这个包主要提供用于操作JavaBean的工具类,Jakarta-Common-BeanUtils的主要功能都在这个包里实现。

    BeanUtils可以直接getset一个属性的值。它将property分成3种类型:

           1Simple——简单类型,如StirngInt……

      (对于Simple类型,第二个参数直接是属性名即可,详见代码)

           2Indexed——索引类型,如 数组、arrayList……

          对于Indexed,则为“属性名[索引值]”,注意这里对于ArrayList和数组都可以用一样的方式进行操作,详见代码)

           3Maped——这个不用说也该知道,就是指Map,比如HashMap……

           对于Map类型,则需要以“属性名(key值)”的形式,详见代码)

        访问不同类型的数据可以直接调用函数getPropertysetProperty。它们都只有2个参数,第一个是JavaBean对象,第二个是要操作的属性名。

     

    4.Converter RequestResultSet中的字符串绑定到对象的属性
      
    经常要从request,resultSet等对象取出值来赋入bean中,如果不用MVC框架的绑定功能的话,下面的代码谁都写腻了。
    String a = request.getParameter("a");   bean.setA(a);  

    String b = request.getParameter("b");  bean.setB(b);

    不妨写一个Binder自动绑定所有属性:

    复制代码

    MyBean bean = ;

            HashMap map 
    = new HashMap();

            Enumeration names 
    = request.getParameterNames();

            
    while (names.hasMoreElements())

            {

              String name 
    = (String) names.nextElement();

              map.put(name, request.getParameterValues(name));

            }

         BeanUtils.populate(bean, map);
    复制代码

     

     其中BeanUtilspopulate方法(Struts用于将一个map的值填充到一个bean)或者getProperty,setProperty方法其实都会调用convert进行转换。
        
    Converter只支持一些基本的类型,甚至连java.util.Date类型也不支持。而且它比较笨的一个地方是当遇到不认识的类型时,居然会抛出异常来。 对于Date类型,我参考它的sqldate类型实现了一个Converter,而且添加了一个设置日期格式的函数。
    要把这个Converter注册,需要如下语句:

    //因为要注册converter,所以不能再使用BeanUtils的静态方法了,必须创建BeanUtilsBean实例:

    BeanUtilsBean beanUtils  =

                
    new  BeanUtilsBean( convertUtils,  new  PropertyUtilsBean() ) ;

            beanUtils.setProperty( bean, name, value ) ;

     

     

    5.BeanUtilsStruts中的应用:

    下面的代码是我们经常在Struts中为了获得浏览器带来的参数的方法:

    复制代码
    DynaActionForm daf  =  (DynaActionForm)form ;

            User user 
    =   new  User() ;

            user.setId( daf.getString( 
    " id "  ) ) ;

            user.setPassword( daf.getString( 
    " password "  ) ) ;

            user.setUsername( daf.getString( 
    " password "  ) ) ;


    复制代码

     

    是不是觉得每次写这些都是在重复造轮子呢?

    在看看用BeanUtils写的:

    J

    BeanUtils.copyProperties( user, daf ) ;

     

    就是这么简单

     

    6.实例

    复制代码
    public   class  Test {

        
    private  String name; 

        
    private  HashMap address  =   new  HashMap(); 

        
    private  String[] otherInfo; 

        
    private  ArrayList product; 

        
    private  ArrayList employee; 

        
    private  HashMap telephone;

    省略get
    / set

    }
    复制代码

     

     

    MainClass:

    Jakarta-Commons- BeanUtils1.8.jar+JDK1.5

    复制代码
    package  com.cache.domain ;

     

    import  java.util.HashMap ;

     

    import  org.apache.commons.beanutils.BeanUtils ;

     

    /**

     * @Author:Tony.Zhang setpsw@gmail.com Apr 22, 2009 1:34:16 PM

     
    */

    public   class  MainClass {

     

        
    /**

         * 
    @param  args

         * 
    @throws  Exception

         
    */

        
    public   static   void  main( String[] args )  throws  Exception{

            Test test 
    =   new  Test();

            test.setName( 
    " zhangyi "  );

            
    //  BeanUtils.getProperty( bean, name )

            
    //  动态取得

            System.out.println(BeanUtils.getProperty( test, 
    " name "  ));

            

            HashMap map 
    =   new  HashMap();

            map.put( 
    " 1 " " 13880808080 "  );

            map.put( 
    " 2 " " 13550505050 "  );

            
    //  BeanUtils.setProperty( bean, name, value )

            BeanUtils.setProperty( test, 
    " telephone " , map );

            
    //  动态取得

            System.out.println(BeanUtils.getProperty( test, 
    " telephone(1) "  ));

           

            
    /**

             * 直接进行Bean之间的clone 复制后的2个Bean的同一个属性可能拥有同一个对象的ref,

             * 这个在使用时要小心,特别是对于属性为类的情况。

             
    */

            Test test2 
    =   new  Test();

            BeanUtils.copyProperties( test2, test );

            System.out.println(BeanUtils.getProperty( test2, 
    " name "  ));

            

        }

    }

    复制代码

     

    注:以上实例使用

    其余的功能大家继续挖掘吧,可以参考官方API的说明J

    ConvertUtilsBean convertUtils = new ConvertUtilsBean();

            DateConverter dateConverter 
    = new DateConverter();

            convertUtils.register(dateConverter,Date.
    class);