zoukankan      html  css  js  c++  java
  • servlet仿struts参数注入

    在struts中可以在action中声明一个成员变量如Game game和Date date,接口访问时可以通过http://xxx.com/xxx/addGameScore?game.gameID=xx&&game.score=10&&date=xxx的方式

    直接将参数注入。用servlet模拟struts的参数注入,可以使用一个servlet对应一个接口集,如只创建一个servlet就可以处理所有关于玩家Player相关的接口

    代码如下:

    创建一个PlayerServlet

     1 /**
     2  * 玩家相关入口
     3  *
     4  */
     5 public class PlayerServlet extends HttpServlet {
     6     private static final long serialVersionUID = -5269133950459049991L;
     7 
     8     public PlayerServlet() {
     9         super();
    10     }
    11 
    12     public void destroy() {
    13         super.destroy(); 
    14     }
    15 
    16     public void doGet(HttpServletRequest request, HttpServletResponse response)
    17             throws ServletException, IOException {
    18         handleService(request,response);
    19     }
    20 
    21     public void doPost(HttpServletRequest request, HttpServletResponse response)
    22             throws ServletException, IOException {
    23         handleService(request,response);
    24     }
    25     //提交给servlet的参数中必须包含target参数,值为对应action的public方法
    26     //处理业务逻辑
    27     private void handleService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
    28         PlayerAction playerAction = new PlayerAction();
    29         ServletUtil.handleServletRequest(playerAction, request, response);
    30         playerAction = null;
    31     }
    32     
    33     public void init() throws ServletException {
    34         
    35     }
    36 }

    如struts一样,需要一个PlayerAction,里面的成员变量为注入的参数,公共方法为对应的逻辑方法 

    创建PlayerAction

     1 /**
     2  * 玩家相关Action
     3  */
     4 public class PlayerAction extends BaseAction{
     5 
     6     private Integer playerID;
     7     
     8     private String playerNickName;
     9     
    10     private Player player;
    11     
    12     private IPlayerService playerService;
    13     
    14     public PlayerAction(){
    15         this.playerService = new PlayerServiceImpl();
    16     }
    17     /**玩家登陆*/
    18     public void playerLogin(){
    19         System.out.println("playerAccount:"+player.getPlayerAccount());
    20         System.out.println("playerPassword:"+player.getPlayerPassword());
    21     }
    22     /**查询玩家信息*/
    23     public void findPlayer(){
    24         try {
    25             response.getWriter().write("玩家ID:"+playerID+",昵称:"+playerNickName);
    26         } catch (Exception e) {
    27             e.printStackTrace();
    28         }
    29     }
    30     
    31 //===========相关get和set方法======================================
    32     public void setPlayerID(Integer playerID) {
    33         this.playerID = playerID;
    34     }
    35 
    36     public void setPlayerNickName(String playerNickName) {
    37         this.playerNickName = playerNickName;
    38     }
    39 
    40     public void setPlayer(Player player) {
    41         this.player = player;
    42     }
    43     public Player getPlayer() {
    44         return player;
    45     }
    46 }

    核心servletUtil,使用java反射注入参数

      1 /**
      2  * servlet工具类,提供servlet向action自动注入参数的相关工具
      3  *
      4  */
      5 public class ServletUtil {
      6     /**
      7      * 处理servlet请求,完成request、response和其它参数注入
      8      * @param baseAction
      9      * @param request
     10      * @param response
     11      */
     12     @SuppressWarnings({ "unchecked", "rawtypes" })
     13     public static void handleServletRequest(BaseAction baseAction,
     14             HttpServletRequest request,HttpServletResponse response){
     15         try {
     16             //注入request和response
     17             requestAndResponseInject(baseAction, request, response);
     18             Map<String, String[]> argsMap  = request.getParameterMap();//获取提交参数
     19             String targetMethod = request.getParameter("target");//获取调用目标方法名
     20             Iterator<Entry<String, String[]>> iterator= argsMap.entrySet().iterator();
     21             while(iterator.hasNext()){
     22                 Entry<String, String[]> entry = iterator.next();
     23                 String key = entry.getKey();
     24                 if(!key.equals("target")){
     25                     ServletUtil.propertyInject(key,entry.getValue(),baseAction);//注入参数
     26                 }
     27             }
     28             Class actionClass = baseAction.getClass();
     29             Method method = actionClass.getDeclaredMethod(targetMethod);
     30             method.invoke(baseAction);//调用目标方法
     31         } catch (Exception e) {
     32             e.printStackTrace();
     33         }
     34     }
     35     
     36     /**
     37      * 向目标action注入request和response对象
     38      * @param target 目标action
     39      * @param request
     40      * @param response
     41      * @throws Exception
     42      */
     43     @SuppressWarnings("rawtypes")
     44     private static void requestAndResponseInject(Object target,
     45             HttpServletRequest request,HttpServletResponse response) throws Exception{
     46         Class actionClass = target.getClass();
     47         Field[] fields = actionClass.getFields();
     48         for(Field f:fields){
     49             if(HttpServletRequest.class.isAssignableFrom(f.getType())){
     50                 f.setAccessible(true);
     51                 f.set(target, request);
     52             }else if(HttpServletResponse.class.isAssignableFrom(f.getType())){
     53                 f.setAccessible(true);
     54                 f.set(target, response);
     55             }
     56         }
     57     }
     58     /**
     59      * 属性注入,支持基本类型、时间和对象,List和Set泛型只支持基本类型
     60      * @param key 属性键
     61      * @param value 值
     62      * @param target 注入目标
     63      * @throws Exception
     64      */
     65     @SuppressWarnings({ "rawtypes", "unchecked" })
     66     public static void propertyInject(String key,String[] value,Object target)throws Exception{
     67         Class actionType = target.getClass();
     68         //非自定义复合对象
     69         if(!key.contains(".")){
     70             Field field = actionType.getDeclaredField(key);
     71             Class fieldType = field.getType();
     72             //获取setXXX方法
     73             Method method=actionType.getDeclaredMethod("set"+key.substring(0, 1).toUpperCase()+key.substring(1),fieldType);
     74             if(List.class.isAssignableFrom(fieldType)){//List泛型
     75                 List<Object> list = new ArrayList<Object>();
     76                 //获取泛型类型
     77                 Type[] argType = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();
     78                 for(int i=0;i<value.length;i++){
     79                     list.add(generateNormalValue((Class)argType[0],value[i]));//填入List
     80                 }
     81                 method.invoke(target,list);//注入List
     82             }else if(Set.class.isAssignableFrom(fieldType)){
     83                 Set<Object> set = new HashSet<Object>();
     84                 Type[] argType = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();
     85                 for(int i=0;i<value.length;i++){
     86                     set.add(generateNormalValue((Class)argType[0],value[i]));
     87                 }
     88                 method.invoke(target,set);
     89             }else{
     90                 method.invoke(target,generateNormalValue(fieldType,value[0]));//基本类型
     91             }
     92         }else{//自定义复合对象属性
     93             generateObjectValue(key,value[0],target);
     94         }
     95     }    
     96     
     97     /**
     98      * 生成基本类型值
     99      * @param fieldType 字段类型
    100      * @param value 值
    101      * @return
    102      * @throws Exception
    103      */
    104     @SuppressWarnings({ "rawtypes", "unchecked" })
    105     private static Object generateNormalValue(Class fieldType,Object value)throws Exception{
    106         //如果为时间类型,转换时间
    107         if(Date.class.isAssignableFrom(fieldType)){
    108             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    109             Date date = sdf.parse(value.toString());
    110             return date;
    111         }else{//Integer、String、Long等封装类型
    112             //获取单参构造函数
    113             Constructor<String> ctor = fieldType.getConstructor(String.class);
    114             return ctor.newInstance(value);
    115         }
    116     }
    117     
    118     /**
    119      * 生成自定义对象值
    120      * @param key 属性键
    121      * @param value 值
    122      * @param target 注入目标
    123      * @throws Exception
    124      */
    125     @SuppressWarnings({ "rawtypes", "unchecked" })
    126     private static void generateObjectValue(String key,Object value,Object target)throws Exception{
    127         String subKey = key;
    128         Class targetType = target.getClass();
    129         String[] keys = key.split("\.");//分割键
    130         subKey = keys[0];
    131         Field field = targetType.getDeclaredField(subKey);
    132         Class fieldType = field.getType();
    133         //获取setXXX方法
    134         Method setMethod=targetType.getDeclaredMethod("set"+subKey.substring(0, 1).toUpperCase()+subKey.substring(1),fieldType);
    135         if(keys.length>1){
    136             Constructor<String> ctor = fieldType.getConstructor();//获取默认构造函数
    137             //获取getXXX方法
    138             Method getMethod=targetType.getDeclaredMethod("get"+subKey.substring(0, 1).toUpperCase()+subKey.substring(1));
    139             Object subTarget = getMethod.invoke(target);
    140             if(null==subTarget){
    141                 subTarget = ctor.newInstance();//调用无参构造函数
    142             }
    143             setMethod.invoke(target, subTarget);//对象注入
    144             generateObjectValue((key.split("\.", 2))[1],value,subTarget);//子属性还是对象,递归注入
    145         }else{
    146             setMethod.invoke(target,generateNormalValue(fieldType,value));//子属性为基本类型
    147         }
    148     }
    149 }

    代码中的BaseAction就是一个普通的类,包含了request和response成员变量和相关的数据输出方法

     1 /**
     2  * action基类,包含request和response信息及数据输出方法
     3  *
     4  */
     5 public class BaseAction {
     6 
     7     public HttpServletRequest request;
     8 
     9     public HttpServletResponse response;
    10 //==数据输出方法==
    11 //....
    12 }

    web.xml

    1   <!-- 玩家相关请求入口 -->
    2     <servlet-name>PlayerServlet</servlet-name>
    3     <servlet-class>com.xxx.servlet.PlayerServlet</servlet-class>
    4   </servlet>
    5   <servlet-mapping>
    6     <servlet-name>PlayerServlet</servlet-name>
    7     <url-pattern>/player</url-pattern>
    8   </servlet-mapping>

    调用方式:

    调用登陆方法:http://www.xxx.com/项目根/player?target=playerLogin&player.playerAccount=xx&player.playerPassword=xxx

    调用查询方法:http://www.xxx.com/项目根/player?target=findPlayer&player.playerID=xx

    本文地址:http://www.cnblogs.com/wangjiajun/p/4788308.html 

  • 相关阅读:
    文件上传之 MultipartFile
    EL表达式从数组 Map List集合取值
    Servlet监听器
    分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)
    分页技术框架(Pager-taglib)学习二(SSH数据库分页)
    分页技术框架(Pager-taglib)学习一(页面分页)
    从request获取各种路径总结
    jsp的页面包含——静态包含、动态包含
    Java对象的浅克隆和深克隆
    Java序列化与反序列化学习(三):序列化机制与原理
  • 原文地址:https://www.cnblogs.com/wangjiajun/p/4788308.html
Copyright © 2011-2022 走看看