精华内容
下载资源
问答
  • BaseServlet继承于HttpServlet,主要使用反射完成servlet后端方法的分发。具体步骤如下: 1.获取请求路径; 2.获取方法名称; 3.获取方法对象(哪个子类继承BaseServlet,那么代码中的this就代表该子类) 4.获取方法...

    BaseServlet如何完成servlet的分发:

    BaseServlet继承于HttpServlet,主要使用反射完成servlet后端方法的分发。具体步骤如下:

    1.获取请求路径;

    2.获取方法名称;

    3.获取方法对象(哪个子类继承BaseServlet,那么代码中的this就代表该子类)

    4.获取方法,执行方法。

    public class BaseServlet extends HttpServlet{
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1.获取请求路径
            String uri = req.getRequestURI();
            System.out.println("请求uri:"+ uri);
            //2.获取方法名称  login
            String methodName = uri.substring(uri.lastIndexOf('/') + 1);
            System.out.println("方法名称:"+ methodName);
            //3.获取方法对象Method
            //哪个子类继承BaseServlet,那么this就代表该子类
            try {
                //获取方法
                Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
                //4.执行方法
                method.invoke(this,req,resp);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
    
        }
    
    

    与传统重写service方法相比:

    原来是一个功能一个Servlet,现在优化为一个模块一个Servlet,由BaseServlet进行方法的转发,并承担一些公共方法的抽取;

    BaseServlet 相当于是项目中所有servlet的父类,让每个模块继承BaseServlet即可;

    BaseServlet让一个servlet可以同时处理多个请求,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。

    图解

    展开全文
  • 今天用类似反射的技术()重写service方法

    昨天在写一个AJAX网页时用类似反射的技术重写servlet的service方法,实现一个servlet多种功能,将主要功能数据库更新(添加新用户)放在doGet()里,次要功能数据库查询(查询用户名是否已存在)放在另一个方法里。实际运行时发现在进行查询操作时总是返回true。查看代码发现eclipse在重写的service方法的首行自动生成了super.service(request,reponse);语句。该语句尝试调用父类的service方法。

    代码示例:

    class Father {
    public void service() {
    System.out.println("Method service() of Father is running...");
    doGet();
    }
    public void doGet() {
    System.out.println("Method doGet() of Father is running...");
    }

    class Son extends Father{
    public void service() {
    super.service();
    }
    public void doGet() {
    System.out.println("Method doGet() of Son is running...");
    }
    public static void main(String[] args) {
    Son son=new Son();
    son.service();
    }
    }

    运行结果:

    Method service() of Father is running...
    Method doGet() of Son is running...


    该自动生成语句导致用于添加新用户的doGet()方法总是被调用,于是在调用查询某个用户名是否存在时,由于该用户名已被添加到数据库,故总是返回true。

    展开全文
  • 在原生的web中,我们要重写HttpServlet中的doGet()或者doPost()方法来实现对url的拦截和处理。 我们通常在前端中action="url?method=methodName"来把多个url请求放到同一个servlet中拦截。 package ...

    在原生的web中,我们要重写HttpServlet中的doGet()或者doPost()方法来实现对url的拦截和处理。

    我们通常在前端中action="url?method=methodName"来把多个url请求放到同一个servlet中拦截。

    package com.igeekhome.ebuy.web.servlet;
    
    import com.igeekhome.ebuy.pojo.Admin;
    import com.igeekhome.ebuy.service.AdminService;
    import com.igeekhome.ebuy.service.impl.AdminServiceImpl;
    
    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 javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    @WebServlet(name = "AdminServlet", urlPatterns = {"/admin/admin", "/admin/manager"})
    public class AdminServlet extends HttpServlet {
    
        private AdminService adminService = new AdminServiceImpl();
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
    //这里利用method参数来确定要执行的方法
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String method = request.getParameter("method");
            if("login".equals(method)) {
                login(request, response);
            } else if("logout".equals(method)) {
                logout(request,response);
            }
        }
    
        private void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
            session.invalidate();
    
            response.sendRedirect(this.getServletContext().getContextPath() + "/admin/login.jsp");
        }
    
        private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String code = request.getParameter("code");
            String pasw = request.getParameter("pasw");
    
            Admin admin = adminService.login(code, pasw);
            if(admin == null) {
                request.setAttribute("adminInfo", "账号或密码错误!");
                request.getRequestDispatcher("/admin/login.jsp").forward(request, response);
            } else {
                HttpSession session = request.getSession();
                session.setAttribute("admin", admin);
                response.sendRedirect(this.getServletContext().getContextPath() + "/admin/manager/index.jsp");
            }
        }
    
    }
    
    

    但是会出现一个问题,当url请求过多的时候,我们要写很多的判断语句。

    那么有没有一种方法,可以让我们专注在业务逻辑和代码的编写上面呢?

    有,利用反射!首先创建一个BaseServlet extends HttpServlet,这样就可以对里面的service方法(也就是doGet和doPost方法进行重写)。通过暴力反射可以动态的获取具体执行子类的类Class,然后利用反射动态调用这个类的方法!

    
    /**
     * 抽取公用的BaseServlet
     *
     * ?method=value
     *      - value与方法名称相同  -> 调用的方法名字 -> 反射
     *                                          -> Class
     */
    public class BaseServlet extends HttpServlet {
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        /**
         * method - 调用的当前Servlet类中方法
         *
         * doGet + doPost
         * service
         */
    //  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String method = request.getParameter("method");   //调用的当前Servlet类中方法
            Class clasz = this.getClass();      //url访问 - this
            try {
                //依据方法名获取对应的Class的Method方法
                Method reflectMethod = clasz.getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);
                reflectMethod.setAccessible(true);      //暴力反射
    
                //调用方法
                reflectMethod.invoke(this, request, response);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    

    然后,像往常一样创建一个servlet extends BaseServlet,这样就等于继承了HttpServelt,同时继承了父类BaseServlet的service()方法,也就是doGet()和doPost()方法。

    package com.igeekhome.ebuy.web.servlet;
    
    import com.igeekhome.ebuy.pojo.Smallkind;
    import com.igeekhome.ebuy.service.SmallKindService;
    import com.igeekhome.ebuy.service.impl.SmallKindServiceImpl;
    
    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.io.PrintWriter;
    import java.util.List;
    import java.util.Map;
    
    @WebServlet(name = "SmallKindServlet", urlPatterns = {"/skind", "/admin/manager/skind"})
    public class SmallKindServlet extends BaseServlet {
    
        private SmallKindService smallKindService = new SmallKindServiceImpl();
    
    //我们只需要专注于代码和方法的编写,而不再需要去写service层的方法选择调用。简化了servlet的代码,看起来更加符合我们的编程规范
        private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Map<String, String[]> parameterMap = request.getParameterMap();
    
            int add = smallKindService.add(parameterMap);
            response.sendRedirect(this.getServletContext().getContextPath() + "/admin/manager/skind?method=list");
        }
    
        /**
         * ajax - 验证子种类是否已存在
         */
        private void getSmallKindByName(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String name = request.getParameter("name");
            String kindId = request.getParameter("kindId");
    
            long count = smallKindService.getSmallKindCountByName(name, kindId);
    
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.print(count);
            writer.flush();
            writer.close();
        }
    
        /**
         * ajax - 获取大种类对应小种类
         */
        private void smallKindList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String kindId = request.getParameter("kindId");
            String smallKIndJson = smallKindService.getSmallKindByKindId(kindId);
    
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.print(smallKIndJson);
            writer.flush();
            writer.close();
        }
    
        /**
         * 获取小种类列表
         */
        private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            List<Smallkind> list = smallKindService.getList();
            request.setAttribute("list", list);
            request.getRequestDispatcher("/admin/manager/menu/skindList.jsp").forward(request, response);
        }
    
    }
    
    

    反射,框架的灵魂!简单,实用!

    展开全文
  • 本打算继承一个API中的Parent类(Parent继承自GrandParent类),重写其中的service方法,copy了Parent的service方法。不过发现Parent的service中也有super.service方法。当时考虑直接调用GrandParent的service方法。...
    本打算继承一个API中的Parent类(Parent继承自GrandParent类),重写其中的service方法,copy了Parent的service方法。不过发现Parent的service中也有super.service方法。当时考虑直接调用GrandParent的service方法。。。未遂(包括反射也不行)。正好看到老外写的一篇文章,翻译:
    在Son类里面写一个test方法:
    展开全文
  • 通过继承HttpServlet(该类即为模板类),重写service方法(在service通过反射获得相应的方法,执行,并跳转到相应的页面),其他功能模块的Servlet类继承该类,并提供相应的方法,方法可返回要跳转的页面路径。...
  • 建立一个Servlet基类,并重写service方法,主要实现判断自己的这个类中是否存在action参数值中对等的方法,如果有调用invoke方法执行这个方法。 其他的Servlet继承这个基类,并写下不同请求所对应的不同方法,因为...
  • //重写HttpServlet中的service方法自定义分发方式 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { Str
  • 通过反射,web.xml配置

    2018-07-02 11:50:00
    1.写一个模拟的servlet接口,其中有三个方法init,service,destroy 写一个实现类重写这三个方法,然后写一个web.xml配置此实现类,写一个测试类,通过反射,给我调用实现类的三个方法 package demo04; ...
  • 1.创建BaseServlet (重写父类的service方法) package com.learning.web.servlet; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; ...
  • 项目总结

    2019-08-23 16:05:03
    BaseServlet ...之后的Servlet继承BaseServlet,不会自己重写service方法,而是去调用父类的service方法,这样就可以通过反射去执行子类相应的请求方法。 优势:这个时候我们就可以把执行类似操作的方法放...
  • servlet的优化

    2020-10-10 21:52:14
    //重写service方法,就不走doGet或doPost方法了 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //目标:实现一个...
  • 此类继承BaseServlet类,BaseServlet继承HttpServlet,再根据Servlet的生命周期,会执行service方法,所以在BaseServlet中重写service方法,再在service方法中通过反射去执行到每个具体的Servlet类中的每个模块功能...
  • Servlet合并案例小结

    2020-09-28 19:24:41
    写一个BaseServlet,继承HttpServlet,重写service方法。调用方法名,利用反射获得方法,利用invoke实现 写一个UserServlet,继承BaseServlet,将原先的增删改查的servlet写成方法。 BaseServlet package ...
  • javaweb项目中随着功能的增加servlet文件的数目也随着增加,如果每个功能都写一个servlet最后文件量...还有一种方法就是抽取公共的servlet继承HttpServlet重写service方法,利用反射技术执行继承了该公共类的子类中...
  • 关于BaseServlet

    2018-01-26 14:11:17
    BaseServlet 是项目中所有servlet的父类,作用是为了让一个servlet可以同时处理多个请求,因为我们之前比如说完成对于商品的增删改查的时候,每一个需求就要创建一个servlet,这样会显得很臃肿,所以...重写service方法  
  • 我看了您的访问私有变量的方法,那是因为您重写了toString方法,相当于你自己还是提供了访问提口给它,因为System.out.println(p)实际会执行p.toString(); 然后再打印出来的,这跟反射机制应该没有什么关系吧~~呵呵~...
  • 1. 写在前面平常都使用封装好的 servlet ,这次项目需要用到反射,所以用到 继承 HttpServlet ,重写 -service() 方法,结果项目报如上错误,查了很多地方,如下 ...http://blog.51cto.com/woshixy/1136705 都没解决我...
  • C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。 【面试题库网整理 .net 面试题(附答案)(三)】 22.您要创建一个显示公司员工列表的应用程序。您使用一个...
  • 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    描述反射机制的作用 62.如何读写一个文件? 63.在图形界面中,一个按钮如何处理鼠标点击事件? 64.在图形界面中,一个表格,如何实现编辑单元格时弹出下拉框? 65.如何加载图片? 66.什么是模态对话框? 67....
  • asp.net知识库

    2015-06-18 08:45:45
    通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: State Server Gems 完整的动态加载/卸载程序集的解决方案 从NUnit中理解.NET自定义属性的应用(转载) 如何在.NET中实现脚本引擎 (CodeDom篇) .NET的插件...
  • 关键是要重写几个获取资源、主题的方法,以及重写getClassLoader方法 5、插件中的LayoutInfalter 通过第4步构造出来的Context获取LayoutInfater即可 6、如何实现插件代码不依赖任何特殊代码,如继承特定的...
  • asp.net面试题

    2011-05-27 17:56:26
    十三、为了实现a.aspx的URL重写,下面哪个正则表达式替换可以实现?( ) A. Regex.Replace(sUrl, @“/(\d+).aspx”, “a.aspx?ID=$0”, RegexOptions.IgnoreCase) B. Regex.Replace(sUrl, @“/(\d+).aspx”, “/a....
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...
  • 2.7.2 给main()方法传递参数 52 2.8 有关编译c#文件的更多内容 52 2.9 控制台i/o 54 2.10 使用注释 56 2.10.1 源文件中的内部注释 56 2.10.2 xml文档 56 2.11 c#预处理器指令 58 2.11.1 #define和 #undef 59 2.11.2 ...

空空如也

空空如也

1 2
收藏数 34
精华内容 13
关键字:

反射重写service方法