• Servlet详解/异常处理/跟踪用户的4种方法


    异常处理

    web页面之间的3种关系

    web页面之间的关系有3种:包含、重定向和请求转发

    包含

    包含就是在一个页面的生成结果中包含另外一个页面。包含可以有静态包含和动态包含两种

    • 静态包含就是将被包含页的源代码先复制到包含页中,再编译执行
      page1.jsp被包含页
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    this is page one!<br/>
    <% int kk=100; %>
    
    • 1
    • 2
    • 3

    page2.jsp包含页,在page2中包含page1的内容

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    this is page two begin...
    <%@ include file="page1.jsp"%> 静态包含,先包含后编译执行 this is page two end...
    <%=kk%> 如果没有包含page1则kk变量没有定义,语法错误
    • 1
    • 2
    • 3
    • 4
    • 5
    • 动态包含就是包含被包含页面的执行结果,并不包含源代码。两个页面实际上是各自独立运行的

    上面的编码方式则不可用,因为page2中的 kk没有定义而直接使用,语法错误
    page1.jsp被包含页

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>this is page one!<br/>
    <% int kk=100; %>
    
    • 1
    • 2

    page2.jsp包含页,在page2中包含page1的独立执行结果,就是包含生成的html文档

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    this is page 3 begin...
    this is page 3 end...
    <%=kk%> 编译失败,HTTP Status 500 - Unable to compile class for JSP
    • 1
    • 2
    • 3
    • 4
    • 5

    在servlet中编程实现动态包含
    //动态包含page1.jsp页面
    request.getRequestDispatcher("page1.jsp").include(request,response);
    包含方法中传递了request和response对象,所以当前Servlet和被包含的页面共享request和response对象

    重定向和请求转发

    效果类似,可以从一个页面跳转到另外一个页面
    请求转发就是将请求的处理委托给另外一个页面进行处理;重定向就是重新向另外一个页面发起请求
    请求转发:

    request.getRequestDispatcher("page1.jsp").forward(request,response);
    
    • 1

    重定向:

    response.sendRedirect("show.do");
    
    • 1

    区别【重点】

    • 是否共享request,请求转发共享,重定向不共享
    • 客户端是否参与。请求转发客户端不参与,浏览器中的地址不会发生变化;重定向客户端参与,浏览器中的地址自动变化为新地址
    • 允许跳转的目标地址
      选用
    • 如果请求转发和重定向都可以的时候,优先使用请求转发,因为效率
    • 如果需要使用request传递共享数据,则需要使用请求转发,否则使用重定向

    典型应用

    用户登录login.jsp

    • 1
    • 2
    • 3
    • 4
    • 5

    在地址为login.do的servlet中接收数据

    public class LoginServlet extends HttpServlet {
    public void doPost(HttpServletRequest request,HttpServletResponse
    response)throws ServletException,IOException {
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    //需要对用户提交的数据进行验证
    Map<String,String> errs=new HashMap<>();
    if(username==null || username.trim().length()<6){ //要求用户名称必须填
    写,并且长度不能少于6个字符
    errs.put("username","用户名称不合法!");
    }
    if(password==null || password.trim().length()<6){
    errs.put("password","用户口令不合法!");
    }
    //如果有报错信息则需要返回到输入页面中进行报错显示。报错信息可以使用request的
    attribute进行传递,同时使用请求转发保证实现页面的数据回填操作
    if(errs.size()>0){
    request.setAttribute("errors",errs);
    request.getRequestDispatcher("login.jsp").forward(request,response);
    return; //如果提前执行页面跳转,则必须紧邻return,以保证后续代码不执行
    }
    ... ...
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    修改login.jsp页面实现报错信息显示和数据回填操作

    <%
    Object obj=request.getAttribute("errors");
    if(obj!=null && obj instanceof Map){
    Map map=(Map)obj;
    if(map.containsKey("username")){ //判断保存报错信息的Map种是否有username对应
    的报错信息
    out.println(map.get("username"))
    }
    }
    %>
    如果用户输入的正确信息,则不应该要求用户重新输入,所以需要从request种获取上次提交的数据---
    数据回填操作
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    跟踪用户的4种方法

    • 隐藏域
    • URL重写
    • 客户端跟踪用户:Cookie
    • 服务器端跟踪用户:session

    会话对象

    session对应类型为HttpSession,用于实现服务器端跟踪用户。一般针对一个浏览器窗口,服务器会提供一个session对象,不管在这个浏览器窗口中以何种方式访问当前应用中的多少的页面,这些页面都共享同一个session对象
    获取session对象

    HttpSession session=request.getSession(true); //Boolean类型的参数,如果值为
    true,则表示有当前窗口对应的session对象,则获取并重用;如果没有则新建。值为false则有则重
    用,没有返回为null,不会自动新建
    HttpSession session=request.getSession(); //等价于getSession(true)
    
    • 1
    • 2
    • 3
    • 4

    操作数据
    setAttribute(“名称”,存放的值Object) 存储或者修改session中存储的数据
    getAttribute(“名称”):Object 获取存储在session中指定名称对应的数据
    removeAttribute(“名称”) 删除指定名称对应的数据
    getAttibuteNames():Enumeration
    具体应用
    应用场景1:跨多个页面传递数据
    PicServlet负责生成图片

    String checkcode=this.generateCheckcode(6); //生成验证码
    HttpSession session=request.getSession();
    session.setAttribute("checkcode",checkcode);//在session中存储了验证码
    
    • 1
    • 2
    • 3

    LoginServlet中接收客户端输入的验证码,并和session中存储的验证码进行比对,以判断用户输入的验证码是否正确

    String checkcode=request.getParameter("checkcode");
    HttpSession session= request.getSession();
    if(checkcode==null || checkcode.trim().length()<1)
    errs.put("checkcode","必须输入校验码!");
    else{
    //如何判断验证码输入正确?要求PicServlet能够以某种方式将动态成成的验证码传递到
    LoginServlet
    Object obj=session.getAttribute("checkcode");
    if(obj!=null && !checkcode.endsWith(obj.toString()))
    errs.put("checkcode","验证码输入错误!");
    session.removeAttribute("checkcode");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    应用场景2:使用session标识当前用户状态,并跨页面数据传输

    boolean bb= userDao.login(user);
    if(bb){
    session.setAttribute("loginInfo",user); //用于标识当前窗口的用户已经登录成功
    //登录成功后,则没有必要继续向下传递login.jsp页面提交的用户名称和口令,所以考虑使用重
    定向
    response.sendRedirect("show.do");
    }else {
    //因为登录失败后返回原始的输入页面login.jsp,需要对用户输入的数据进行回填处理,供用户
    修改再次登录
    request.setAttribute("msg","登录失败!请重新登录");
    request.getRequestDispatcher("login.jsp").forward(request,response);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在需要判断用户是否登录的servlet中首先判断用户的登录状态

    public class ShowServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse
    response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    Object obj = session.getAttribute("loginInfo");
    if (obj == null) {
    session.setAttribute("msg","请登录后使用本系统");
    response.sendRedirect("login.do");
    } else {
    request.getRequestDispatcher("show.jsp").forward(request,
    response);
    }
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    兼容SringBoot 3.X版本的 API工具(Springdoc)
    docker——入门介绍、组件介绍、安装与启动、镜像相关命令、容器相关命令、应用部署
    java计算机毕业设计教评系统源码+mysql数据库+系统+lw文档+部署
    SpringCloud学习(二)——Eureka注册
    Python中的模块
    AI为药物开发助力两篇文章介绍
    2 寄存器
    基础算法 - 求子矩阵的和
    【查找、排序~python】
    C++中的外观模式
  • 原文地址:https://blog.csdn.net/qq_51222096/article/details/128086694