zoukankan      html  css  js  c++  java
  • 利用请求分发思想和反射技术进行代码优化

    package com.csn.web;
    
    import com.csn.pojo.vo.PageBean;
    import com.csn.pojo.vo.Pagination;
    import com.csn.pojo.vo.Result;
    import com.csn.service.StudentService;
    import com.csn.util.BaseController;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    @WebServlet(urlPatterns = "/student/*")
    public class StudentServlet extends HttpServlet {
        private StudentService service = new StudentService();
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置请求和响应编码
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
    
            /*todo:请求分发 优化代码**/
    
            //1.获取方法名(请求地址中的具体需求eg:(student/selectByPage) )
            StringBuffer requestURL = request.getRequestURL();
            //切割地址 student/selectByPage
            int Index = requestURL.lastIndexOf("/");//拿到"/"的索引位 赋值给Index
            //用String的substring(a,b)方法截取字符串 (左包右不包)
            // substring(a,b)中的参数b,其值最大可以为 父字符串的长度,但并不包含索引值为b的那个字符。
            String method = requestURL.substring(Index + 1,requestURL.length());//切割:student/selectByPage => selectByPag 将selectByPag赋值给method方法
    
     /*       if(method.equals("selectByPage")) {
                //分页查询功能
                selectByPage(request,response);
            }else if(method.equals("addStu")) {
                //添加数据功能
                addStu(request,response);
            } else if(method.equals("updateStu")) {
                //修改数据功能
                updateStu(request,response);
            } else if(method.equals("deleteStu")) {
                //删除数据功能
                deleteStu(request,response);
            }*/
    
            /*todo:反射 优化代码*/
            //找到要反射的类
            try {
                Class aClass = this.getClass();//=StudentServlet.class
                //找到类中指定的方法, 方法名method
                Method m = aClass.getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);
                //调用方法
                m.setAccessible(true);//暴力反射 忽略访问权限的限制,直接调用 目的invoke方法的实现 权限检查
                //invok参数说明: this指调用此方法的对象,request,response 指调用参数
                /*
                *第一个参数:调用底层方法的对象
                *其他参数  :用于方法调用的参数
                * */
                m.invoke(this, request, response);//invoke()/**知识盲区,有机会再研究反射底层**/
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
    
        }
    
        private void deleteStu(HttpServletRequest request, HttpServletResponse response) {
        }
    
    
        private void updateStu(HttpServletRequest request, HttpServletResponse response) {
        }
    
    
        private void addStu(HttpServletRequest request, HttpServletResponse response) {
    
        }
    
        private void selectByPage(HttpServletRequest request, HttpServletResponse response) {
    
                //获取请求参数
                try{
                    //获取请求体中的json格式参数并映射到Pagination中
                    Pagination pagination = BaseController.parseJSON2Object(request, Pagination.class);
    
                    //调用业务层的查询方法
                    PageBean page = service.selectByPage(pagination);
                    //响应给客户端
                    //将Result对象转成json,并用响应给前端
                    BaseController.printResult(response,new Result(true,"查询成功!",page));
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    try {
                        BaseController.printResult(response, new Result(false, "查询失败o(╥﹏╥)o!"));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
        }
    }

    invok()官方API:

    invoke

    public Object invoke(Object obj,
                         Object... args)
                  throws IllegalAccessException,
                         IllegalArgumentException,
                         InvocationTargetException
    对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。

    如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。

    如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

    如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。

    如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。

    如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。

    参数:
    obj - 从中调用底层方法的对象
    args - 用于方法调用的参数
    返回:
    使用参数 argsobj 上指派该对象所表示方法的结果
    抛出:
    IllegalAccessException - 如果此 Method 对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。
    IllegalArgumentException - 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。
    InvocationTargetException - 如果底层方法抛出异常。
    NullPointerException - 如果指定对象为 null,且该方法是一个实例方法。
    ExceptionInInitializerError - 如果由此方法引起的初始化失败。
  • 相关阅读:
    全文本的检索
    网卡配置
    linux解压命令
    Session
    swoole安装
    Linux 系统磁盘满处理方法
    php写入和读取文件内容
    PHP读取文件夹的文件列表
    php 公历农历互相转换
    PHP实现RESTful风格的API实例
  • 原文地址:https://www.cnblogs.com/axibug/p/14992615.html
Copyright © 2011-2022 走看看