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; %>

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

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

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

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

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
this is page 3 begin...<br/>
<jsp:include page="page1.jsp"/>
this is page 3 end...<br/>
<%=kk%> 编译失败,HTTP Status 500 - Unable to compile class for JSP

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

重定向和请求转发

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

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

重定向:

response.sendRedirect("show.do");

区别【重点】

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

典型应用

用户登录login.jsp

<form action="login.do" method="post">
<input name="username"/>
<input name="password" type="password"/>
<input type="submit" value="登录系统"/>
</form>

在地址为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,以保证后续代码不执行
}
... ...
}
}

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

<%
Object obj=request.getAttribute("errors");
if(obj!=null && obj instanceof Map){
Map<String,String> map=(Map<String,String>)obj;
if(map.containsKey("username")){ //判断保存报错信息的Map种是否有username对应
的报错信息
out.println(map.get("username"))
}
}
%>
如果用户输入的正确信息,则不应该要求用户重新输入,所以需要从request种获取上次提交的数据---
数据回填操作
<input name="username" value='<%=request.getParameter("username")%>'/>

跟踪用户的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)

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

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

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");
}

应用场景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);
}

在需要判断用户是否登录的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);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值