web中,利用反射給物件賦值

qq_51347907發表於2020-12-26

在WEB專案中,利用反射得到jsp頁面的資料並完成給對應物件的賦值

目標—定義工具類,新增轉換方法。實現從請求取值並呼叫javaBean中相關setter訪問器

1>定義一個工具類

public class UtilParameter{ 

    /**
     * 將HTTP請求的引數賦值給指定型別JavaBean的相關屬性
     */
     public  static  Object method01(HttpServletRequest req, Class classs){ }
     /**
     * 此方法將請求引數值轉換為相關屬性的型別
     */
     public  static  Object  parseValue(String [] value, Class type){ }

}

2>建立將HTTP請求的引數賦值給指定型別JavaBean的相關屬性的方法

/**
     * 將HTTP請求的引數賦值給指定型別JavaBean的相關屬性
     * @param req     http請求
     * @param classs 目標JavaBean型別
     * @return       classs型別的例項
     * @throws Exception
     */
    public  static  Object method01(HttpServletRequest req, Class classs)throws Exception{
        //  建立類的例項
        Object object=classs.newInstance();
        //獲得object中所有方法
        Method[] methods=classs.getDeclaredMethods();
        //獲得表單中所有的文字域的name---從jsp頁面獲得
        Enumeration<String> parameteNames = req.getParameterNames();
        //判斷如果表單中有元素就進入迴圈
        while(parameteNames.hasMoreElements()) {
            //獲得每個文字域的name
            String parameteName = parameteNames.nextElement();
            //因為無法判斷文字域是否是單值或者雙值,所以我們全部使用雙值接收
            String[] parameteValues = req.getParameterValues(parameteName);
            //判斷如果這個name對應的值為空,或不存在,直接進行下一次迴圈
            if(parameteValues==null||parameteValues.length<=0){
                continue;
            }
            //列印parameteValues檢視jsp頁面輸入的值是否拿到
//            for (String parameteValue : parameteValues) {
//                System.out.println("-----"+parameteValue);
//            }

            //遍歷某類中的所有方法,從而獲取setXXX()方法
            for (Method method : methods) {
                //對set開頭的方法進行篩選
                if (method.getName().startsWith("set")) {
                    //得到此方法的引數列表
                    Class[] parameterTypes = method.getParameterTypes();
                    //獲取setXxx方法的Xxx...並把其轉換為小寫
                    String currentName = method.getName().substring(3,4).toLowerCase()+method.getName().substring(4);
                    //判斷如果此引數列表只有一個引數
                    if (parameterTypes.length == 1) {
                        //把從jsp頁面獲取的name引數名稱與currentName做對比,如果一樣,就執行賦值操作
                        if (currentName.equals(parameteName)) {
                            //放入引數值之前對引數列表型別進行判斷---parseValue()方法
                           Object obj=parseValue(parameteValues,parameterTypes[0]);
                            method.invoke(object,obj);
                        }
                    }
                }
            }
        }
        return object;
    }

3>建立一個將請求引數值轉換為相關屬性型別的方法

/***
     *
     * 此方法將請求引數值轉換為相關屬性的型別
     * @param value  對應值的型別
     * @param type   引數型別
     * @return   返回的值  各個型別
     * @throws Exception  丟擲錯誤
     */

    public  static  Object  parseValue(String [] value, Class type)throws Exception{
        //如果是陣列進入if塊
        if (type.isArray()) {
            //獲取type的型別
            Class componentType = type.getComponentType();
            //如果是String型別執行
            if (String.class == componentType)
                return value;
            else {//如果是其他型別
                //建立一個陣列型別是componentType型別,長度是傳過來的陣列長度
                //newInstance()方法的返回值是Object型別
                Object result = Array.newInstance(componentType, value.length);
                int i = 0;
                for (String one : value)
                    //set方法用於給指定陣列賦值
                    Array.set(result, (i++), parseValue(new String[]{one}, componentType));
                return result;
            }
        }
                //如果是String型別
                if(type==String.class){
                    return  value[0];
                }
                //如果是Boolean型別,預設給true,如有需要可根據需要更改
                if(type==Boolean.class ||type==boolean.class){
                    return true;
                }
                //古國是double型別
                if(type==double.class||type==Double.class){
                    return Double.parseDouble(value[0]);
                }
                //如果是short型別
                if(type==Short.class ){
                     return  Short.parseShort(value[0]);
                }
                //如果是long型別
                 if(type==Long.class ){
                     return  Long.parseLong(value[0]);
                }
                 //如果是int型別
                if (type==int.class||type==Integer.class){
                    return  Integer.parseInt(value[0]);
                }
                //如果是Date型別,其日期格式也可以根據需要更改
                if (Date.class==type){
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.parse(value[0]);
                }
                //如果是char型別
                if(char.class==type||Character.class==type){
                    return value[0].charAt(0);
                }
                //找不到此型別返回null
            return null;
    }

以上工具類就已完成。注意的是,jsp頁面中表單元素的name值要與pojo中實體類的屬性一一對應(名字要一樣)。

4>測試

在新增的servlet中的doGet()或doPost()方法中呼叫此轉換方法

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        try {
            UserInfoServiceImpl userInfoService=new UserInfoServiceImpl();
            //得到某類的類資訊
            Class cls=Class.forName("cn.bscp.pojo.UserInfo");
            //呼叫工具類中的轉換方法,完成指定物件的賦值
           UserInfo userInfo=(UserInfo) UtilParameter.method01(req,cls);
            //呼叫新增的方法
            int result= userInfoService.InsertUserInfo(userInfo);
          if(result>0){
              System.out.println("新增成功");
          }else {
              System.out.println("新增失敗");
          }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

加油每一天!?

相關文章