1.登录时记住用户名
浏览器请求login.jsp,用户拿到登录表单,用户在提交表单时勾选了“记住用户名”的选项,登录请求LoginServlet,在LoginServlet中首先需要拿到用户名,然后判断用户是否勾选了“记住用户名”,如果用户勾选了,创建一个Cookie,保存用户的用户名,然后将该Cookie添加到应答中,返回给用户,而在login.jsp中也需要判断用户是否携带了记住用户名的Cookie,如果携带了,从Cookie中取出用户名并显示在页面上;如果没有勾选,删除之前的Cookie。
LoginServlet中的代码
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;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取web.xml中配置的字符集
String encode=this.getServletContext().getInitParameter("encode");
//1.处理乱码-请求乱码
//POST请求乱码
request.setCharacterEncoding(encode);
//2.接收请求参数
String username=request.getParameter("username");
String password=request.getParameter("password");
String remname=request.getParameter("remname");
//3.表单验证
//4.执行逻辑
//1)记住用户名
// 判断用户是否勾选了记住用户名的选项
if(remname!=null&&"true".equals(remname)){
//勾选了记住用户名
//创建一保存用户名的Cookie
//URLEncoder.encode用来对一个字符串进行编码
//如果是中文的话在页面上显示的是16进制编码
//所以我们需要在login.jsp中进行处理
Cookie cookie = new Cookie("remname",URLEncoder.encode(username,encode));
//设置一个有效时间
cookie.setMaxAge(60*60*24*7);//7天
//手动设置路径为web应用的根路径
//EasyMall被配置成了虚拟主机的默认web应用
//导致request.getContextPath()返回""
//setPath("")->无效的,所以setPath(""+"/")->有效
cookie.setPath(request.getContextPath()+"/");
//将Cookie添加到Response中
response.addCookie(cookie);
}else{
//没有勾选记住用户名-删除之前保存的Cookie
Cookie cookie=new Cookie("remname","");
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(0);//删除当前Cookie
response.addCookie(cookie);
}
//2)登录
//5.根据执行的结果返回应答内容
//将请求重定向到首页
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
login.jsp中的代码,因为Cookie使用的是ASCII码,所以我们可以用一个工具类:URLEncoder来处理中文乱码问题;如果用户携带了记住用户名的Cookie,帮用户勾选“记住用户名”的选项。
<body>
<%
//可以写java代码
//1.获取用户本次请求携带的所有Cookie
Cookie[] cs=request.getCookies();
//2.判断用户是否携带了记住用户名的Cookie
Cookie findC=null;
if(cs!=null){
for(Cookie c:cs){
if("remname".equals(c.getName())){
findC=c;//找到了记住用户名的Cookie
break;
}
}
}
//3.如果携带了,获取Cookie中保存的用户名
String username="";//用来保存Cookie中携带的用户名
if(findC!=null){
//使用保存的用户名给username赋值
//有就返回值,没有就返回空串
//username=findC.getValue();
//解决页面上的16进制乱码
username=URLDecoder.decode(findC.getValue(),"utf-8");
}
//4.将用户名添加到username的input中
%>
<h1>欢迎登录EasyMall</h1>
<form action="/LoginServlet" method="POST">
<table>
<tr>
<td class="tdx">用户名:</td>
<td><input type="text" name="username" value="<%=username%>"/></td>
</tr>
<!-- 如果用户勾选了记住用户名,那么下一次用户在登录的时候浏览器会默认勾选 -->
<tr>
<td colspan="2">
<input type="checkbox" name="remname"
<%=findC==null?"":"checked='checked'" %>
value="true"/>记住用户名
<input type="checkbox" name="autologin" value="true"/>30天内自动登录
</td>
</tr>
2.登录实现
用户请求login.jsp,login.jsp返回给用户一个登录页面,用户在页面上输入用户名和密码后点击提交,将请求发送给LoginServlet,其中的逻辑有:处理乱码问题;接收表单参数;表单验证;执行记住用户名逻辑;执行登录逻辑。
我们现在细说一下登录逻辑:验证用户名密码,如果不正确,则跳转到login.jsp,获取错误提示信息显示在页面上;如果正确,我们需要保存用户的登录状态,向Session中添加一个键值对为user:实际用户名。index.jsp(实际上市head.jsp)也需要从Session作用域中得知用户是否登录成功。如果Session中有用户的键值对,说明用户登录成功,那么首页左上角变为“欢迎...回来 | 注销”,如果没有,则左上角还是“登录 | 注册”。
LoginServlet中的代码
//2)登录
//判断用户的用户名和密码是否正确
String sql = "select * from user where username=? and password=?";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn=JDBCUtils.getConnection();
ps=conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
rs=ps.executeQuery();
if(rs.next()){
//登录成功-向Session中添加登录状态
request.getSession().setAttribute("user", username);
//重定向到首页
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else{
//添加错误提示信息,并返回login.jsp
request.setAttribute("errMsg", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("登录出现异常:"+e.getMessage());
}finally{
JDBCUtils.close(conn, ps, rs);
}
我们为了实现注销的功能,需要写一个LogoutServlet
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 LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//执行注销的逻辑
//销毁用户绑定的Session
request.getSession().invalidate();
//请求重定向的首页
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
login.jsp中的代码
<h1>欢迎登录EasyMall</h1>
<form action="/LoginServlet" method="POST">
<table>
<tr>
<td colspan="2" style='text-align:center;color:red'><%=request.getAttribute("errMsg")==null?"":request.getAttribute("errMsg") %></td>
</tr>
<tr>
<td class="tdx">用户名:</td>
<td><input type="text" name="username" value="<%=username%>"/></td>
</tr>
head.jsp中的代码
<div id="line1">
<div id="content">
<%
HttpSession sess = request.getSession(false);
if(sess==null || sess.getAttribute("user")==null){%>
<a href="/login.jsp">登录</a> |
<!-- 由于当前项目是虚拟主机默认的web应用,因此项目隐射的URL应该是"" -->
<!-- <a href="/EasyMall01/regist.jsp">注册</a> -->
<a href="regist.jsp">注册</a>
<%}else{%>
欢迎<%=request.getSession().getAttribute("user") %>回来 |
<a href="/LogoutServlet">注销</a>
<%} %>
</div>
</div>