BaseServlet工具类

写一个项目往往需要N多个Servlet,而且一个servlet只有一个doGet或doPost.如果项目比较大,Servlet的数量会比较惊人。为了避免Servlet数量过多,我们可以在一个Servlet中写多个接收请求的方法。

具体思路:Servlet中处理请求的方法是service()方法,这说明我们需要让service()方法去调用其他方法。例如调用add()、mod()、del()、all()等方法。可以在请求时,添加一个参数,表示需要调用的方法名,然后在Servlet中判断。

实例代码:AServlet.java

public class AServlet extends javax.servlet.http.HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取method参数值
        String methodName=request.getParameter("method");
        
        //method参数值不能为空或null
        if(methodName==null||methodName.trim().equals("")){
            throw new RuntimeException("请输入需要访问的方法名");
        }

        //判断调用
        if(methodName.equals("addUser")){
            addUser(request,response);
        }else if(methodName.equals("updateUser")){
            updateUser(request,response);
        }else if(methodName.equals("queryUser")){
            queryUser(request,response);
        }else if(methodName.equals("deleteUser")){
            deleteUser(request,response);
        }
    }

    protected void addUser(HttpServletRequest request, HttpServletResponse response)
            throws javax.servlet.ServletException, IOException {
        System.out.println("addUser");
    }

    protected void updateUser(HttpServletRequest request, HttpServletResponse response)
            throws javax.servlet.ServletException, IOException {
        System.out.println("updateUser");
    }

    protected void queryUser(HttpServletRequest request, HttpServletResponse response)
            throws javax.servlet.ServletException, IOException {
        System.out.println("queryUser");
    }

    protected void deleteUser(HttpServletRequest request, HttpServletResponse response)
            throws javax.servlet.ServletException, IOException {
        System.out.println("deleteUser");
    }
}

这里需要注意:因为Servlet使通过service来调用其他方法,请求处理方法的签名必须与service相同:即返回值和参数,以及声明的异常都相同!

 

上面通过判断来决定调用那个方法,不方便扩展。这里我们通过反射,来自动调用对应的方法。

代码实现AServlet.java

public class AServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取method参数值
        String methodName=request.getParameter("method");

        //method参数值不能为空或null
        if(methodName==null||methodName.trim().equals("")){
            throw new RuntimeException("请输入需要访问的方法名");
        }

        //获得当前的类对象
        Class clazz=this.getClass();

        //创建反射中的方法对象
        Method method=null;

        try {
            /**
             * 调用类的getMethod获得方法
             * 第一个参数:类名
             * 后面的参数:方法的参数类型
             */
            method= clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(methodName+"(HttpServletRequest,HttpServletResponse)方法不存在!");
        }

        try {
            /**
             * 对比正常调用方法:this.addUser(request,response)
             */
            method.invoke(this,request,response);
        } catch (Exception e) {
            System.out.println(methodName+"(HttpServletRequest,HttpServletResponse)方法内部出现了异常!");
            throw new RuntimeException(e);
        }
    }

    protected void addUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("addUser");
    }

    protected void updateUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("updateUser");
    }

    protected void queryUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("queryUser");
    }

    protected void deleteUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("deleteUser");
    }
}

这里的Method getDeclaredMethod()和Method getMethod()需要区分一下:

  • getMethod():访问本类中定义的公共方法
  • getDeclaredMethod():访问本类中定义的所有方法

再进一步考虑,如果有多个Servlet,反射代码可以只写一次吗?

解决方案就是,将反射写在一个所有Servlet都继承的父类里面,下面我们就写一个这样的父类:BaseServlet.java

public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取method参数值
        String methodName=request.getParameter("method");

        //method参数值不能为空或null
        if(methodName==null||methodName.trim().equals("")){
            throw new RuntimeException("请输入需要访问的方法名");
        }

        //获得当前的类对象
        Class clazz=this.getClass();

        //创建反射中的方法对象
        Method method=null;

        try {
            /**
             * 调用类的getMethod获得方法
             * 第一个参数:类名
             * 后面的参数:方法的参数类型
             */
            method= clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(methodName+"(HttpServletRequest,HttpServletResponse)方法不存在!");
        }

        try {
            /**
             * 对比正常调用方法:this.addUser(request,response)
             */
            method.invoke(this,request,response);
        } catch (Exception e) {
            System.out.println(methodName+"(HttpServletRequest,HttpServletResponse)方法内部出现了异常!");
            throw new RuntimeException(e);
        }
    }
}

AServlet.java

public class AServlet extends BaseServlet {

    protected void addUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("addUser");
    }

    protected void updateUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("updateUser");
    }

    protected void queryUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("queryUser");
    }

    protected void deleteUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("deleteUser");
    }
}

BServlet.java

public class BServlet extends BaseServlet {
    protected void addNews(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("addNews");
    }

    protected void editNews(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("editNews");

    }
}

这里补充一个包含转发重定向的处理技巧:

很多时候我们访问函数需要实现转发重定向等作用,如果每次都在函数中写,可能有很多重复的代码。现在我们有了BaseServlet,可以把转发重定向等代码在BaseServlet中写,这样只要写一遍。

重写BServlet

public class BServlet extends BaseServlet {
    protected String addNews(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("addNews");
        //返回转发
        return "f:/index.jsp";

    }

    protected String editNews(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("editNews");
        //返回重定向
        return "r:"+request.getContextPath()+"/index.jsp";

    }
}

在需要转发重定项的函数直接在函数结束时返回一个字符串,包含一个标志字母(如f或r等),以及地址。

重写BaseServlet

public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取method参数值
        String methodName=request.getParameter("method");

        //method参数值不能为空或null
        if(methodName==null||methodName.trim().equals("")){
            throw new RuntimeException("请输入需要访问的方法名");
        }

        //获得当前的类对象
        Class clazz=this.getClass();

        //创建反射中的方法对象
        Method method=null;

        try {
            /**
             * 调用类的getMethod获得方法
             * 第一个参数:类名
             * 后面的参数:方法的参数类型
             */
            method= clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(methodName+"(HttpServletRequest,HttpServletResponse)方法不存在!");
        }

        try {
            /**
             * 对比正常调用方法:this.addUser(request,response)
             *
             * 返回值为一个字符串
             * 包好:表示为转发或是重定项
             * r:代表重定项
             * f:代表转发
             */
            String retstr = (String) method.invoke(this,request,response);

            //返回的字符串不能为空或是null
           if(retstr==null||retstr.equals("")){
               return;
           }

            if (retstr.contains(":")) {
                int index=retstr.indexOf(":");
                if(retstr.charAt(0)=='f'){//转发
                    request.getRequestDispatcher(retstr.substring(index+1)).forward(request,response);
                }else if(retstr.charAt(0)=='r'){//重定向
                    response.sendRedirect(retstr.substring(index+1));
                }
            }

        } catch (Exception e) {
            System.out.println(methodName+"(HttpServletRequest,HttpServletResponse)方法内部出现了异常!");
            throw new RuntimeException(e);
        }
    }
}

 

首先,我们需要创建一个Product实体类,用于存储商品信息。假设该类包含以下属性: ```java public class Product { private int id; private String name; private double price; private String description; // 其他属性 // getter和setter方法 } ``` 接着,我们需要创建一个ProductDao类,用于从数据库中获取商品信息。假设我们使用JDBC连接数据库,可以在ProductDao类中编写以下代码: ```java public class ProductDao { // 获取数据库连接的方法 // 查询所有商品信息的方法 public List<Product> getAllProducts() { List<Product> products = new ArrayList<>(); // 获取数据库连接 // 执行查询语句 // 将查询结果封装为Product对象,并添加到products列表中 // 关闭连接 return products; } } ``` 然后,我们需要创建一个ProductService类,用于调用ProductDao类中的方法获取商品信息。可以在ProductService类中编写以下代码: ```java public class ProductService { private ProductDao productDao; public ProductService() { productDao = new ProductDao(); } // 获取所有商品信息的方法 public List<Product> getAllProducts() { return productDao.getAllProducts(); } } ``` 接着,我们需要创建一个BaseServlet类,用于处理页面的请求。可以在BaseServlet类中编写以下代码: ```java public abstract class BaseServlet extends HttpServlet { // 处理GET请求的方法 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } // 处理POST请求的方法 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求的路径 // 根据路径调用相应的处理方法 } // 显示所有商品信息的方法 protected void showAllProducts(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ProductService productService = new ProductService(); List<Product> products = productService.getAllProducts(); request.setAttribute("products", products); request.getRequestDispatcher("/showAllProducts.jsp").forward(request, response); } } ``` 最后,我们需要创建一个showAllProducts.jsp页面,用于展示所有商品信息。可以在showAllProducts.jsp页面中编写以下代码: ```html <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>所有商品信息</title> </head> <body> <table> <thead> <tr> <th>ID</th> <th>名称</th> <th>价格</th> <th>描述</th> </tr> </thead> <tbody> <c:forEach items="${products}" var="product"> <tr> <td>${product.id}</td> <td>${product.name}</td> <td>${product.price}</td> <td>${product.description}</td> </tr> </c:forEach> </tbody> </table> </body> </html> ``` 以上代码演示了如何使用Java Web技术展示所有商品信息。当用户访问showAllProducts路径时,BaseServlet会调用showAllProducts方法,该方法会调用ProductService中的getAllProducts方法获取所有商品信息,并将其存储在request对象中,然后转发到showAllProducts.jsp页面展示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值