Severlet会话管理之Cookie使用
分为两个severlet程序,第一个用于判断cookie,和根据cookie的情况决定是否对表单进行填充,打印form表单在界面上;第二个用于响应表单的请求,如果有“记住密码”,“xx天内免登录”等信息,则创建cookie。
第一个程序如下:
public void Service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/html;charset=gb2312");
request.setCharacterEncoding("gb2312");
//在打印表单前,事先尝试获取Cookie
Cookie cookie_number = null;
Cookie cookie_password = null;
String number = "";
String password = "";
Cookie []cookies = request.getCookies();
if(cookies != null) {
//System.out.println("cookies[]不为空");
for(int i = 0; i<cookies.length; i++) {
System.out.println(cookies[i].getName());
if(cookies[i].getName().equals("number")) {
cookie_number = cookies[i];
number = cookie_number.getValue();
}
if(cookies[i].getName().equals("password")) {
cookie_password = cookies[i];
password = cookie_password.getValue();
}
}
}
// 实际逻辑
PrintWriter out = response.getWriter();
if(number.isEmpty() || password.isEmpty()) { //没有获取到cookie信息,仅仅正常打印表单
System.out.println("未自动填写登录信息");
try {
out.println("<h1>Login</h1>");
out.println("<form name=\"form\" method=\"post\" action=\"GetPostData\">");
out.println("<input name=\"number\" type=\"text\" placeholder=\"请输入学号/工号\"/>");
out.println("<br>");
out.println("<input name=\"password\" type=\"password\" placeholder=\"请输入密码\"/>");
out.println("<br>");
out.println("<input name=\"CheckboxRememberPwd\" type=\"checkbox\">记住密码");
out.println("<br>");
out.println("<input name=\"submit_login\" type=\"submit\" value=\"登录\" style=\"color: white; font-family: bold; background: forestgreen; margin-top: 20px; margin-right: 20px\">");
out.println("<input name=\"reset_input\" type=\"reset\" value=\"重置\" style=\"border: azure; background: aliceblue; color: gray\">");
out.println("</form>");
}finally {
out.close();
}
}
else { //获取到了完整的用户登录信息,自动填充表单
System.out.println("已自动填写登录信息");
System.out.println(number);
number = URLDecoder.decode(number,"utf-8");
System.out.println(number);
try {
out.println("<h1>Login</h1>");
out.println("<form name=\"form\" method=\"post\" action=\"GetPostData\">");
out.format("<input name=\"number\" type=\"text\" value=\"%s\"/>",number); //填充学号
out.println("<br>");
out.format("<input name=\"password\" type=\"password\" value=\"%s\"/>",password); //填充密码
out.println("<br>");
out.println("<input name=\"CheckboxRememberPwd\" type=\"checkbox\" checked>记住密码");
out.println("<br>");
out.println("<input name=\"submit_login\" type=\"submit\" value=\"登录\" style=\"color: white; font-family: bold; background: forestgreen; margin-top: 20px; margin-right: 20px\">");
out.println("<input name=\"reset_input\" type=\"reset\" value=\"重置\" style=\"border: azure; background: aliceblue; color: gray\">");
out.println("</form>");
}finally {
out.close();
}
}
}
第二个程序:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//doGet(request, response);
response.setContentType("text/html;charset=gb2312");
request.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
if(request.getParameter("number").isEmpty() || request.getParameter("password").isEmpty()) { //判断学号,密码是否都不为空,为空则提示
out.println("请完整输入学号密码");
}
else {
try {
out.println(
"<BODY>\n"+
"<div align=center>"+
"<h2>登录成功!</h2>\n"+
"学号/工号:"+
request.getParameter("number")+
"<br><br>"+
"密码:"+
request.getParameter("password")+
"<br><br>"+
"记住密码状态:"+
request.getParameter("CheckboxRememberPwd")+
"</div>"+
"</BODY></HTML>");
if(request.getParameter("CheckboxRememberPwd") == "null") {
//用户没有选择“记住密码”
System.out.println("用户没有选择“记住密码”");
}
else {
//用户选择“记住密码”
//Cookie操作
Cookie []cookies = request.getCookies();
Cookie cookie_number = null;
Cookie cookie_password = null;
boolean IsModify = false; //最新提交的表单与cookie存储是否不同
if(cookies != null) {
for(int i = 0; i<cookies.length; i++) {
if(cookies[i].getName().equals("number")) {
cookie_number = cookies[i];
if(!cookies[i].getValue().equals(request.getParameter("number"))) {
cookie_number.setValue(request.getParameter("number"));
IsModify = true;
}
}
if(cookies[i].getName().equals("password")) {
cookie_password = cookies[i];
if(!cookies[i].getValue().equals(request.getParameter("password"))) {
cookie_number.setValue(request.getParameter("password"));
IsModify = true;
}
}
}
}
if(cookie_number==null || cookie_password==null || IsModify) { //首次登录或者客户端删除了cookie数据 或者更新了新的学号密码
//System.out.println("添加cookie到响应返回给客户端");
String number = URLEncoder.encode(request.getParameter("number"),"utf-8"); //解决中文乱码
cookie_number = new Cookie("number",number);
cookie_password = new Cookie("password",request.getParameter("password"));
cookie_number.setPath(request.getContextPath());
cookie_password.setPath("/");
cookie_number.setHttpOnly(true);
cookie_password.setHttpOnly(true);
cookie_number.setMaxAge(60*60*24*30); //设置为一个月
cookie_password.setMaxAge(60*60*24*30);
response.addCookie(cookie_number);
response.addCookie(cookie_password);
}
}
}finally {
out.close();
}
}
}
遇到问题:
- cookie不生效,原因:
response.addCookie(cookie);
这一句一定要写在out.close();
这一句话之前。 - console发出警告:
在路径为[/Severlet_First]的上下文中,servlet[GetPost]的Servlet.service()引发异常
我是因为测试中文乱码问题产生的警告,只需要利用number = URLDecoder.decode(number,"utf-8");
从cookie中取出后解码成中文,String number = URLEncoder.encode(request.getParameter("number"),"utf-8");
,在存入cookie之前编译成utf-8即可。
存疑:
cookie.setPath("/");
此存入的路径是客户端的路径?