使用过滤器验证用户是否登录
/**
* @Title: NoLoginFilter.java
* @Package com.qfedu.web.filter
* @Description: TODO(用一句话描述该文件做什么)
* @author Feri
* @date 2018年5月28日
* @version V1.0
*/
package com.gdsdxy.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Title: NoLoginFilter.java
* @Package com.qfedu.web.filter
* @Description: TODO(用一句话描述该文件做什么)
* @author Feri
* @date 2018年5月28日
* @version V1.0
*/
@WebFilter("/*")
public class NoLoginFilter implements Filter {
private String[] urls= {"getCart","addCart","order.jsp","orderDetail.jsp","getDirectOrder","addOrder","addfavorites","getGoodsById"};
/* */
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
String path=request.getServletPath();
if(isHave(path)) {
//需要进行登录拦截校验
if(request.getSession().getAttribute("user")==null) {
response.sendRedirect("login.jsp");
}else {
chain.doFilter(request, response);
}
}else {
chain.doFilter(request, response);
}
}
private boolean isHave(String path) {
for(String u:urls) {
if(path.contains(u)) {
return true;
}
}
return false;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
过滤器的配置:一是通过注解,二是通过web.xml中配置
如@WebFilter("/*")就是拦截所有请求。
xml方式可以说是和Servlet使用xml配置方式一样
myFilter
com.clucky.filter.MyFilter
myFilter
/*
Filter有3个阶段,分别是初始化,拦截和过滤,销毁。
初始化阶段:当服务器启动时,我们的服务器(Tomcat)就会读取配置文件,扫描注解,然后来创建我们的Filter。
拦截和过滤阶段:只要请求资源的路径和拦截的路径相同,那么过滤器就会对请求进行过滤,这个阶段在服务器运行过程中会一直循环。
销毁阶段:当服务器(Tomcat)关闭时,服务器创建的Filter也会随之销毁
FilterConfig和FilterChain这2个对象是由服务器(Tomcat)在创建和调用Filter对象时所传入的
FilterConfig对象可以读取我们配置的初始参数,FilterChain可以实现多个Filter之间的连接。
FilterConfig
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class MyFilterConfig implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("-----------获取全部key:value------------");
//得到所有配置参数的名字
Enumeration names = filterConfig.getInitParameterNames();
while (names.hasMoreElements()) {
//得到每一个名字
String name = names.nextElement();
System.out.println(name+" = "+filterConfig.getInitParameter(name));
}
System.out.println("-----------end.....------------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
xml:
myFilterConfig
com.clucky.filter.MyFilterConfig
driver
com.mysql.jdbc.Driver
url
jdbc:mysql://localhost:3306/equip_employ_manage?serverTimezone=GMT
username
root
password
root
myFilterConfig
/*
FilterChain
第一个filter
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class Filter01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("调用过滤器01对请求进行过滤~~~~");
//放行,如果还有过滤器,那么就执行下一个过滤器
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("调用过滤器01对响应进行过滤~~~~");
}
@Override
public void destroy() {
}
}
第二个Filter
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class Filter02 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("调用过滤器02对请求进行过滤~~~~");
//放行,如果还有过滤器,那么就执行下一个过滤器
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("调用过滤器02对响应进行过滤~~~~");
}
@Override
public void destroy() {
}
}
我们可以看见Filter01先进行过滤,然后交给Filter02,然后访问资源,然后Filter02对响应进行过滤,然后Filter01对响应进行过滤
多个Filter的执行顺序
上面我们配置了2个过滤器,那么我们怎么知道那个过滤器先执行呢?其实大家可以直接使用代码进行验证,培养独立思考的习惯,这里我就直接给出答案了。如果我们是在web.xml中配置的过滤器,那么过滤器的执行顺序就是
在web配置的顺序,配置在上面那么就会先执行。
如果我们是使用@WebFilter进行配置的,那么执行顺序就是字符比较顺序来执行,例如有2个过滤器,一个是AFilter,一个是BFilter,那么AFilter就会先执行。
如果注解和xml混用,那么在web.xml中配置的会先执行。
工具类:生成自定义数字
package com.gdsdxy.common.utils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
import java.util.UUID;
//随机数
public class RandomUtils {
//生成激活码
public static String createActive(){
return getTime()+Integer.toHexString(new Random().nextInt(900)+100);
}
//设置时间戳
public static String getTime(){
return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime());
}
//生成订单编号
public static String createOrderId(){
return getTime()+UUID.randomUUID().toString();
}
}
工具类:密码加密
package com.gdsdxy.common.utils;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
//MD5 摘要算法 签名或者简易加解密
public class MD5Utils {
public static String md5(String password){
try {
//获取摘要对象
MessageDigest md = MessageDigest.getInstance("MD5");
//设置要签名的内容
md.update(password.getBytes());
//获取摘要结果
return new BigInteger(1, md.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
工具类:邮箱编码、解码
package com.gdsdxy.common.utils;
import java.util.Base64;
/**
* 基于JDK1.8实现的BASE64编码
* 编码
* 解码*/
public class Base64Utils {
//编码
public static String encode(String msg){
return Base64.getEncoder().encodeToString(msg.getBytes());
}
//解码
public static String decode(String msg){
return new String(Base64.getDecoder().decode(msg));
}
}
Controller: :
创建激活码,创建它给对象的属性赋值,下面利用它作为条件查询,激活对象
上传的图片:用MultipartFile file接收,然后创建file desfile对象:再通过接口的file对象file.transferTo(创建的desfile对象)进行图片的存储
// 注册
@RequestMapping("userregister")
public String register(User user, Model model, HttpSession session, HttpServletRequest request, MultipartFile file) throws IOException {
// 创建激活码
String acode = RandomUtils.createActive();
user.setActivatecode(acode);
String fn = FileUtils.createFileName(file.getOriginalFilename());
File desfile = new File("C:\\hitech\\src\\main\\webapp\\image", fn);
file.transferTo(desfile);
user.setPicture(fn);
if (userService.save(user)) {
// 新增成功
session.setAttribute("acode", acode);
// 发送激活码
EmailUtils.sendEmail(user);
request.setAttribute("email",user.getEmail());
request.setAttribute("zt", "会员注册");
request.setAttribute("ts", "注册成功 别忘记激活!");
return "registerSuccess";
} else {
model.addAttribute("registerMsg", "服务器开小差,请稍后再来");
return "register";
}
}
UserService:
实现类:
Dao:
//新增
@Insert("insert into t_user(role ,username,password,email,gender,createtime ,flag ,activatecode,picture) values(1,#{username},#{password},#{email},#{gender},now(),1,#{activatecode},#{picture})")
int insert(User user);
EmailUtils.sendEmail(user);
EmailUtils :发送邮件,进行激活用户
package com.gdsdxy.common.utils;
import com.gdsdxy.domain.User;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Properties;
/*
* 基于JDK实现邮件发送
* 主要是实现激活码的发送
* */
public class EmailUtils {
public static void sendEmail(User user){
//邮箱
String myAccount = "[email protected]";
//授权码
String myPass = "java168";
//邮箱服务器
String SMTPHost = "smtp.163.com";
//设置属性信息
Properties prop = new Properties();
//设置协议
prop.setProperty("mail.transport.protocol", "smtp");
//邮件服务器
prop.setProperty("mail.smtp.host", SMTPHost);
//认证
prop.setProperty("mail.smtp.auth", "true");
//1、创建会话
Session session = Session.getDefaultInstance(prop);
//设置是否需要调试
session.setDebug(false);
//2、创建发送信息
MimeMessage message = createMsg(session,myAccount,user);
//4发送信息操作
try {
Transport tran = session.getTransport();
//连接
tran.connect(myAccount, myPass);
//发送消息
tran.sendMessage(message, message.getAllRecipients());
//关闭
tran.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//生成邮件消息
private static MimeMessage createMsg(Session session, String myAccount, User user) {
//创建消息对象
MimeMessage message = new MimeMessage(session);
//设置
try {
//3.1发送方
message.setFrom(new InternetAddress(myAccount, "HITECH官方邮件", "utf-8"));
//3.2设置接收方
/*
* MimeMessage.RecipientType.TO
* MimeMessage.RecipientType.CC
* MimeMessage.RecipientType.BCC
* */
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(user.getEmail(), user.getUsername(), "utf-8"));
//3.3 设置主题
message.setSubject("HITECH激活码","utf-8");
//获取本机的ip地址
String ip = Inet4Address.getLocalHost().getHostAddress();
String url = "http://localhost:8080/hitech_war/activate?e="+ Base64Utils.encode(user.getEmail())+"&c="+Base64Utils.encode(user.getActivatecode());
//String url = "http://"+ip+":8080/fengmi_war/activate?e="+ Base64Utils.encode(user.getEmail())+"&c="+Base64Utils.encode(user.getActivatecode());
//设置正文信息
message.setContent(user.getUsername()+",欢迎你加入我们
为了更好体验我们的产品,请点击激活"+url+"","text/html;charset=utf-8");
//设置日期
message.setSentDate(new Date());
//保存
message.saveChanges();
} catch (UnsupportedEncodingException | MessagingException | UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
}
}
UserService
实现类:
Dao:
//激活
@Update("update t_user set flag=2 where email=#{email} and activatecode=#{code}")
int updateAcode(@Param("email") String email, @Param("code") String code);
普通登录:
Controller:
// 登陆
@RequestMapping("userlogin")
public String login(String username, String password, Model model, HttpSession session) {
if (!StrUtils.empty(username, password)) {
User user = userService.getUserByName(username);
if (user != null) {
// 校验密码
if (user.getPassword().equals(MD5Utils.md5(password))) {
// 正确
// 记录登录信息到会话中
session.setAttribute("user", user);
Cart cart = cartService.queryByUid(user.getId());
if (cart == null) {
cart = new Cart();
cart.setUid(user.getId());
cart.setMoney(0);
cartService.createCart(cart);
}
session.setAttribute("cart", cartService.queryByUid(user.getId()));
// 页面跳转
return "index";
}
}
}
model.addAttribute("loginMsg", " 账号或密码错误!");
return "login";
}
UserService:
实现类:
UserDao:
//登录 用户名或密码都可以使用
@Select("select * from t_user where flag=2 and (username=#{name} or email=#{email})")
@ResultType(User.class)
User select(String name);
user.getPassword().equals(MD5Utils.md5(password)) :通过从数据库加密的密码进行解码,对比
登录成功后更具用户id进行查询是否含有购物车,创建一个购物车:
Cart cart = cartService.queryByUid(user.getId());
CartService:
实现类:
CartDao:
//获取用户的购物车
@Select("select * from t_cart where uid=#{uid}")
@ResultType(Cart.class)
public Cart queryByUid(int uid);
cartService.createCart(cart);
CaartService:
CartDao:
registerSuccess页面
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
HITECH
点击连接进行验证登录
邮箱登录:
UserService:
实现类:更具email获取用户信息,进行发送邮件,进行验证用户登录
User Dao:
//根据email获取user实例
@Select("select * from t_user where email=#{email} and flag=2")
@ResultType(User.class)
User selectEmail(String email);
EmailUtils2 :工具类发送短信:进行本地验证登录 用户信息
package com.gdsdxy.common.utils;
import com.gdsdxy.domain.User;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Properties;
/*
* 基于JDK实现邮件发送
* 主要是实现激活码的发送
* */
public class EmailUtils2 {
public static void sendEmail(User user){
//邮箱
String myAccount = "[email protected]";
//授权码
String myPass = "java168";
//邮箱服务器
String SMTPHost = "smtp.163.com";
//设置属性信息
Properties prop = new Properties();
//设置协议
prop.setProperty("mail.transport.protocol", "smtp");
//邮件服务器
prop.setProperty("mail.smtp.host", SMTPHost);
//认证
prop.setProperty("mail.smtp.auth", "true");
//1、创建会话
Session session = Session.getDefaultInstance(prop);
//设置是否需要调试
session.setDebug(false);
//2、创建发送信息
MimeMessage message = createMsg(session,myAccount,user);
//4发送信息操作
try {
Transport tran = session.getTransport();
//连接
tran.connect(myAccount, myPass);
//发送消息
tran.sendMessage(message, message.getAllRecipients());
//关闭
tran.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//生成邮件消息
private static MimeMessage createMsg(Session session, String myAccount, User user) {
//创建消息对象
MimeMessage message = new MimeMessage(session);
//设置
try {
//3.1发送方
message.setFrom(new InternetAddress(myAccount, "HITECH官方邮件", "utf-8"));
//3.2设置接收方
/*
* MimeMessage.RecipientType.TO
* MimeMessage.RecipientType.CC
* MimeMessage.RecipientType.BCC
* */
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(user.getEmail(), user.getUsername(), "utf-8"));
//3.3 设置主题
message.setSubject("HITECH邮箱登录","utf-8");
//获取本机的ip地址
String ip = Inet4Address.getLocalHost().getHostAddress();
String url = "http://localhost:8080/hitech_war/emailLogin?username="+ user.getUsername()+"&password="+user.getPassword();
//String url = "http://"+ip+":8080/fengmi_war/activate?e="+ Base64Utils.encode(user.getEmail())+"&c="+Base64Utils.encode(user.getActivatecode());
//设置正文信息
message.setContent(user.getUsername()+",欢迎你,
点击登录(不行就复制粘贴地址到浏览器上)"+url+"","text/html;charset=utf-8");
//设置日期
message.setSentDate(new Date());
//保存
message.saveChanges();
} catch (UnsupportedEncodingException | MessagingException | UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
}
}
Controller:验证用户登录
实现类:
UserDao:
//登录 用户名或密码都可以使用
@Select("select * from t_user where flag=2 and username=#{username} and password=#{password}")
@ResultType(User.class)
User Emailyanz(@Param("username") String username,@Param("password") String password);
userService.Xiugaijihuoma(acode, e);
UserService
实现类
//修改激活码
@Update("update t_user set activatecode=#{c} where email=#{e}")
boolean Xiugaijihuoma(@Param("c") String c ,@Param("e") String e);
userService.selectEmailAndC(acode,e);发送邮件进行修改
实现类:
package com.gdsdxy.common.utils;
import com.gdsdxy.domain.User;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Properties;
/*
* 基于JDK实现邮件发送
* 主要是实现激活码的发送
* */
public class EmailUtils3 {
public static void sendEmail(User user){
//邮箱
String myAccount = "[email protected]";
//授权码
String myPass = "java168";
//邮箱服务器
String SMTPHost = "smtp.163.com";
//设置属性信息
Properties prop = new Properties();
//设置协议
prop.setProperty("mail.transport.protocol", "smtp");
//邮件服务器
prop.setProperty("mail.smtp.host", SMTPHost);
//认证
prop.setProperty("mail.smtp.auth", "true");
//1、创建会话
Session session = Session.getDefaultInstance(prop);
//设置是否需要调试
session.setDebug(false);
//2、创建发送信息
MimeMessage message = createMsg(session,myAccount,user);
//4发送信息操作
try {
Transport tran = session.getTransport();
//连接
tran.connect(myAccount, myPass);
//发送消息
tran.sendMessage(message, message.getAllRecipients());
//关闭
tran.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//生成邮件消息
private static MimeMessage createMsg(Session session, String myAccount, User user) {
//创建消息对象
MimeMessage message = new MimeMessage(session);
//设置
try {
//3.1发送方
message.setFrom(new InternetAddress(myAccount, "HITECH官方邮件", "utf-8"));
//3.2设置接收方
/*
* MimeMessage.RecipientType.TO
* MimeMessage.RecipientType.CC
* MimeMessage.RecipientType.BCC
* */
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(user.getEmail(), user.getUsername(), "utf-8"));
//3.3 设置主题
message.setSubject("HITECH忘记密码","utf-8");
//获取本机的ip地址
String ip = Inet4Address.getLocalHost().getHostAddress();
String url = "http://localhost:8080/hitech_war/wjmm.jsp?e="+Base64Utils.encode(user.getEmail())+"&c="+Base64Utils.encode(user.getActivatecode());
//String url = "http://"+ip+":8080/fengmi_war/activate?e="+ Base64Utils.encode(user.getEmail())+"&c="+Base64Utils.encode(user.getActivatecode());
//设置正文信息
message.setContent(user.getUsername()+",你好,
点击更新密码(不行就复制粘贴地址到浏览器上)"+url+"","text/html;charset=utf-8");
//设置日期
message.setSentDate(new Date());
//保存
message.saveChanges();
} catch (UnsupportedEncodingException | MessagingException | UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
}
}
registerSuccess:跳转页面
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
HITECH
修改密码页面:${param.e}获取连接后加密的邮箱跟激活码
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" %>
HITECH
修改密码
Controller:
UserService:
实现类:
UserDao:
//根据email和激活码修改密码
@Update("update t_user set password=#{password},activatecode=#{cc} where email=#{e} and activatecode=#{c}")
boolean wjmm(@Param("cc") String cc,@Param("password") String password,@Param("e") String e,@Param("c") String c);