一、请求转发和重定向:
1.请求转发:
请求转发的介绍:
(1)请求转发解决的问题:
服务器在接收到浏览器的请求后,仅仅使用一个Servlet 进行请求处理,会造成不同的 Servlet 逻辑代码冗余,Servlet 的职责不明确。
请求转发的作用:
(1)作用:
解决了一次请求内的不同 Servlet 的数据(请求数据+其他数
据)共享问题。
(2)作用域:
基于请求转发,一次请求中的所有 Servlet 共享。
特点:
(1)由服务器创建;
(2) 每次请求都会创建;
(3)生命周期一次请求;
常用方法:
(1)存储数据:request.setAttribute(String name,String value);
(2)获取数据:request.getAttribute(Object obj);
(3)转发路径:request.getRequestDispathcher(“转发路径”).forward(request,response);
总结
代码示例:
package com.zlw.servlet2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Login2 extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取request对象中请求转发流转数据
// String str = (String)request.getAttribute("str");
String str = ((request.getAttribute("str"))==null?"":(String)request.getAttribute("str"));
//响应处理结果
PrintWriter out = response.getWriter();
out.print("");
out.print("
用户登录");
out.print("
");
out.print("
");
out.print(""+str+"");
out.print("
");out.print("用户名:
");out.print("密码:
");out.print("");
out.print("
");
out.print(" ");
out.print("");
}
}
package com.zlw.servlet2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ToLogin extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String name = request.getParameter("username");
String pwd = request.getParameter("pwd");
if("李四".equals(name)&&"1234".equals(pwd)){
response.getWriter().write("登录成功!");
}else{
// response.getWriter().write("用户名或密码错误!");
//将数据存储到request对象中
request.setAttribute("str", "用户名或密码错误!");
//请求转发
request.getRequestDispatcher("login2").forward(request, response);
return;
}
}
}
正确的用户名和密码
登录成功
错误的用户名和密码
跳转的请求
2.重定向:
重定向解决 的问题:
如果当前的请求,Servlet 无法进行处理;
如果使用请求转发,造成表单数据重复提交;
特点:
(1)两次请求;
(2)浏览器地址栏信息改变 ;
(3)避免表单重复提交 ;
使用方法:
response.sendRedirect(“路径”);
代码示例:
package com.zlw.servlet2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Login2 extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取request对象中请求转发流转数据
// String str = (String)request.getAttribute("str");
String str = ((request.getAttribute("str"))==null?"":(String)request.getAttribute("str"));
//响应处理结果
PrintWriter out = response.getWriter();
out.print("");
out.print("
用户登录");
out.print("
");
out.print("
");
out.print(""+str+"");
out.print("
");out.print("用户名:
");out.print("密码:
");out.print("");
out.print("
");
out.print(" ");
out.print("");
}
}
package com.zlw.servlet2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ToLogin extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String name = request.getParameter("username");
String pwd = request.getParameter("pwd");
if("李四".equals(name)&&"1234".equals(pwd)){
response.getWriter().write("登录成功!");
}else{
// response.getWriter().write("用户名或密码错误!");
//将数据存储到request对象中
request.setAttribute("str", "用户名或密码错误!");
//重定向
response.sendRedirect("login2");
return;
}
}
}
3.转发请求和重定向的区别:
两者的异同
二、Cookie的实现:
1.为什么需要cookie?
不同的请求使用相同的请求数据,但是请求只要结束数据就被销毁了,其他请求需要将公共数据重新书写发送。
2.cookie的特点:
(1)如果不设置有效期则默认存储在浏览器的内存里,浏览器关闭即失效;
(2)如果设置了有效期,则存储到客户端的硬盘里,到期后自动销毁;
(3)如果不设置有效路径则任意项目路径的请求都会附带存储的cookie信息;
(4)如果设置了有效路径只有在该路径下的请求才会附带设置的cookie信息。
3.总结:
总结
4.代码示例:
Login类(登录界面):
package com.zlw.cookie3;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Login extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应编码格式
response.setContentType("text/html;charset=utf-8");
//获取输入流
PrintWriter out = response.getWriter();
//获取cookie信息
Cookie[] cs = request.getCookies();
String userName="";
String userPass="";
//遍历cookie
if (cs!=null&&cs.length>0) {
for (Cookie cookie : cs) {
String name=cookie.getName();
if ("userName".equals(name)) {
userName = cookie.getValue();//获取cookie中用户名信息
}else if("userPass".equals(name)){
userPass = cookie.getValue();//获取cookie中密码信息
}
}
}
out.print("");
out.print("
用户登录");
out.print("
");
out.print("
");
out.print("用户名:
");out.print("密码:
");out.print("
");out.print("
");
out.print("");
out.print("");
}
}
DoLogin类:
package com.zlw.cookie3;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DoLogin extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out= response.getWriter();
//获取输入的用户名和密码
String userName = request.getParameter("userName");
String userPass = request.getParameter("userPass");
//如果用户名和密码都是admin,则显示“登录成功”,否则显示“用户名或密码有误!”
if("admin".equals(userName)&&"admin".equals(userPass)){
//将用户名和密码的信息保存到Cookie中
Cookie c1= new Cookie("userName", userName);//创建Cookie对象,用于保存数据
c1.setMaxAge(3600*24*3);//设置有效期为3天
response.addCookie(c1);
Cookie c2=new Cookie("userPass",userPass);
c2.setMaxAge(3600*24*3);//设置有效期为3天
response.addCookie(c2);
response.sendRedirect("index");
// request.getRequestDispatcher("index").forward(request, response);
}else{
out.print("用户名或密码有误!");
}
}
}
Index类:
package com.zlw.cookie3;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Index extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从Cookie中获取用户名信息
Cookie[] cs= request.getCookies();//获取Cookie信息
String userName="";
for (Cookie cookie : cs) {
String name = cookie.getName();//获取cookie的名称
if ("userName".equals(name)) {
userName = cookie.getValue();//获取cookie的值
}
}
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("");
out.print("
主页");
out.print("
");
out.print("
"+userName+",登录成功!
");
out.print("");
out.print("");
}
}
第一次登录
结果
三天内打开这个请求
三、Session:
1.解决的问题:
Request 对象解决了一次请求内的不同 Servlet 的数据共享问
题,一个用户的不同请求的处理需要使用相同的数据。
2.原理:
用户使用浏览器第一次向服务器发送请求,服务器在接受到请
求后,调用对应的 Servlet 进行处理。在处理过程中会给用户创建一个 session 对象,用来存储用户请求处理相关的公共数据,并将此 session 对象的 JSESSIONID 以 Cookie 的形式存储在浏览器中(临时存储,浏览器关闭即失效)。用户在发起第二次请求及后续请求时,请求信息中会附带 JSESSIONID,服务器在接收到请求后,调用对应的 Servlet 进行请求处理,同时根据 JSESSIONID 返回其对应的 session 对象。
3.特点:
(1)由服务器进行创建;
(2)每个用户独立拥有一个session;
(3)默认存储时间为30分钟;
4.session使用流程:
(1)浏览器发起请求到Aservlet,在AServlet中使用req.getSession()获取Session对象,如果此次请求中没有SessionID则创建一个新的Session对象,如果有SessionID则将其对应的Session对象返回(前提是该session对象没有到期),如果session对象到期销毁了,就算有sessionID也会重新创建一个Session。
(2)校验session是否失效,存储数据到session对象中或者获取session中的数据或者删除session中的数据。
5.session的作用域:
浏览器不关闭,session不失效,则同一用户的任意请求获取的都是同一个session;一次会话。
6.session的有效期设置和强制销毁:
设置有效期:
(1)session默认有效时间为30分钟。
(2)可以在tomcat下的web.xml中进行配置注意:此种配置方式是所有的tomcat下的项目默认为30分钟。
(3)也可以在代码中使用session.setMaxInactiveInterval(int seconds);设置session的有效时间,参数为整数类型的秒。
强制销毁:
使用session.invalidate()方法强制销毁session。
7.代码示例:
package com.zlw.servlet;
import java.io.IOException;
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;
/**
* session学习:
* 问题:
* 用户不同的请求在处理的时候需要使用其他请求中的数据该怎么办?
* 解决:
* session技术
* 使用:
* 创建session对象
* HttpSession session =req.getSession();
* 存储数据到session中
* session.setAttribute(String name, Object value);
* 获取session对象
* HttpSession session =req.getSession();
* 获取session中的数据
* session.getAttribute(String uname);注意:返回的object类型,需要强制转换
* 删除session中的数据
* session.removeAttribute(String uname);注意:如果有数据则删除,没有则什么都不做。
* 流程:
* 1、 浏览器发起请求到Aservlet,在AServlet中使用req.getSession()获取Session对象,如果此次请求中没有
* SessionID则创建一个新的Session对象,如果有SessionID则将其对应的Session对象返回(前提是该session对象没有到期),如果session
* 对象到期销毁了,就算有sessionID也会重新创建一个Session。
* 2、 校验session是否失效,存储数据到session对象中或者获取session中的数据或者删除session中的数据
* 特点:
* session解决了同一个用户不同请求 的数据共享问题。
* session的作用域:浏览器不关闭,session不失效,则同一用户的任意请求获取的都是同一个session
* 一次会话
* session的设置:
* session默认有效时间为30分钟,可以在tomcat下的web.xml中进行配置
* 注意:此种配置方式是所有的tomcat下的项目默认为30分钟
* 也可以在代码中使用
* session.setMaxInactiveInterval(int seconds);//设置session的有效时间,参数为整数类型的秒
* session.invalidate();//强制销毁session
* @author zhang
*
*/
//@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname =req.getParameter("uname");
//处理请求数据
System.out.println("ServletA.service:"+uname);
//创建session对象
HttpSession session= req.getSession();
//存储数据到session对象中
session.setAttribute("uname", uname);
System.out.println("ServletA.service:"+session.getId());
//响应处理结果
//重定向
resp.sendRedirect("servletB");
}
}
package com.zlw.servlet;
import java.io.IOException;
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;
//@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//获取Session对象
HttpSession session = req.getSession();
//获取A的处理结果数据
String uname = (String)session.getAttribute("uname");
//处理请求数据
//打印A流转的数据
System.out.println("ServletB.service:"+uname);
//响应结果的处理
//重定向
}
}
状态栏
结果
状态栏
结果
四、优化登录案例:
LoginServlet:
package com.zlw.login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应格式
resp.setContentType("text/html;charset=utf-8");
//获取Session中的数据
HttpSession session= req.getSession();
String str = (session.getAttribute("flag")==null?"":"用户名或密码错误!");
//销毁session
session.invalidate();
//获取请求信息
//处理请求信息
//响应处理结果
//直接响应
resp.getWriter().write("");
resp.getWriter().write("
");
resp.getWriter().write("");
resp.getWriter().write("
");
resp.getWriter().write("
");
resp.getWriter().write(""+str+"");
resp.getWriter().write(" 用户名:
");resp.getWriter().write(" 密码:
");resp.getWriter().write("
");resp.getWriter().write("
");
resp.getWriter().write("");
resp.getWriter().write("");
}
}
UserServlet:
package com.zlw.login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname=req.getParameter("uname");
String pwd = req.getParameter("pwd");
//处理请求信息
//校验用户信息
if ("张三".equals(uname)&&"123".equals(pwd)) {
//登录成功
//处理响应结果
}else{
//登录失败
//创建session并增加登录失败标记
HttpSession session = req.getSession();
session.setAttribute("flag", "loginFalse");
//相应处理结果(重定向到登录页面)
resp.sendRedirect("login");
}
}
}
结果:
用户名和密码错误
结果
错误页面刷新之后