30天自动登录
在EasyMall的登录页面,可以选择30天内容自动登录
用户信息需要保存30天,使用session不合适,应该考虑将用户信息存入cookie,由于整个网站的页面可能都会需要登录状态,所以可以将全部页面过滤,看是否需要自动登录,过滤器可以满足需求。
代码实现:
1.创建LoginFilter.java
package cn.tedu.filter;
//30天自动登录
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import com.easymall.domain.User;
import com.easymall.exception.MsgException;
import com.easymall.service.UserService;
public class LoginFilter implements Filter {
UserService userService=new UserService();
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
//读取cookie用户信息autologin
Cookie[] cs=req.getCookies();
//遍历cookie,从中寻找autologin,自动登录cookie
Cookie autologinC=null;
if(cs!=null){
for (Cookie c : cs) {
if("autologin".equals(c.getName())){
autologinC=c;
}
}
}
//找到autologin,取出用户名和密码,与数据库中的数据做比对
if(autologinC!=null){
//取出用户名和密码
String value=URLDecoder.decode(autologinC.getValue(), "utf-8");
//value的组成应该为username+#+password,所以根据#切割
String[] vs=value.split("#");
String username=vs[0];
String password=vs[1];
try {
//与数据库中的数据做比对
//由于在三层框架中userService服务层已经实现了登录功能,所以在此处应该直接调用
User user=userService.loginUser(username, password);
//保存登录状态---添加到session域
req.getSession().setAttribute("user", user);
} catch (MsgException e) {
throw new RuntimeException(e);
}
}
//放行
chain.doFilter(req, response);
}
public void init(FilterConfig config) throws ServletException {
// TODO Auto-generated method stub
}
}
2.修改loginServlet
//判断是否需要自动登录,如果需要则创建一个自动登录的cookie,保存用户信息30天
if("true".equals(autologin)){
Cookie cookie=new Cookie("autologin",URLEncoder.encode(username, "utf-8")+"#"+password);
cookie.setMaxAge(60*60*24*30);
cookie.setPath(request.getContextPath()+"/");
response.addCookie(cookie);
}
3.添加配置
<!--30天自动登录过滤器 -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.tedu.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
MD5加密
1.MD5概述
MD5是一种加密算法,可以用于数据加密,文件快传,文件校验,文件压缩等方面。
MD5还被称之为数据摘要算法,或数据指纹算法。
a.特点
i.经过加密后的数据,是不可破译的(除了王小云),无法得到原有的明文内容。
ii.经过加密的数据,都是由128位2进制数据组成。通常会把它书写成32位16进制的数据。
iii.任何形式的数据,经过加密之后,都会变为二进制数据,或长度为32位16进制的数据。
iv.同一份数据经过md5加密之后,一定会得到同一个结果。
2.数据库和代码数据都需要加密
md5密码数据库中的数据(密码)
数据库加密的api:
update user set password=md5(password);
在数据库加密之后,代码中的密码也应当加密,否则会出现吗,明文密码与密码密码做出判断的情况,永远无法匹配。
3.MD5修改EasyMall
创建MD5Utils工具类:
package com.easymall.utils;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
//MD5加密算法
public class MD5Utils {
public static String md5(String plainText){
byte[] secretBytes=null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
String md5code=new BigInteger(1,secretBytes).toString(16);
for (int i = 0; i < 32-md5code.length(); i++) {
md5code="0"+md5code;
}
return md5code;
}
}
a.修改LoginServlet
对密码进行加密(针对哪些要与数据库中的密码进行比较的密码)
监听器listener:
1.监听器概述:
servlet和filter及listener并称servlet三大技术
a.listener主要功能是实现对某一个事件的监听,一旦出发监听事件,则监听器就会做出对应的操作。
2.监听器的种类:
一共分为三类,八种监听器
a.监听域的创建和销毁的监听器
request | ServletRequestListener |
---|---|
session | HttpSessionListener |
servletcontext | ServletContextListener |
代码:
package cn.tedu.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
//监听request域创建与销毁的监听器
public class RequestListenerDemo1 implements ServletRequestListener {
//请求销毁时触发
public void requestDestroyed(ServletRequestEvent arg0) {
System.out.println("请求结束.."+arg0.getServletContext());
}
//请求创建时触发
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println("请求开始.."+arg0.getServletContext());
}
}
package cn.tedu.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//监听session域的创建与销毁的监听器
public class SessionListenerDemo1 implements HttpSessionListener {
//监听session域的创建
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("session域创建..."+arg0.getSession());
}
//监听session域的销毁
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("session域销毁..."+arg0.getSession());
}
}
package cn.tedu.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//servletcontext域的创建与销毁监听
public class ServletContextListenerDemo1 implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("day15结束..."+arg0.getServletContext());
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("day15开始..."+arg0.getServletContext());
}
}
配置:
<!-- request监听域 -->
<listener>
<listener-class>cn.tedu.listener.RequestListenerDemo1</listener-class>
</listener>
<!-- session监听域 -->
<listener>
<listener-class>cn.tedu.listener.SessionListenerDemo1</listener-class>
</listener>
<!-- servletcontext监听域 -->
<listener>
<listener-class>cn.tedu.listener.ServletContextListenerDemo1</listener-class>
</listener>
b.监听域中属性创建修改删除的监听器
ServletContextAttributeListenter | |
---|---|
HttpSessionAttributeListenter | |
ServletRequestAttributeListenter |
代码:
package cn.tedu.listener;
//servletcontext域属性监听器
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class SCListenterDemo1 implements ServletContextAttributeListener {
//在属性创建时触发
public void attributeAdded(ServletContextAttributeEvent arg0) {
System.out.println("servletcontext属性"+arg0.getName()+"创建"+arg0.getValue());
}
//在属性删除时触发
public void attributeRemoved(ServletContextAttributeEvent arg0) {
System.out.println("servletcontext属性"+arg0.getName()+"删除"+arg0.getValue());
}
//在属性修改时触发
public void attributeReplaced(ServletContextAttributeEvent arg0) {
System.out.println("servletcontext属性"+arg0.getName()+"替换"+arg0.getValue()+"替换后"+arg0.getServletContext().getAttribute("name"));
}
}
package cn.tedu.listener;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//测试servletcontext域属性监听器
public class ServletContextTest extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
ServletContext sc = this.getServletContext();
sc.setAttribute("name", "曹阳");
sc.setAttribute("name", "lishai");
sc.removeAttribute("name");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
配置:
<!-- servletcontext域属性监听域 -->
<listener>
<listener-class>cn.tedu.listener.SCListenterDemo1</listener-class>
</listener>
c.监听javabean在session域中变化的监听器
HttpSessionBindingListenter
HttpSessionActivationListenter
此类监听器在使用时,直接在JavaBean身上实现对应的接口,不需要添加相关的配置信息
代码:
package cn.tedu.domain;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
//监听javabean在session域中变化的监听器
//javabean
public class Person implements HttpSessionBindingListener{
private String name;
private int age;
private String gender;
public Person(){}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//javabean进入session域时触发
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("javabean进入session"+name);
}
//JavaBean移除session域时触发
public void valueUnbound(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
System.out.println("javabean移除session"+name);
}
}
package cn.tedu.listener;
//测试session域监听器
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 cn.tedu.domain.Person;
public class SessionTest extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getSession().setAttribute("name", "aaa");
//创建JavaBean对象,添加到session域中
Person p=new Person("李帅",18,"男");
request.getSession().setAttribute("p", p);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
EasyMall项目修改(监听器)
package cn.easymall.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
public class RequestListener implements ServletRequestListener {
public void requestDestroyed(ServletRequestEvent arg0) {
//获取请求对象
HttpServletRequest request=(HttpServletRequest) arg0.getServletRequest();
//获取请求对象的参数ip、url
String url=request.getRequestURI().toString();
String ip=request.getRemoteAddr();
String username=request.getParameter("username");
if(username==null){
username="游客";
}
System.out.println("用户【"+username+"】访问地址【"+url+"】客户机IP【"+ip+"】请求结束");
}
public void requestInitialized(ServletRequestEvent arg0) {
//获取请求对象
HttpServletRequest request=(HttpServletRequest) arg0.getServletRequest();
//获取请求对象的参数ip、url
String url=request.getRequestURI().toString();
String ip=request.getRemoteAddr();
String username=request.getParameter("username");
if(username==null){
username="游客";
}
System.out.println("用户【"+username+"】访问地址【"+url+"】客户机IP【"+ip+"】请求开始");
}
}
package cn.easymall.listener;
//监听servletcontext创建销毁的监听器
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SCListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("EasyMall启动");
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("EasyMall销毁");
}
}
package com.easymall.domain;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
//封装用户信息的Javabean
public class User implements HttpSessionBindingListener{
private int id;
private String username;
private String password;
private String nickname;
private String email;
public User(){}
public User(int id, String username, String password, String nickname,
String email) {
super();
this.id = id;
this.username = username;
this.password = password;
this.nickname = nickname;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("用户【"+username+"】登录EasyMall");
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("用户【"+username+"】退出EasyMall");
}
}
配置文件:
<!--servletcontextlistener -->
<listener>
<listener-class>cn.easymall.listener.SCListener</listener-class>
</listener>
<!--ServletRequestListener -->
<listener>
<listener-class>cn.easymall.listener.RequestListener</listener-class>
</listener>