分析:
一、用户登陆:
就是根据客户端输入的用户名和密码,查找数据库是否匹配。如果匹配就是登陆成功,把user对象返回,并存到session域中去,表示用户登陆成功,重定向到首页。
其他页面可以在session域中取出user对象,调用user对象所包含维护的数据
如果账号查询不到,返回用户名不存在信息到request域做出用户不正确或不存在反馈,并return结束。
如果密码不匹配,返回密码错误信息到request域,并return结束。
二、自动登陆
自动登录,利用的是filter过滤,与cookies技术。
1.在用户第一次访问login.jsp页面的时候,如果勾选到了自动登陆选项,那么在login.jsp提交表单时候,就会把autoLogin也作为表单数据进行提交。<input type="checkbox" name="autoLogin" value="autoLogin">,即可以在后端servlet中request.getParameter("autoLogin") 获取。
2.在用户名与密码都正确的时候,加入判断语句,通过request获取String autoLogin,如果autoLogin等同于字符串"autoLogin",表示用户勾选了自动登陆代码。那么就把用户名,与密码存到cookie中。直接Cookie cookie_username = new Cookie("cookie_username",user.getusername),密码也是这样获取。然后response.addCookie(cookie_username)...放到客户端cookie中去。这样,客户端cookie就有了账号与密码。
3.创建一个servlet,继承Filter,覆写Filter的doFilter方法。实现每次自动登陆过滤的功能。首先把ServletRequest类型的参数request强转为 HttpServletRequest类型的参数req,然后通过req获取session域,并获取user对象。如果user!=null,就是已经登陆,不需要再执行登陆操作,直接放行。如果user==null,那么就是没有登陆,执行以下代码:通过req获取cookies。遍历cookies,得到cookie,记录cookie.getName() 为账号与密码 cookie的值。这样就从cookies内得到账号与密码。通过账号与密码再执行登陆操作的代码。
三、注销用户
注销用户即在session域消灭user对象,user没有了,就是用户已经注销。因为还有cookie记录,服务器会完成自动登陆,所以还要把客户端的cookie消除,操作为把账号和密码的cookie设置为空,存活时间设置为0,这样才完全完成。
准备:
步骤:
login.jsp
1.在submit所在表单,用post形式,填写提交表单的地址就是业务功能的地址。提交方法,方法名,用隐藏域提交
2.在适当的位置加如<span>标签,颜色为红色,插入如果登陆失败后request域返回的错误信息
3.修改 “自动登陆” 所在为止的value name,如果被勾选了,与表单数据一同提交。
4.判断user对象是否为空,如果不为空显示用户名,与“退出”。如果为空,显示“登陆”与“注册”
UserProduct
注册功能
1.获取客户端表单中的username和password
2,根据username,password传到service层,dao层,在数据库查询user对象
3,如果不匹配,在request域传达错误信息,转发回login.jsp页面。并结束代码,如果有则返回user对象。
4、判断用户是否有勾选自动登陆功能。如果果有,则把账号与密码存到cookie,并设置cookie存放时间。
5、把user存到session域,登陆就完成了,最后重定向到首页。
退出登陆功能
1.获取session并消除名为在域中名“user”对象。
2.创建用户名,域账号cookie,设置为空,时间设置为0,并存到客户端
3.重定向到首页
autoLoginFilter
1.创建一个Filter,实现Filter,复写doFilter功能
2.强转为HttpServletRequest类型
3.获取cookies,如果不为空遍历cookies,得到名为cookie_username cookie_password两个cookie的值。
4.如果账号与密码值不为空,查询对应user用户,并把得到的user存到session域中
5.放行所有操作。
6.配置web.xml哪些需要过滤的地址。
header.jsp
1.修改“登陆”与“注册”位置所在的代码,判断user是否存在,如果不存在,显示“登陆”“注册”,如果user存在,提取user对象的username显示与“退出”
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>会员登录</title>
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet" href="css/style.css" type="text/css" />
<style>
body {
margin-top: 20px;
margin: 0 auto;
}
.carousel-inner .item img {
width: 100%;
height: 300px;
}
.container .row div {
/* position:relative;
float:left; */
}
font {
color: #666;
font-size: 22px;
font-weight: normal;
padding-right: 17px;
}
</style>
</head>
<body>
<!-- 引入header.jsp -->
<jsp:include page="/header.jsp"></jsp:include>
<div class="container"
style="width: 100%; height: 460px; background: #FF2C4C url('images/loginbg.jpg') no-repeat;">
<div class="row">
<div class="col-md-7">
<!--<img src="./image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">-->
</div>
<div class="col-md-5">
<div
style="width: 440px; border: 1px solid #E7E7E7; padding: 20px 0 20px 30px; border-radius: 5px; margin-top: 60px; background: #fff;">
<font>会员登录</font>USER LOGIN
<div> </div>
<form class="form-horizontal" method="post" action="${pageContext.request.contextPath }/user">
<!-- 加上隐藏域,执行方法的地址 -->
<input type="hidden" name="method" value="login">
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="username" name="username"
placeholder="请输入用户名">
</div>
<span style="color: red">${usernameInfo }</span>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">密码</label>
<div class="col-sm-6">
<input type="password" class="form-control" id="password" name="password"
placeholder="请输入密码">
</div>
<span style="color:red">${passwordInfo }</span>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="inputPassword3"
placeholder="请输入验证码">
</div>
<div class="col-sm-3">
<img src="./image/captcha.jhtml" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<!-- 如果勾选了自动登陆,把数据一起进行表单提交 -->
<label> <input type="checkbox" name="autoLogin" value="autoLogin"> 自动登录
</label> <label> <input
type="checkbox"> 记住用户名
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" width="100" value="登录" name="submit"
style="background: url('./images/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height: 35px; width: 100px; color: white;">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- 引入footer.jsp -->
<jsp:include page="/footer.jsp"></jsp:include>
</body>
</html>
UserServlet
package com.itheima.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import javax.mail.MessagingException;
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;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import com.itheima.domain.User;
import com.itheima.service.UserService;
import com.itheima.utils.MailUtils;
public class UserServlet extends BaseServlet {
//注销用户
public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//把session域里面的user对象删除
HttpSession session = request.getSession();
session.removeAttribute("user");
//把cookie里面的账号和密码清除
Cookie cookie_username = new Cookie("cookie_username","");
Cookie cookie_password = new Cookie("cookie_password","");
//设置时间为0,消除客户端的cookie
cookie_username.setMaxAge(0);
cookie_password.setMaxAge(0);
//存储cookie
response.addCookie(cookie_username);
response.addCookie(cookie_password);
//退出登陆后重定向到首页
response.sendRedirect(request.getContextPath());
}
//登陆用户
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
UserService service = new UserService();
//获取用户名
String username = request.getParameter("username");
boolean username_isExist = service.checkUsername(username);
if(!username_isExist) {
//返回错误信息
request.setAttribute("usernameInfo", "用户名错误或者不存在");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
//获取密码,并按照用户名,匹配密码,登陆用户
String password = request.getParameter("password");
User user = service.login(username,password);
if(user==null) {
//返回错误信息
request.setAttribute("passwordInfo", "密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
//判断用户是否勾选了自动登陆选项
String autoLogin = request.getParameter("autoLogin");
//必须“autoLogin”在前,以防止空指针错误
if("autoLogin".equals(autoLogin)) {
//用户勾选了自动登陆,把账号与密码存到cookie
Cookie cookie_username = new Cookie("cookie_username",user.getUsername());
cookie_username.setMaxAge(10*60);
Cookie cookie_password = new Cookie("cookie_password",user.getPassword());
cookie_password.setMaxAge(10*60);
response.addCookie(cookie_username);
response.addCookie(cookie_password);
}
//把user存到session登陆
HttpSession session = request.getSession();
session.setAttribute("user", user);
//跳到首页
response.sendRedirect(request.getContextPath());
}
//注册新用户
public void register(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
//0。验证码的判断
String checkcode_session = (String) request.getSession().getAttribute("checkcode_session");
String checkcode_user = request.getParameter("checkCode");
if(!checkcode_user.equals(checkcode_session)) {
request.setAttribute("checkInfo", "验证码失败");
request.getRequestDispatcher("register.jsp").forward(request, response);
return;
}
//1.获取表单数据,并封装成user对象
Map<String, String[]> parameterMap = request.getParameterMap();
User user = new User();
//自定义转换器
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class clazz, Object value) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = format.parse(value.toString());
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
}, Date.class);
//利用工具封装到user
try {
BeanUtils.populate(user, parameterMap);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
//手动封装没有的数据
user.setUid(UUID.randomUUID().toString());
user.setTelephone(null);
user.setState(0);
user.setCode(UUID.randomUUID().toString());
//传递到service层
UserService service = new UserService();
boolean isSuccess = service.register(user);
if(isSuccess) {
//2.激活注册用户
//注册成功
String emailMsg ="恭喜您注册成功,请您点击进行激活<a href='http://localhost:8080/Shop/user?method=active&activeCode="+user.getCode()+"'>"
+ "http://localhost:8080/Shop/user?method=active&activeCode="+user.getCode()+"</a>";
try {
MailUtils.sendMail(user.getEmail(), emailMsg);
} catch (MessagingException e) {
e.printStackTrace();
}
response.sendRedirect(request.getContextPath()+"/registerSuccess.jsp");
}else {
//注册失败
response.sendRedirect(request.getContextPath()+"/registerFail.jsp");
}
}
//检验用户名是否已存在checkUsername
public void checkUsername(HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取需要检测的用户名
String username = request.getParameter("username");
//传递到service层
UserService service = new UserService();
boolean isExist = service.checkUsername(username);
String json ="{\"isExist\":"+isExist+"}";
response.getWriter().write(json);
}
//激活账户
public void active(HttpServletRequest request,HttpServletResponse response) {
//获取需要激活账号的激活码
String activeCode = request.getParameter("activeCode");
//传递到service层
UserService service = new UserService();
service.active(activeCode);
}
}
UserService
package com.itheima.service;
import java.sql.SQLException;
import com.itheima.dao.UserDao;
import com.itheima.domain.User;
public class UserService {
//注册新用户
public boolean register(User user) {
UserDao dao = new UserDao();
int row=0;
try {
row = dao.register(user);
} catch (SQLException e) {
e.printStackTrace();
}
return row>0?true:false;
}
//检验用户名是否已存在
public boolean checkUsername(String username) {
UserDao dao = new UserDao();
Long row =0L;
try {
row = dao.checkUsername(username);
} catch (SQLException e) {
e.printStackTrace();
}
return row>0?true:false;
}
// 激活账号
public void active(String activeCode) {
UserDao dao = new UserDao();
try {
dao.active(activeCode);
} catch (SQLException e) {
e.printStackTrace();
}
}
//登陆用户
public User login(String username, String password) {
UserDao dao = new UserDao();
User user = null;
try {
user = dao.login(username,password);
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
}
UserDao
package com.itheima.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.itheima.domain.User;
import com.itheima.utils.DataSourceUtils;
public class UserDao {
/*`uid` varchar(32) NOT NULL,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`telephone` varchar(20) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`code` varchar(64) DEFAULT NULL,*/
//注册新用户
public int register(User user) throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?)";
int update = runner.update(sql, user.getUid(),user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),
user.getTelephone(),user.getBirthday(),user.getSex(),user.getState(),user.getCode());
return update;
}
//检验用户名是否已存在
public Long checkUsername(String username) throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select count(*) from user where username=?";
Long query = (Long) runner.query(sql, new ScalarHandler(), username);
return query;
}
//激活账号
public void active(String activeCode) throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql ="update user set state=? where code=?";
runner.update(sql, 1,activeCode);
System.out.println("激活成功");
}
//登陆用户
public User login(String username, String password) throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select * from user where username=? and password=?";
User user = runner.query(sql, new BeanHandler<User>(User.class), username,password);
return user;
}
}
autoLoginFilter
package com.itheima.web.filter;
import java.io.IOException;
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.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.domain.User;
import com.itheima.service.UserService;
public class AutoLoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//强转类型
HttpServletRequest req = (HttpServletRequest) request;
//获取cookies
Cookie[] cookies = req.getCookies();
//遍历cookies,获取用户名与密码
String username=null;
String password=null;
if(cookies!=null) {
for(Cookie cookie:cookies) {
if(cookie.getName().equals("cookie_username")) {
username = cookie.getValue();
}
if(cookie.getName().equals("cookie_password")) {
password = cookie.getValue();
}
}
}
//根据用户名与密码查询user对象
if(username!=null&&password!=null) {
UserService service = new UserService();
User user = service.login(username, password);
//把user对象存到session域,完成登陆
req.getSession().setAttribute("user", user);
}
//放行
chain.doFilter(req, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
head.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<!-- 登录 注册 购物车... -->
<div class="container-fluid">
<div class="col-md-4">
<img src="img/logo2.png" />
</div>
<div class="col-md-5">
<img src="img/header.png" />
</div>
<div class="col-md-3" style="padding-top:20px">
<ol class="list-inline">
<!-- 判断用户是否登陆,如果登陆显示用户名 -->
<c:if test="${empty user }">
<li><a href="login.jsp">登录</a></li>
<li><a href="register.jsp">注册</a></li>
</c:if>
<c:if test="${!empty user }">
<li><a href="javascript:;">欢迎您,${user.username }</a></li>
</c:if>
<li><a href="cart.jsp">购物车</a></li>
<li><a href="order_list.jsp">我的订单</a></li>
</ol>
</div>
</div>
<!-- 导航条 -->
<div class="container-fluid">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">首页</a>
</div>
<!-- 商品分类列表 ajax-->
<script type="text/javascript">
$(function(){
$.post(
"${pageContext.request.contextPath}/product?method=category",
function(data){
//[{"cid":"xxx","cname":"xxx"},{},{},{},{}]
var content ="";
for (var i = 0; i < data.length; i++) {
//拼接字符串后,内部双引号必须改为单引号
//a标签链接为根据cid查找商品的一个servlet,注意拼接字符串
content+="<li><a href='${pageContext.request.contextPath}/product?method=productListByCid&cid="+data[i].cid+"'>"+data[i].cname+"</a></li>"
}
//添加li到ul中
$("#categoryUl").html(content);
},
"json"
);
});
</script>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav" id="categoryUl">
<!-- <li class="active"><a href="product_list.htm">手机数码<span class="sr-only">(current)</span></a></li>
<li><a href="#">电脑办公</a></li>
<li><a href="#">电脑办公</a></li>
<li><a href="#">电脑办公</a></li>
--> </ul>
<form class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</nav>
</div>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Shop</display-name>
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 自动登陆 -->
<filter>
<display-name>AutoLoginFilter</display-name>
<filter-name>AutoLoginFilter</filter-name>
<filter-class>com.itheima.web.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<description></description>
<display-name>BaseServlet</display-name>
<servlet-name>BaseServlet</servlet-name>
<servlet-class>com.itheima.web.servlet.BaseServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BaseServlet</servlet-name>
<url-pattern>/BaseServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>CheckImgServlet</display-name>
<servlet-name>CheckImgServlet</servlet-name>
<servlet-class>com.itheima.web.servlet.CheckImgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CheckImgServlet</servlet-name>
<url-pattern>/checkImg</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>UserServlet</display-name>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.itheima.web.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>ProductServlet</display-name>
<servlet-name>ProductServlet</servlet-name>
<servlet-class>com.itheima.web.servlet.ProductServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProductServlet</servlet-name>
<url-pattern>/product</url-pattern>
</servlet-mapping>
</web-app>