zoukankan      html  css  js  c++  java
  • BaseServlet 介绍

    1. BaseServlet 的作用

    • 让一个Servlet可以处理多种不同的请求,不同的请求调用Servlet的不同方法.

    2. 实现原理

    • 客户端发送请求时, 必须多给出一个参数, 用来说明要调用的方法!! 这样,BaseServlet 通过该参数来
      调用目标方法.
    • 请求处理方法的签名必须与 service 相同, 即方法的返回值和参数,以及声明的异常都相同.

    // 代码示例
        public class AServlet extends HttpServlet{
    
            // service 方法
            public void service(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    // 获取参数, 用来识别客户端想请求的方法
                    // 然后判断是哪一个方法, 是哪一个方法,就调用哪一个方法.
    
                    // 我们这里给参数的名字为 method
                    String methodName = req.getParameter("method");
    
                    if(methodName.equals("addUser")){
                        addUser(req,resp);
                    }else if(methodName.equals("editUser")){
                        editUser(req,resp);
                    }else if(methodName.equals("deleteUser")){
                        deleteUser(req,resp);
                    }
            }
    
            // 添加客户的方法
            public void addUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
                }
    
            // 编辑客户的方法
            public void editUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
            }
    
            // 删除客户的方法
            public void deleteUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
            }
        }
    
    
    // 升级版
        /*
         * 思路:
         *     得到方法名称, 是否可以通过反射来调用方法?
         * 步骤:
         *    1. 得到方法名, 通过方法名再得到 Method 类的对象
         *    2. 需要得到 class, 然后调用它的方法进行查询! 得到 Method
         *    3. 我们要查询的是当前类的方法, 所以我们需要得到当前类的 Class
         */
    
    public abstact class BaseServlet extends HttpServlet{
    
        public void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException{
    
                // 获取参数, 用来识别用户想请求的方法
                String methodName = req.getParameter("method");
    
                // 判断该参数是否存在, 不存在,抛出异常
                if(methodName == null || methodName.trim().isEmpty()){
                    throw new RuntimeException("您没有传递 method 参数! 无法确定您想调用的方法");
                }
    
                // 得到当前类的 class 对象
                 Class c = this.getClass();
    
                // 查询方法, 参数需要: 方法名和该方法的参数类型
                // 该方法的参数类型必须与 service 中的参数类型一致
                Method method = null;
                try{
                    method = c.getMethod(methodName,
                                    HttpServletRequest.class, HttpServletResponse.class);
                } catch(Exception e){
                    throw new RuntimeException("您要调用的方法"+methodName+",它不存在!");
                }
    
                // 调用 method 方法
                // 反射调用, 第一参数表示当前类,
                // 正常调用: this.method(req,resp)
                try{
                    method.invoke(this,req,resp);  
                } catch(Exception e){                    
                    throw new RuntimeException(e);
                }
    }
    
    // AServlet 继承 BaseServlet
    public void class AServlet extends BaseServlet{
            // 添加客户的方法
            public void addUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
                }
    
            // 编辑客户的方法
            public void editUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
            }
    
            // 删除客户的方法
            public void deleteUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
            }    
    }
    
    // 处理转发和重定向问题
    public void class BServlet extends BaseServlet{
    
            // 添加客户的方法
            public String addUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
    
                    // 返回表示转发的字符串, "f" 表示 forward
                    return "f:/index.jsp";
                }
    
            // 编辑客户的方法
            public String editUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
    
                    // 返回表示重定向的字符串, "r" 表示 redirect
                    return "r:/index.jsp";
            }
    
            // 删除客户的方法
            public String deleteUser(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException{
    
                    System.out.println("addUser()....");
    
                    return null;
            }    
    }
    
    // BaseServlet 升级
    public void abstract BaseServlet extends HttpServlet{
        public void service(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException,IOException{
    
                String methdoName = req.getParameter("method");
    
                if(methodName == null || methodName.trim().isEmpty()){
                    throw new RuntimeException("您没有传递method参数,无法确定要调用的方法!");
                }
    
                Class c = this.getClass();
    
                Method method=null;
                try{
                    method = c.getMethod(methodName,
                                HttpServletRequest.class,HttpServletResponse.class);
                }catch(Exception e){
                    throw new RuntimeException("您要调用的"+methodName+"方法,它不存在!");
                }
    
                // 调用 method 方法
    
                try{
    
                    String result = (String)method.invoke(this,req,resp);
    
                    /*
                     * 获取请求处理方法执行后返回的字符串, 它表示转发或重定向的路径!
                     * 完成转发或重定向.
                     *
                     *  如果用户返回的字符串为 null, 或为 "", 那么我们什么也不做!
                     *
                     * 查看返回的字符串中是否包含冒号, 如果没有, 表示转发
                     * 如果有, 使用冒号分割字符串, 得到前缀和后缀!!
                     * 其中前缀如果是 f, 表示转发, 如果是 r, 表示重定向, 后缀就是要转发或重定向的路径了!
                     */
    
                    if(result == null || result.trim().isEmpty()){
                        return;
                    }
    
                    // 如果不为空
                    if(result.contains(":")){
                        // 使用冒号分割字符串, 得到前缀和后缀
                        int index = result.indexOf(":"); // 获取冒号的位置
                        String s = result.substring(0,index);  // 获取前缀
                        String path = result.subString(index+1); // 获取后缀, 即路径
    
                        if(e.equalsIgnoreCase("r")){ // 如果前缀是 r, 重定向
                            resp.sendRedirect(req.getContextPath()+path);
                        }else if(e.equalsIgnoreCase("f")){
                            req.getRequestDispatcher(path).forward(req,resp);
                        } else {
                            throw new RuntimeException("您指定的操作:"+s+",当前版本不支持!");
                        }
    
                    } else { // 没有冒号, 默认为转发
                        req.getRequestDispatcher(result).forward(req,resp);
                    }
    
    
                }catch(Exception e){
                    throw new RuntimeException(e);
                }
        }
    }
    

    参考资料:

  • 相关阅读:
    【自然框架】 之 资源角色——列表过滤方案(思路篇)
    【自然框架】 之 主从表的添加、修改
    今天你进步了吗?
    【自然框架】通用权限的视频演示(一):添加角色,权限到功能节点和按钮
    【杂谈】您是以什么姿态来参与讨论、回帖的?
    【自然框架】之通用权限:用PowerDesigner重新设计了一下数据库,有ER图和表关系图
    【自然框架】 页面里的父类—— 改进和想法、解释
    页面里的父类——BaseUI源代码下载(2009.10.15更新)
    【自然框架】 页面里的父类——把共用的东东都交给父类,让子类专注于其他。
    【自然框架】之通用权限:数据库设计的几种使用方式
  • 原文地址:https://www.cnblogs.com/linkworld/p/7627132.html
Copyright © 2011-2022 走看看