JavaWeb阶段性项目1:系统的servlet优化5


前置知识

前置准备

知识准备

已掌握JavaSE/MySQL/JDBC+HTML/CSS/JavaScript基础

并已完成了Javaweb前置知识的学习

01-JavaWeb-HTML初识

02-JavaWeb-CSS初识

03-JavaWeb-JavaScript初识

04-JavaScript基础应用-鼠标悬浮/离开表格格式变化

05-JavaWeb-Tomcat8安装、Servlet初识

06-JavaWeb-Servlet方法/生命周期、HTTP/会话session

07-JavaWeb-视图模板技术Thymeleaf的使用

08-JavaWeb-Servlet保存作用域

09-JavaWeb-阶段性项目1:最简单的后台库存管理系统

10-JavaWeb阶段性项目1:系统的servlet优化1 

11-JavaWeb阶段性项目1:系统的servlet优化2

12-JavaWeb阶段性项目1:系统的servlet优化3

13-JavaWeb阶段性项目1:系统的servlet优化4

资源准备

尚硅谷丨2022版JavaWeb教程视频

教学资源

https://pan.baidu.com/s/1TS7QJ_a2vHHmXkggAs8RMQ

提取码:yyds

servlet优化的过程5

package com.fancy.fruit.controllers;
​
import com.fancy.fruit.dao.FruitDAO;
import com.fancy.fruit.dao.impl.FruitDAOImpl;
import com.fancy.fruit.pojo.Fruit;
import com.fancy.myssm.basedao.myspringmvc.ViewBaseServlet;
import com.fancy.myssm.basedao.util.StringUtil;
​
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
​
​
public class FruitController extends ViewBaseServlet {
​
    private FruitDAO fruitDAO = new FruitDAOImpl();
​
    private String update(Integer fid, String fname, Integer price, Integer fcount, String remark) {
​
        //2.获取参数
​
        //3.执行更新
        fruitDAO.updateFruit(new Fruit(fid, fname, price, fcount, remark));
​
        //4.资源跳转
        //super.processTemplate("index",req,resp);
        //此处需要重定向,目的是重新给IndexServlet发请求,然后覆盖到session中,这样index页面上显示的数据才是最新的
        //resp.sendRedirect("fruit.do");//重定向,重新给fruit.do,给session重新给fruit更改后的数据
        return "redirect:fruit.do";
    }
​
    private String edit(Integer fid, HttpServletRequest req) throws ServletException {
        //HTML是模板,thymeleaf是引擎,我们在servlet中调用了引擎并且给了引擎需要的模板和参数
        if (fid != null) {
            Fruit fruit = fruitDAO.getFruitByFid(fid);
            //获取到fruit对象后将之放置在session作用域
            req.setAttribute("fruit", fruit);
            //thymeleaf的viewBaseServlet中的方法,处理模板数据
            //super.processTemplate("edit",req,resp);
            return "edit";
        }
        return "error";
    }
​
    private String del(Integer fid) {
        if (fid != null) {
            fruitDAO.delFruit(fid);
            return "redirect:fruit.do";
        }
        return "error";
    }
​
    private String add(String fname, Integer price, Integer fcount, String remark) {
​
        Fruit fruit = new Fruit(0, fname, price, fcount, remark);
​
        fruitDAO.addFruit(fruit);
​
        return "redirect:fruit.do";
    }
​
​
    private String index(String oper, String keyword, Integer pageNo, HttpServletRequest request) {
        //添加关键词查询功能
        HttpSession session = request.getSession();
​
        if (pageNo == null) {
            pageNo = 1;
        }
        if (StringUtil.isNotEmpty(oper) && "search".equals(oper)) {
            pageNo = 1;
            if (StringUtil.isEmpty(keyword)) {
                keyword = "";
            }
            session.setAttribute("keyword", keyword);
        } else {
            Object keywordObj = session.getAttribute("keyword");
            if (keywordObj != null) {
                keyword = (String) keywordObj;
            } else {
                keyword = "";
            }
        }
​
        // 重新更新当前页的值
        session.setAttribute("pageNo", pageNo);
​
        FruitDAO fruitDAO = new FruitDAOImpl();
        List<Fruit> fruitList = fruitDAO.getFruitList(keyword, pageNo);
        session.setAttribute("fruitList", fruitList);
​
        //总记录条数
        int fruitCount = fruitDAO.getFruitCount(keyword);
        //总页数
        int pageCount = (fruitCount + 5 - 1) / 5;
        session.setAttribute("pageCount", pageCount);
​
        return "index";
    }
​
}

把获取参数的操作交给中央控制器DispatcherController处理

改DispatcherController的service方法,需使用Java8的反射相关新特性,获取运行时类的对象中的方法中的参数名,操作如下:

JavaWeb阶段性项目1:系统的servlet优化5

Java虚拟机在编译时,附带上的形参名称-parameters

设置好后再删掉,out目录下的编译后.class文件

最终改好的DispatcherController的service方法:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        request.setCharacterEncoding("UTF-8");
        //假设url是:  http://localhost:8080/pro15/hello.do
        //那么servletPath是:    /hello.do
        // 我的思路是:
        // 第1步: /hello.do ->   hello   或者  /fruit.do  -> fruit
        // 第2步: hello -> HelloController 或者 fruit -> FruitController
        String servletPath = request.getServletPath();
        servletPath = servletPath.substring(1);
        int lastDotIndex = servletPath.lastIndexOf(".do") ;
        servletPath = servletPath.substring(0,lastDotIndex);
​
        Object controllerBeanObj = beanMap.get(servletPath);
​
        String operate = request.getParameter("operate");
        if(StringUtil.isEmpty(operate)){
            operate = "index" ;
        }
​
        try {
            Method[] methods = controllerBeanObj.getClass().getDeclaredMethods();
            for(Method method : methods){
                if(operate.equals(method.getName())){
                    //1.统一获取请求参数
​
                    //1-1.获取当前方法的参数,返回参数数组
                    Parameter[] parameters = method.getParameters();
                    //1-2.parameterValues 用来承载参数的值
                    Object[] parameterValues = new Object[parameters.length];
                    for (int i = 0; i < parameters.length; i++) {
                        Parameter parameter = parameters[i];
                        String parameterName = parameter.getName() ;
                        //如果参数名是request,response,session 那么就不是通过请求中获取参数的方式了
                        if("request".equals(parameterName)){
                            parameterValues[i] = request ;
                        }else if("response".equals(parameterName)){
                            parameterValues[i] = response ;
                        }else if("session".equals(parameterName)){
                            parameterValues[i] = request.getSession() ;
                        }else{
                            //从请求中获取参数值
                            String parameterValue = request.getParameter(parameterName);
                            String typeName = parameter.getType().getName();
​
                            Object parameterObj = parameterValue ;
​
                            if(parameterObj!=null) {
                                if ("java.lang.Integer".equals(typeName)) {
                                    parameterObj = Integer.parseInt(parameterValue);
                                }
                            }
​
                            parameterValues[i] = parameterObj ;
                        }
                    }
                    //2.controller组件中的方法调用
                    method.setAccessible(true);
                    Object returnObj = method.invoke(controllerBeanObj,parameterValues);
​
                    //3.视图处理
                    String methodReturnStr = (String)returnObj ;
                    if(methodReturnStr.startsWith("redirect:")){        //比如:  redirect:fruit.do
                        String redirectStr = methodReturnStr.substring("redirect:".length());
                        response.sendRedirect(redirectStr);
                    }else{
                        super.processTemplate(methodReturnStr,request,response);    // 比如:  "edit"
                    }
                }
            }
​
            /*
            }else{
                throw new RuntimeException("operate值非法!");
            }
            */
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

常见错误: IllegalArgumentException: argument type mismatch

点击下一页时出的问题

因为URL= localhost:8080/pro16/fruit.do?pageNo=1 下一页时

因为URL= localhost:8080/pro16/fruit.do?pageNo=2

pageNo获取为2时,parameterValues中存储的是字符串“2”而不是integer的2

所以,需要增加一个判断再赋给parameterObj,才能添加到承载最终参数值数组的parameterValues中

运行

JavaWeb阶段性项目1:系统的servlet优化5

JavaWeb阶段性项目1:系统的servlet优化5

JavaWeb阶段性项目1:系统的servlet优化5

报错原因:request和req的问题,以后项目注意参数名称统一。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/280403.html

(0)
上一篇 2022年8月14日
下一篇 2022年8月14日

相关推荐

发表回复

登录后才能评论