JavaWeb的Cookie
这里是用
tomcat+servlet
实现的JavaWeb,只是对cookie的保存和验证学习。
基本流程
- 初始 html 输入账密使用 post 方法跳转到页面 A,
- 页面 A 类使用
doPost
验证用户正确,保存用户身份, - 创建新 cookie,保存用户的账密,设置时效
- 重定向到新页面 B,
- 页面 A 类使用
- 新页面 B直接绘制即可。
- 直接访问页面 A,则属于 GET 请求!
- 调用页面 A 类的
doGet
获取 request 携带的 cookie:req.getCookies()
- 根据 cookie 中保存的账密来认证。因为直接访问 A 页面的 request 没有携带手动输入的账密,就是个干净的请求
- 认证通过就自动重定向到新页面 B,不会再显示原来的输入账密界面!
- 调用页面 A 类的
- 页面 B 直接绘制
访问变化
- 项目启动后进入yyds页面
- 输入账密后,会进行身份通过认证并保存cookie,重定向进入center
- 302重定向去center
- response创建用户的cookie
- 在center页面输入adminlog,在20s以内会因为身份认证通过直接重定向到此页面,20s后则会正常进入adminlog输入账户密码
- 输入center重新访问此页面同理,都会因为有cookie认证直接在center了!
代码
adminlog.java
需要有doGET
请求和doPOST
请求两种响应,不需要绘制页面,只要做身份验证和重定向的功能!
doGET
是对于直接在地址栏输入此网址,如果有cookie就会身份验证直接重定向到centerdoPOST
则是工程启动时第一次访问的那个账密输入页面,输入后会通过POST方法访问,主要是创建cookie并重定向
@WebServlet("/adminlog")
public class AdminLogServlet extends HttpServlet {
SqlSessionFactory factory;
@SneakyThrows
@Override
public void init() throws ServletException {
factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("batis-config.xml"));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 若req携带了cookie直接访问此页面,就相当于使用了GET请求,所以认证cookie,通过即跳转,
Cookie[] cookies = req.getCookies();
if(cookies != null){
String username = null;
String password = null;
System.out.println("(adminlog.doGet)request的密码:"+req.getParameter("adminpassword"));
for (Cookie cookie : cookies) {
if(cookie.getName().equals("name")) username = cookie.getValue();
if(cookie.getName().equals("password")) password = cookie.getValue();
}
if(username != null && password != null){
//Cookie存放了用户,就登陆校验
try (SqlSession sqlSession = factory.openSession(true)){
MyMapper mapper = sqlSession.getMapper(MyMapper.class);
Student user = mapper.queryStu(username, password);
if(user != null){
// 查询到了 用户
resp.sendRedirect("center");
return; //直接返回
}else{
// 没查到,cookie清零!
Cookie cc1 = new Cookie("name",username);
Cookie cc2 = new Cookie("password",password);
cc1.setMaxAge(0);
cc2.setMaxAge(0);
resp.addCookie(cc1);
resp.addCookie(cc2);
}
}
}
}
req.getRequestDispatcher("/").forward(req, resp); //正常情况还是转发给默认的Servlet帮我们返回静态页面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 接收前一个页面发来的req,根据其账密来认证,通过就跳转去中心,同时保留cookie
try (SqlSession ss = factory.openSession(true)) {
MyMapper mapper = ss.getMapper(MyMapper.class);
Map<String, String[]> reqmap = req.getParameterMap();
if (reqmap.containsKey("adminusername") && reqmap.containsKey("adminpassword")) {
String name = req.getParameter("adminusername");
String pwd = req.getParameter("adminpassword");
Student ret = mapper.queryStu(name, pwd);
if (ret != null) {
// 身份正确,存储cookie并重定向到center
if(reqmap.containsKey("remember-me")){
Cookie ck_name = new Cookie("name",name);
Cookie ck_pwd = new Cookie("password",pwd);
ck_pwd.setMaxAge(20);
resp.addCookie(ck_name);
resp.addCookie(ck_pwd);
}
resp.sendRedirect("center");
} else {
// 身份错误,转发到china
req.getRequestDispatcher("/china").forward(req, resp);
}
} else {
resp.sendRedirect("/china");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
center.java
直接绘制用户中心即可,一般都是接收GET请求,POST请求没用上。这里没有做用户判断,如果直接地址栏输入center是可以直接进来的。
@WebServlet("/center")
public class CenterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("CENTER -> doGet");
drawPage(req, resp);
}
private void drawPage(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer =resp.getWriter();
writer.write("<h1>/center 管理员中心!</h1>");
Cookie[] reqcc = req.getCookies();
for (Cookie cc:reqcc){
writer.write("<div>cookie的 "+cc.getName()+" = "+cc.getValue()+"</div>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("CENTER -> doPost");
drawPage(req, resp);
}
}