会话管理
一、RequestDispatcher接口
1、请求转发和请求重定向的区别
ServletRequest:是一个域对象。内部维护了一个Map<String,Object>
Object getAttribute(String name):
void setAttribute(String name,Object obj):
void removeAttribute(String name):
重定向:客户端行为
HttpServletResponse.setState(302);
HttpServletResponse.setHeader("Location",String url);
或者
HttpServletResponse.sendRedirect(String url);等同以上2句代码
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 重定向演示
public class ServletDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("demo", "text");
// 返回特征码,进行重定向
// response.setStatus(302);
// response.setHeader("Location", "/review_day06/servlet/ServletDemo2");
response.sendRedirect("/review_day06/servlet/ServletDemo2");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = (String) request.getAttribute("demo");
if (value != null)
response.getOutputStream().write(value.getBytes());
else
response.getOutputStream().write("value is null.<br/>".getBytes());
response.getOutputStream().write("This is Demo2".getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}结果:
value is null. This is Demo2
客户端发送了两次请求,且两次请求并不是同一个,故:
源组件和目标组件中的request并不是同一个,所以不能实现数据的共享。
转发:服务器行为
方式一:
RequestDispatcher rd = ServletContext.getRequestDispatcher(String path):必须以"/"开头。path只能使用绝对路径
方式二:
RequestDispatcher rd = request.getRequestDispatcher(String path):如果以"/"开头,表示使用绝对路径;不以"/"开头,表示相对路径。
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//转发演示
public class ServletDemo3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("demo", "text");
//RequestDispatcher rd = request.getRequestDispatcher("/servlet/ServletDemo4");
//此处使用"/review_day06/servlet/ServletDemo4"报错;使用ServletDemo4不报错;/servlet/ServletDemo4不报错
RequestDispatcher rd = getServletContext().getRequestDispatcher("/servlet/ServletDemo4");
//此处使用"/review_day06/servlet/ServletDemo4"报错;使用ServletDemo4也报错
rd.forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = (String) request.getAttribute("demo");
response.getOutputStream().write((value+"<br/>").getBytes());
response.getOutputStream().write("This is demo4".getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}结果:
text This is demo4
转发时,客户端只发送了一次请求,源组件和目标组件中的request是同一个,可以实现数据共享。
**扩展知识点:各种URL地址的写法。
相对路径:实际开发中不建议使用。
绝对路径:建议使用方式。
绝对路径的写法:
如果是给服务器用的地址:"/"代表当前应用 /day06
如果是给客户端用的地址:"/"并不代表当前应用,只是区分相对路径用的。需要加上/day06
sendRedirect(String url): url要加 /day06
href: 要加 /day06
form-->action:要加 /day06
请求转发:不要加 /day06
2、包含
源组件包含目标组件:共享请求和响应对象的数据。
目标组件的输出都会出现在源组件中。
目标组件设置的所有响应码头无效。
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//include演示
//源组件
public class ServletDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("这是demo5<br/>");
RequestDispatcher rd = request.getRequestDispatcher("/servlet/ServletDemo6");
rd.include(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//目标组件
public class ServletDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("这是demo6");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
结果:
这是demo5 这是demo6
二、会话技术概述
1、什么是会话?如同打电话
2、会话过程中主要解决的问题是保存用户的数据
3、开发技术:
a、cookie技术:客户端技术
响应消息:Set-Cookie:
请求消息:Cookie:
b、session技术:服务器端技术
三、Cookie概述:API
1、Cookie是Servlet向客户端写的小数据信息。这些信息被浏览器保存在自己的缓存目录中。再次请求服务器资源时能带过去。
2、Cookie的属性:
name:必须要的属性。
value:必须要的属性。
------------------------------------------------
以下属性可选:
comment:
path:生成cookie的资源路径。区分重名cookie的。
http://localhost:8080/day06/servlet/ServletDemo1
path:/day06/servlet
带Cookie问题:
localost/day06/servlet : lastAccessTime Cookie
访问路径:http://www.baidu.com/index.jsp 不会带,域名不同
访问路径:http://localhost:8080/day06 会带
访问路径:http://localhost:8080/day06/servlet/a/b/ServletDemo2 不会
如果把cookie的path设置为了当前应用:“/day06”,意味着访问day06下面的任何资源,浏览器都会带cookie过来。
domain:域。默认是生成Cookie的域名。
maximum age:设置Cookie的最大存活时间。默认值最大存活时间是浏览器进程(会话范围)。如果值0,代表要删除该cookie,注意domain/path
version:
每个浏览器客户端最多能放300个cookie。对每一个网站做多能放20个cookie;每一个cookie的大小不能超过4KB。
域名+路径+name(domain+path+name):唯一确定一个Cookie
3、如何向客户端写Cookie:HttpServletResponse.addCookie(Cookie c)(原理:response.setHeader("Set-Cookie","name=value");
4、服务器如何获取客户端带来的Cookie。HttpServletRequest.getCookies()(原理:request.getHeader("Cookie"));
四、Cookie案例:
1、记录最后一次的访问时间:帮助大家理解Cookie原理的。
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* 显示用户上次的访问时间
* name = value-->lastAccessTime = ;
*
* 思路:
* 1.需要获取cookie,从cookie中取出最后的访问时间返回给客户端;
* 2.将新的访问时间写回给cookie
*
*/
public class CookieDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("上次访问的时间是:");
//从cookie中取出最后的访问时间返回给客户端;
//1.获取所有的Cookie
Cookie[] cookies = request.getCookies();
//2.从中取出值为lastAccessTime的Cookie
for(int i=0;cookies!=null&&i<cookies.length;i++){
if("lastAccessTime".equals(cookies[i].getName())){
long time = Long.parseLong(cookies[i].getValue());//得到上次访问的时间
Date d = new Date(time);
DateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
//将获得的时间响应给浏览器
out.write(df.format(d));
}
}
//3.将本次访问的时间写回给cookie
Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
cookie.setMaxAge(24*60*60);//cookie保存时间
cookie.setPath(request.getContextPath());//request.getContextPath()等同于/review_day06
response.addCookie(cookie);
//4.删除cookie
out.write("<a href='"+request.getContextPath()+"/servlet/CookieDemo2'>清除</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//清除cookie
public class CookieDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie cookie = new Cookie("lastAccessTime", "");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}结果:
2、记住登陆用户名
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;
//功能:1.提供登录的UI界面;2.显示已保存的用户名
public class LoginUIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username="";
String checked = "";
//显示已保存的用户名
Cookie cookies[] = request.getCookies();
for(int i=0;cookies!=null&&i<cookies.length;i++){
if("userInfo".equals(cookies[i].getName())){
username = cookies[i].getValue();
checked="checked='checked'";
break;
}
}
//提供登陆的界面
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("<form action='"+request.getContextPath()+"/servlet/LoginServlet' method='post'>");
out.write("用户名:<input type='text' name='username' value='"+username+"'/><br/>");
out.write("密码:<input type='password' name='password'/><br/>");
out.write("<input type='checkbox' name='remember' "+checked+"/>记住用户名<br/>");
out.write("<input type='submit' value='登陆'/><br/>");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}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 LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
String password = request.getParameter("password");
String remember = request.getParameter("remember");
//验证用户、密码暂略
out.write("欢迎您:"+username);
//
if(remember==null){
//当不选中 记住用户名 时,删除cookie
Cookie cookie = new Cookie("userInfo", "");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
}else{
//当选中 记住用户名 时,则保存cookie
Cookie cookie = new Cookie("userInfo", username);
cookie.setPath(request.getContextPath());
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}结果:
3、购物网站:记住最近的浏览产品记录
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 功能:1.列出所有的商品列表;2.列出用户近期的浏览记录;3.提供购买链接
// cookis以bookHistory命名
public class ShowAllBooksServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示左右的书,并提供购买链接
out.write("<a>本站有以下商品:</a><hr/>");
Map<String, Book> books = BookDB.findAllBooks();
for (Map.Entry<String, Book> me : books.entrySet()) {
out.write(me.getValue().getName()
+ "  <a target='_blank' href='"
+ request.getContextPath()
+ "/servlet/ShowDetailsServlet?id=" + me.getKey()
+ "'>查看</a><hr/>");
}
out.write("最近查看的商品如下<hr/>");
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("bookHistory".equals(cookies[i].getName())) {
String value = cookies[i].getValue();
String ids[] = value.split("\\-");
for (String id : ids) {
Book book = BookDB.findBookById(id);
out.write(book.getName() + "<br/>");
}
break;
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;
// 1.显示书籍的详细内容;2.写cookie
public class ShowDetailsServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示详细信息
out.write("本书的详细信息为: <br/>");
String id = request.getParameter("id");
Book book = BookDB.findBookById(id);
out.write(book.toString());
// 写cookie
String ids = makeIds(request, id);
Cookie cookie = new Cookie("bookHistory", ids);
cookie.setPath(request.getContextPath());
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
}
/*
* 1.没有cookie
* 2.有cookie,但是没有名为bookHistory的cookie
* 3.有名为bookHistory的cookie
* 原 新 组织后
* 1 2 2-1
* 1-2 2 2-1
* 1-2 3 3-1-2
*
* 1-2-3 4 4-1-2
* 1-2-3 2 2-1-3
*/
private String makeIds(HttpServletRequest request, String id) {
Cookie[] cookies = request.getCookies();
// 没有cookie
if (cookies == null) {
return id;
}
boolean hasBookHistory = false;
String value = "";
for (Cookie cookie : cookies) {
if ("bookHistory".equals(cookie.getName())) {// 这里必须使用cookie.getName(),而不是cookie
hasBookHistory = true;
value = cookie.getValue();
}
}
if (!hasBookHistory) {
return id;
}
String[] vs = value.split("\\-");
LinkedList<String> list = new LinkedList<String>(Arrays.asList(vs));//需要将vs传入
if (list.size() < 3) {
if (list.contains(id)) {
list.remove(id);
list.addFirst(id);
} else {
list.addFirst(id);
}
} else {
if (list.contains(id)) {
list.remove(id);
list.addFirst(id);
} else {
list.removeLast();
list.addFirst(id);
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
if (i > 0)
sb.append("-");
sb.append(list.get(i));// 不是sb.append(id);
}
return sb.toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.util.HashMap;
import java.util.Map;
public class BookDB {
private static Map<String,Book> books = new HashMap<String,Book> ();
static{
books.put("1", new Book("1", "葵花宝典", "HMM", 5.00f, "欲练此功,必须练好基本功"));
books.put("2", new Book("2", "辟邪剑法", "WDD", 4.00f, "欲练此功,必须练好基本功"));
books.put("3", new Book("3", "JPM", "DJR", 15.00f, "古代爱情小说"));
books.put("4", new Book("4", "Java面向对象编程", "WZT", 85.00f, "Java入门经典书籍"));
books.put("5", new Book("5", "红高粱", "CYY", 7500000.00f, "买套房"));
}
public static Map<String, Book> findAllBooks(){
return books;
}
public static Book findBookById(String id){
return books.get(id);
}
}
public class Book {
private String id;
private String name;
private String author;
private float price;
private String description;
public Book() {}
public Book(String id, String name, String author, float price,
String description) {
super();
this.id = id;
this.name = name;
this.author = author;
this.price = price;
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", author=" + author
+ ", price=" + price + ", description=" + description + "]";
}
}
效果:
五、HttpSession概述
每个客户端都有自己对应的HttpSession对象,该对象存放在服务器的内存中。
得到HttpSession对象:
HttpServletRequest.getSession():
先根据你传递的JSESSIONID的值,在内存找id为此值的session对象。名称为JSESSIONID的Cookie如果不存在,或者找不到对应session对象,会新建一个HttpSession对象。
HttpServletReqeust.getSession(boolean b):
如果为true:效果等同没有参数的getSession()
如果为false:只会查找。
HttpSession.getId()
HttpSession实际上借助了Cookie技术,知不是过是写了一个特殊名称的cookie而已。
此Cookie的path是当前应用,age是会话范围。name是JSESSIONID,value是session对象的id。
六、HttpSession的原理
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 1.显示所有的商品;2.提供购买链接;
public class ShowProductsServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示所有商品
out.write("本站有以下商品:<br/>");
Map<String, Book> books = BookDB.findAllBooks();
for (Map.Entry<String, Book> me : books.entrySet()) {
out.write(me.getValue().getName() + "<a href='"
+ request.getContextPath() + "/servlet/BuyServlet?id="
+ me.getKey() + "'>购买</a><hr/>");// 别忘了传入me.getKey(),否则找不到商品
}
out.write("<a href='" + request.getContextPath()
+ "/servlet/ShowCartServlet'>查看购物车</a><br/>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
// 提供购买功能
public class BuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String id = request.getParameter("id");// 获取到要购买商品的id
Book book = BookDB.findBookById(id);// 找到要买的商品
// 获得session,如果没有,则创建
HttpSession session = request.getSession();
Object obj = session.getAttribute("cart");// 获取购物车
// 如果没有购物车,则创建一个容器来盛放要买的商品,并将数据传给购物车
if (obj == null) {
List<Book> cart = new ArrayList<Book>();
cart.add(book);
session.setAttribute("cart", cart);
} else {
List<Book> cart = (List<Book>) obj;
cart.add(book);// 这里不是setAttribute,因为已有Attribute,所以只需添加元素
}
out.write("商品已成功放入购物车!<a href='" + request.getContextPath()
+ "/servlet/ShowProductsServlet'>继续购物</a><br/>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
// 1.显示已加入购物车的商品
public class ShowCartServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(false);// 只查看,不创建
if (session == null) {
out.write("还没有购买任何物品!");
return;
}
List<Book> cart = (List<Book>) session.getAttribute("cart");
if (cart == null) {
out.write("还没有购买任何物品!");
return;
}
System.out.println(cart);
out.write("您已经购买了如下商品:<hr/>");
for (Book book : cart) {
out.write(book.getName() + "<br/>");
}
out.write("<a href='#'>去结算</a> <a href='"
+ request.getContextPath()
+ "/servlet/ShowProductsServlet'>继续购物</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
效果图:
2、实现用户一次登陆和验证码验证
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;
import javax.servlet.http.HttpSession;
/*
* 需要一个主页(IndexServlet)
* 1.如果已登录,则显示欢迎信息和注销链接
* 需要获取session,从session中获取username,显示在欢迎信息中;
* 2.如果未登录,则显示登录链接
*/
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("这是主页<hr/>");
// 获取session
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
String username = null;
if (user != null) {
username = user.getUsername();
}
if (username != null) {
out.write("欢迎您," + username + "<br/>");
out.write("<a href='" + request.getContextPath()
+ "/servlet/LogoutServlet'>注销</a>");
} else {
out.write("欢迎光临本站,如果想要浏览更多信息<br/>请<a href='"
+ request.getContextPath()
+ "/servlet/LoginUIServlet'>登录</a><br/>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
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;
import javax.servlet.http.HttpSession;
/*
* 需要一个主页(IndexServlet)
* 1.如果已登录,则显示欢迎信息和注销链接
* 需要获取session,从session中获取username,显示在欢迎信息中;
* 2.如果未登录,则显示登录链接
*/
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("这是主页<hr/>");
// 获取session
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
String username = null;
if (user != null) {
username = user.getUsername();
}
if (username != null) {
out.write("欢迎您," + username + "<br/>");
out.write("<a href='" + request.getContextPath()
+ "/servlet/LogoutServlet'>注销</a>");
} else {
out.write("欢迎光临本站,如果想要浏览更多信息<br/>请<a href='"
+ request.getContextPath()
+ "/servlet/LoginUIServlet'>登录</a><br/>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
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;
import javax.servlet.http.HttpSession;
/*
* 需要一个登录后台处理Servlet(LoginServlet)
* 1.获取session,获取username、password、code的值,如果三者都匹配,则登录成功,跳转到主页;
* 2.如果有一项不匹配,则输出错误信息;
* 3.检测checkbox,如果checked=checked,则写cookie,否则,删除cookie
*/
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
String password = request.getParameter("password");
String code = request.getParameter("code");
String remember = request.getParameter("remember");
HttpSession session = request.getSession();
String value = (String) session.getAttribute("code");
// 判断验证码
if (!code.equals(value)) {
out.write("验证码输入错误!<br/>");
out.write("<a href='" + request.getContextPath()
+ "/servlet/LoginUIServlet'>重新登录</a>");
return;
}
// 根据username、password查找数据库中的用户
User user = UserDB.findUser(username, password);
if (user == null) {
out.write("用户名或密码输入错误!<br/>");
out.write("<a href='" + request.getContextPath()
+ "/servlet/LoginUIServlet'>重新登录</a>");
return;
} else {
Cookie cookie = new Cookie("userInfo", username);
if (remember == null) {
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
}else{
cookie.setPath(request.getContextPath());
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
}
session = request.getSession();
session.setAttribute("user", user);
out.write("登录成功!2秒后返回主页,如果长时间没有反应,请点击<a href='"
+ request.getContextPath()
+ "/servlet/IndexServlet'>这里</a>");
response.setHeader("Refresh", "2;URL=" + request.getContextPath()
+ "/servlet/IndexServlet");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
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 ImageServlet extends HttpServlet {
private static int WIDTH = 120;
private static int HEIGHT = 25;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//验证码图片不缓存
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
// 获取画布
BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_RGB);
// 获取画笔
Graphics g = image.getGraphics();
// 画边框
g.setColor(Color.GRAY);
g.drawRect(0, 0, WIDTH, HEIGHT);
// 填充背景色
g.setColor(Color.YELLOW);
g.fillRect(1, 1, WIDTH - 2, HEIGHT - 2);
// 画干扰线
g.setColor(Color.RED);
Random r = new Random();
for (int i = 0; i < 9; i++) {
g.drawLine(r.nextInt(WIDTH), r.nextInt(HEIGHT), r.nextInt(WIDTH),
r.nextInt(HEIGHT));
}
// 画数字
g.setColor(Color.BLUE);
g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 20));
int x = 20;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
String num = r.nextInt(10) + "";
sb.append(num);
g.drawString(num, x, 20);
x += 20;
}
//获取session,存储code
HttpSession session = request.getSession();
session.setAttribute("code", sb.toString());
ImageIO.write(image, "jpeg", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
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;
import javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//删除session中的user
HttpSession session = request.getSession();
session.removeAttribute("user");
out.write("注销成功!<a href='"+request.getContextPath()+"/servlet/IndexServlet'>返回主页</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class User {
private String username;
private String password;
public User(){}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
import java.util.ArrayList;
import java.util.List;
public class UserDB {
private static List<User> users = new ArrayList<User>();
static{
users.add(new User("chenchong","123"));
users.add(new User("admin","admin"));
}
public static User findUser(String username,String password){
User user = null;
for(User u:users){
if(u.getUsername().equals(username)&&u.getPassword().equals(password)){
user = u;
}
}
return user;
}
}
效果图:
3、防止表单重复提交
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.util.MD5Util;
//提供注册界面,向RegisterServlet提交数据
//在这里产生唯一的id,防止表单重复提交
public class RegisterUIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// String s = System.currentTimeMillis()+new Random().nextInt()+"";//尽量获取唯一的id
// String token = MD5Util.encode(s);//获取token
String token = UUID.randomUUID().toString();//可以获取唯一的值
request.getSession().setAttribute("token", token);//将取到的位移token存放到session中
out.write("<hr/>");
out.write("<form action='"+request.getContextPath()+"/servlet/RegisterServlet' method='post'>");
out.write("用户名<input type='text' name='username'/><br/>");
out.write("密码<input type='password' name='password'/><hr/>");
out.write("token<input type='text' name='token' value='"+token+"'>");//这里的type本应为hidden,但是为了便于观察,设为text
out.write("<input type='submit' name='提交'/><br/>");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
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 RegisterServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
String iToken = request.getParameter("token");//表单中提交过来的token
String sToken = (String) request.getSession().getAttribute("token");//session中存储的token
//在提交表单以后,删除session中token
//对比两个token的值,如果相同,则表单尚未提交过;如果不同,则表单已经提交过
if(iToken.equals(sToken)){
try {
Thread.sleep(2000);
} catch (Exception e) {
throw new RuntimeException(e);
}
out.write("表单提交成功!<br/>");
request.getSession().removeAttribute("token");
}else{
out.write("网页已过期!");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.security.MessageDigest;
import sun.misc.BASE64Encoder;
//对一组数字进行MD5加密
public class MD5Util {
public static String encode(String message){
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(message.getBytes());//获取message的数据指纹,不一定是一个字符
//new String(b);//不可行,在转换为字符串时,会查码表,可能会出现乱码
BASE64Encoder base64 = new BASE64Encoder();
return base64.encode(md5);//将数据转为明文
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
效果图:
1.正常提交表单
2.重复提交












浙公网安备 33010602011771号