该用户从未签到
|
现在很多网站都有为用户保存登陆信息(即保存Cookie)的功能,当用户下一次进入网站时,可以帮助用户自动登陆,使网站显得更加友好。笔者通过研究ACEGI项目的自动登陆源码,编写了一个安全有效的实现两星期自动登陆功能的java工具类,下面是具体的实现流程和实现代码。6 [+ ~, d3 o# H U8 D4 T; [
- X% @4 r% j2 N- c6 |
先说一下流程:
! E, A8 H' i- r0 B. L0 _* m' I4 h5 K: n1 f2 n5 |
1.保存用户信息阶段:
& P# l1 x5 Z1 r9 ~( P( d _/ @7 v1 H7 y9 P+ }8 k( ?
当用户登陆网站时,在登陆页面填写完用户名和密码后,如果用户在提交时还选择了“两星期内自动登陆”复选框,那么在后台程序中验证用户名和密码全都正确后,还要为用户保存这些信息,以便用户下一次可以直接进入网站;如果用户没有勾选“两星期内自动登陆”复选框,则不必为用户保存信息,那么用户在下一次登陆网站时仍需要填写用户名和密码。
7 ~$ f( ~6 U/ j
N7 _8 K1 T+ a3 U$ S; Q/ N' E 在保存用户信息阶段,主要的工作是对用户的信息进行加密并保存到客户端。加密用户的信息是较为繁琐的,大致上可分为以下几个步聚:: w" u: [8 D) @' e
* v: M8 y1 _9 d8 {- Q5 a
① 得到用户名、经MD5加密后的用户密码、cookie有效时间(本文设置的是两星期,可根据自己需要修改)
+ u# J9 L7 ~ ?5 F3 z9 @ ② 自定义的一个webKey,这个Key是我们为自己的网站定义的一个字符串常量,这个可根据自己需要随意设置
2 ^5 m' p% F! z. D) _ ③ 将上两步得到的四个值得新连接成一个新的字符串,再进行MD5加密,这样就得到了一个MD5明文字符串
% R' \- C9 {" I {" F' Q/ E ④ 将用户名、cookie有效时间、MD5明文字符串使用“:”间隔连接起来,再对这个连接后的新字符串进行Base64编码! g5 z5 c4 g) d+ E
⑤ 设置一个cookieName,将cookieName和上一步产生的Base64编码写入到客户端。+ R8 m/ v; p3 B
8 z! ]% B8 l: R2 A2 `
2.读取用户信息:
7 j0 @6 q. P( [
# D" a/ _ C2 T- p$ y 其实弄明白了保存原理,读取及校验原理就很容易做了。读取和检验可以分为下面几个步骤:
1 E0 A# p; R$ t. x2 p3 N! [1 |( U/ d) \' i+ C9 L' y" R# F: g( T
① 根据设置的cookieName,得到cookieValue,如果值为空,就不帮用户进行自动登陆;否则执行读取方法
, e' }; m! E# i/ J& t, t+ s ② 将cookieValue进行Base64解码,将取得的字符串以split(“:”)进行拆分,得到一个String数组cookieValues(此操作与保存阶段的第4步正好相反),这一步将得到三个值:7 a" u4 S" j3 P0 P5 \# L
9 k: R! \6 D; E
cookieValues[0] ---- 用户名4 }. I4 I# `1 c" W) N
cookieValues[1] ---- cookie有效时间/ s! U- S3 d1 Z" V. G9 E S
cookieValues[2] ---- MD5明文字符串
( i; `( l$ O( z) O
4 z3 D# v0 |" a ③ 判断cookieValues的长度是否为3,如果不为3则进行错误处理。
1 o; t7 J% j* J# Z ④ 如果长度等于3,取出第二个,即cookieValues[1],此时将会得到有效时间(long型),将有效时间与服务器系统当前时间比较,如果小于当前时间,则说明cookie过期,进行错误处理。$ O& j& ], ~3 Q. N1 B- D$ S; N
⑤ 如果cookie没有过期,就取cookieValues[0],这样就可以得到用户名了,然后去数据库按用户名查找用户。! C1 ]* R8 D& F/ `0 _! i. Z
⑥ 如果上一步返回为空,进行错误处理。如果不为空,那么将会得到一个已经封装好用户信息的User实例对象user
2 Z" O: Q }0 Q* c4 ^) N ⑦ 取出实例对象user的用户名、密码、cookie有效时间(即cookieValues[1])、webKey,然后将四个值连接起来,然后进行MD5加密,这样做也会得到一个MD5明文字符串(此操作与保存阶段的第3步类似); U! ]' O! p; x6 ] c) ^
⑧ 将上一步得到MD5明文与cookieValues[2]进行equals比较,如果是false,进行错误处理;如果是true,则将user对象添加到session中,帮助用户完成自动登陆6 s1 y( Y8 W# @
# ?5 V$ ^# d. m3 _2 p; q" s# x 完整的代码,用途请参见注释
* U+ B# F$ @; M+ U8 RCookieUtil.java
( ]: w- T2 N2 ]% a, j% I& S
% Y5 ?& i* Y" B; ?# `) E( n8 n% R处理cookie的工具类,包括读取,保存,清除三个主要方法。
* V( D0 T" \* m3 D- X7 l# m' T, X8 Y
- public class CookieUtil {
/ c* r( U) P* S4 U' ^4 A) P - //保存cookie时的cookieName
+ b# b' e! y. w4 u z9 H, X - private final static String cookieDomainName = “cn.itcast”; ! v$ Z9 b; k4 S R1 t" e7 H8 @3 `
- //加密cookie时的网站自定码
C2 k. |9 }. B8 O - private final static String webKey = “itcast”; 3 D( S8 x6 V% e) `# m& Q; P) S
- //设置cookie有效期是两个星期,根据需要自定义
# I# Z E) n5 l) n - private final static long cookieMaxAge = 60 * 60 * 24 * 7 * 2; 3 }3 @; N8 \- V9 {6 c6 A
- //保存Cookie到客户端--------------------------------------------------------------------------------------------------------6 J8 T/ }& v) F8 K. S9 A4 h
- //在CheckLogonServlet.java中被调用
4 R/ ^% c% U) M# k - //传递进来的user对象中封装了在登陆时填写的用户名与密码 S. q* g/ N7 ?' ?& t# F ?
- public static void saveCookie(User user, HttpServletResponse response) {
' K) W z' Q6 D/ o7 z. s/ f5 j - ; l6 q/ U4 L6 b
- //cookie的有效期2 v. L; L. m" w9 b5 ^
- long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000); ( t) ~. m1 G l0 U
- //MD5加密用户详细信息
* W* s5 l7 t4 M# [9 B/ @ - String cookieValueWithMd5 =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTime + ":" + webKey); ! v3 @9 S; V* l9 E; Q" l
- //将要被保存的完整的Cookie值5 \/ E' w# K6 f* F( s
- String cookieValue = user.getUserName() + ":" + validTime + ":" + cookieValueWithMd5;
5 N! S, S) M; [5 j( }' R+ R - //再一次对Cookie的值进行BASE64编码1 Y6 T$ j% e+ f5 k K( X
- String cookieValueBase64 = new String(Base64.encode(cookieValue.getBytes()));
' Q) f+ k) H' x/ v+ g& b7 U/ `# H - //开始保存Cookie
' J" ?; ]# o. w" _( e q* O! N( z% w - Cookie cookie = new Cookie(cookieDomainName, cookieValueBase64);
0 |( j% W8 u* s) y
! p" \$ _! R* a9 U# y- //存两年(这个值应该大于或等于validTime)
- B/ \6 X f2 J7 k3 @ - cookie.setMaxAge(60 * 60 * 24 * 365 * 2);
1 Z8 |) N( r6 ~( H2 a, N6 ^& ^ - //cookie有效路径是网站根目录6 ]! N) H' G8 h/ s* {$ i( q
- cookie.setPath("/");
( [0 i b! Z% a* K6 w/ W - //向客户端写入+ s' ]% f6 h- c P1 G' e, Z
- response.addCookie(cookie);0 M9 z' z0 r$ }# _- i4 J( Y
! ~" Z3 s4 u' R! o& j' N- }# a/ K# d) n8 `: t9 n( |) d8 J
+ r$ ~/ _" }2 A R, O- //读取Cookie,自动完成登陆操作--------------------------------------------------------------------------------------------
1 E% p! Y4 X; t" K
; ^ ^: f% }- Y- v) @) x+ ~- //在Filter程序中调用该方法,见AutoLogonFilter.java
* \" y* P/ [ p/ l8 O - public static void readCookieAndLogon(HttpServletRequest request, HttpServletResponse response,
; v% B, Z+ C7 O$ L/ @ - FilterChain chain) throws IOException, ServletException,UnsupportedEncodingException{
, `* {& Y( j9 a$ a/ H - //根据cookieName取cookieValue# f U+ S3 G+ M7 O# b
- Cookie cookies[] = request.getCookies();
6 ~# R# M0 N! f: p - String cookieValue = null;
7 b6 m+ K" E1 h$ @" D# Q8 X/ z - if(cookies!=null){
1 c3 N |8 H: {! D$ X - for(int i=0; i<cookies.length; i++){9 w D4 `0 {9 \* H% m
- if (cookieDomainName.equals(cookies[i].getName())) {: n( J6 R! M8 ~2 l$ x9 g
- cookieValue = cookies[i].getValue();
9 ~. X6 ^/ K2 G7 j0 T7 \ - break;
) j9 u& a, r4 E! X/ a - }
+ l9 \* c6 o1 Z4 p* f# r - }
& a' e& W$ ~/ T$ C - }
- g: b5 {$ x. R8 p% c6 k, D - 2 O5 @: y1 L8 @
- ) ~% T6 T; E- A \" A$ `& R! x
- //如果cookieValue为空,返回,
: U. x5 A; n' B. i9 r, l - 6 ^- P" l, ?5 ?0 H% k3 M9 B, M
- if(cookieValue==null){8 X4 e3 `. D8 t; x
: ?7 D' A* z# r# @- return;, z4 y2 c$ T! E5 m; K* ^ @# n; G" R
. e3 a ` q- I; ^; c6 k. S- }
( \% Z' n0 @, ?2 l4 [
& ?, w/ }# M0 Z6 l" B! i: |- //如果cookieValue不为空,才执行下面的代码
" P" K2 @1 N& G' w
( w* h. z5 ~& i* _- //先得到的CookieValue进行Base64解码& _# ]: X* r! \* [/ q
- % L; |* L4 ?: O; W6 b
- String cookieValueAfterDecode = new String (Base64.decode(cookieValue),"utf-8");/ z( j9 n% L, A2 m! V
- : z) o- W$ M. ~, ~" R' ?5 K
- //对解码后的值进行分拆,得到一个数组,如果数组长度不为3,就是非法登陆+ l" D D9 ]$ g) t# F& `
- String cookieValues[] = cookieValueAfterDecode.split(":"); ) a4 F- M% |% {1 o$ p* i! Q* l( Y
- if(cookieValues.length!=3){
! B. x5 k: B4 h! ? - response.setContentType("text/html; charset=utf-8"); 2 t+ t5 y$ E9 x' ?) l
- PrintWriter out = response.getWriter();
: v' \3 S: I p/ [# c - out.println("你正在用非正常方式进入本站...");
3 K5 F- M; X# I6 l - out.close();
) E k4 L5 C( J, @# l# m a - return;
! H9 V/ e) V$ M) S7 x - }# } `: `/ N) w/ v3 j
- //判断是否在有效期内,过期就删除Cookie
" F0 u- L, d) ]7 k5 {: c - long validTimeInCookie = new Long(cookieValues[1]); ' w3 \+ K) R) q/ a" R- O' F3 @
- if(validTimeInCookie < System.currentTimeMillis()){. w! ^; K5 _+ N. X$ R
- //删除Cookie
n5 @0 I3 W3 G ^+ g - clearCookie(response);
) J# ~9 z- I! }6 d/ d) B - response.setContentType("text/html; charset=utf-8");
* m- S$ m% ~. h1 V" e/ t; B - PrintWriter out = response.getWriter(); 8 e6 @1 Y2 D2 }' m+ G
- out.println("<a href=’logon.jsp’>你的Cookie已经失效,请重新登陆</a>"); $ ?+ y0 P) d( o
- out.close();
% v: |: j. \* E: Y# w - return; 1 D* m) S0 E* H+ r% S$ o0 N% y
- }) W+ V Y6 c8 p5 U
$ W6 J3 V: [ D/ g1 O* m- //取出cookie中的用户名,并到数据库中检查这个用户名,
, d% x- R" M( Q: `6 h- G( G - String username = cookieValues[0];
, h! F6 j. ] e, l/ _0 H( R: K - //根据用户名到数据库中检查用户是否存在
$ r: M% a, k" e2 E. W- d - UserDAO ud = DaoImplFactory.getInstance();* U, r5 ?" V T4 ^. L* T5 I
- 2 C4 ^. H: s9 v2 T
- User user = ud.selectUserByUsername(username);; _, u) Q! W8 c, l1 ]
- & f8 {5 z% r# b- x+ j+ y
- //如果user返回不为空,就取出密码,使用用户名+密码+有效时间+ webSiteKey进行MD5加密5 N$ |0 {$ ~' d f
- if(user!=null){
; e3 I6 u f% r1 S$ m! t/ t - String md5ValueInCookie = cookieValues[2]; 2 |! k& W% ]/ @1 z: k; ~" W' U
- String md5ValueFromUser =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTimeInCookie + ":" + webKey);
2 z! X: E: H/ K& ?2 G - //将结果与Cookie中的MD5码相比较,如果相同,写入Session,自动登陆成功,并继续用户请求, m7 d3 m7 C$ w/ `: M. O) P
- if(md5ValueFromUser.equals(md5ValueInCookie)){
2 M) }, j4 d3 }" n - HttpSession session = request.getSession(true); ( Q9 M5 B2 i6 f" n0 m
- session.setAttribute("user", user);
& ~ f8 u3 M- o6 N5 z) b6 R; g* W - chain.doFilter(request, response);
4 \! S. \3 V ^( @4 ] - }
, g* ^! z8 S# T$ s/ B& c# Y - }else{6 u Q. {# V- @( l' c+ w7 \0 O, e
- //返回为空执行, H- m( k4 z0 o* Z+ y
- response.setContentType("text/html; charset=utf-8");
- A' ~/ g2 x7 |1 T4 ]8 F" j - PrintWriter out = response.getWriter();
9 `* ^3 b9 e* {: O - out.println("cookie验证错误!"); O5 g: N/ S0 A1 X
- out.close();
$ F! Z/ V' }: P- j% ]" R - return;
# `+ p0 B' y0 ], j - }0 X0 C1 V7 U l2 S
- }" e. s; l4 j$ A c5 _- R f+ r3 ~
- //用户注销时,清除Cookie,在需要时可随时调用------------------------------------------------------------9 n( G$ {3 _9 v
- public static void clearCookie( HttpServletResponse response){3 [& J, c" l# A P* a- }- b' H
- Cookie cookie = new Cookie(cookieDomainName, null);
u8 ^: ]3 Y% x! C - cookie.setMaxAge(0);
! N5 @. W/ ^1 z& C N - cookie.setPath("/"); ( j4 `. J4 E* v4 l
- response.addCookie(cookie); ) V8 S; E1 f5 L+ U, E
- }' Y8 F0 h6 u2 |1 D
- //获取Cookie组合字符串的MD5码的字符串----------------------------------------------------------------------------8 D% B+ c. z& G5 r$ h
- public static String getMD5(String value) {. Q5 |7 e; p. H |* R- x
- String result = null; 6 v3 F$ V, X; k3 k' X; a) ]% }
- try{
7 p& D; z. E) r* A& G6 q e$ q$ r - byte[] valueByte = value.getBytes();
o K- D" Q! T5 \2 V) Z - MessageDigest md = MessageDigest.getInstance("MD5"); 2 \3 k! Z7 |# D
- md.update(valueByte);
4 @; D+ B' [1 Z" t: ?* [- q - result = toHex(md.digest());
2 p9 r5 L$ ^# ], z1 B; u$ o9 B; f - } catch (NoSuchAlgorithmException e2){
+ p" R6 V) ]( I7 M5 ~ - e1.printStackTrace(); 2 V5 @$ b- X ~5 T& l
- }; A1 b1 f* T% i+ t
- return result; ; [' h( O% p9 I8 |6 b
- }! @9 P9 [( Q+ T( k9 V
- ! r: I6 p3 a1 l# d
- //将传递进来的字节数组转换成十六进制的字符串形式并返回. g( |* M# U: F9 f) Y* ]
- / @" J8 M8 K$ p5 X9 m
- private static String toHex(byte[] buffer){
! S1 e- [, G' P+ g4 A: f; n - StringBuffer sb = new StringBuffer(buffer.length * 2);
" s d; g' @6 k7 L- ~: t4 e - for (int i = 0; i < buffer.length; i++){1 |$ i8 r. s4 d+ w/ ~' Y' g8 f, B
- sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
7 u0 S4 v' [6 j* w& j7 _* X - sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
2 s/ {/ Q" x! M: B" K5 r8 S - }
! m R: V: U: h C% j - return sb.toString(); 1 m# F5 `% D# ?' G$ D1 n$ K
- }0 ^: S$ f4 B3 _3 C
- }
9 v) k. j" U: ~9 I8 N1 V9 [+ z* @
' z& A# M# ^. C, o- z- 下面的是对CookieUtil工具类各方法的调用演示:
& x q4 ~, @/ F7 D) _% l - % R. P8 G& U! K6 g# @
- User.java+ t( k; |. [# A0 H
- 8 W8 E5 `% H9 M! A" e2 R7 }* J N
- 封装用户信息的JavaBean对象模型: A0 i3 M8 P' z
- package com.itcast.bean; 6 q* F! d! }; y" H$ V9 k& Z
- public class User {
$ b0 F2 t# B$ ^1 d" Z! ^ - private int id; 6 E, V2 V$ w; Y0 Z2 q& V
- private String userName;
4 X: ^" a' `/ @ Y - private String password;
7 ?3 e6 R6 M* S$ R, ~1 G' Z3 v - public String getPassword() {
$ J9 `+ S K B" ~6 |# b - ' W3 Y c4 ?9 C/ `
- return password;
: g4 P6 z& m8 A
( \% A" j. z/ n2 }0 N; B G0 E- }& ^$ A; I |# M0 G$ a0 B" D: _. j
- public void setPassword(String password) {
9 S/ s" e1 T d# k2 ~ - 6 X8 W, `1 J/ z6 E; P1 O j
- this.password = password;
2 ~' h7 O, I/ m9 Y - ! L! E& h" ^; c0 k. c
- }
: Q( S, k# Q/ A" A
2 r; G# R6 F4 k2 E- public String getUserName() {* }% T; S& D* [
- / }1 D3 W; u- K7 u
- return userName;
+ h) P5 B3 q) K4 n d - o5 B- t0 R' c/ S) @
- }2 T1 U- w7 B1 i- I; y
- ) R% C) e, x3 N* ]6 G
- public void setUserName(String userName) {+ c& @ ?+ H, B
C2 G q4 ]* W& D3 }$ q8 [- this.userName = userName;# c$ Z) C/ {0 w1 ?$ `
- ' h0 V( Z7 Z$ J' W# y+ u5 Q0 t2 o
- }# s1 V$ f1 _9 w6 _. y5 q
) N, v5 Z7 e" d# B; R- public int getId() {
+ v/ T! w- m! k0 y - 5 N3 q4 E; Y& d8 X+ D
- return id;
5 \) F1 Q8 g1 G% x3 i& `
; {( F4 E4 V( F7 u+ v- }2 j( @. { ?& e
- # C8 \. E/ H' B4 ?5 I4 T( b* B; @
- public void setId(int id) {- D& q. }, N/ \; g- }0 D; P
1 u7 A& g, ~# N% H' Z- this.id = id;/ g9 }& x& K2 h- d
- \3 E8 ~2 @' j: I: g
- }
6 k8 U) W. T) B0 P8 }# {, u
: Q& R3 }1 ^/ A2 `. u- }
复制代码 1 U: [ ~8 Q A2 k2 `1 ~2 D4 S# ~3 I/ p
AutoLogonFilter.java( x6 b/ b4 } H# G6 j. M
; h4 t7 @' X H- o9 y* d过滤器程序,可在WEB-INF/web.xml中设置过滤规则,本文对过滤规则不作介绍,此程序主要作用是检查用户在上一次登陆时是否保存了Cookie,如果保存了,就处理Cookie信息,并帮助用户自动登陆! m2 b7 o+ }" ]) P* M$ S9 k! ]
3 H+ p6 q3 {$ I: X0 a2 G
0 @( u4 I0 l( w" A' q本程序主要调用了CookieUtil.java中的读取与自动登陆方法,即readCookieAndLogon方法
& J2 f4 V9 D, P# _ j- package cn.itcast.filter;
6 X* b& N `2 ^- ~3 T9 n( z; r' B
0 U( ~: ^3 e6 q; r* {: f- f- import java.io.IOException;
3 E0 f1 M- o) k* a! i - import javax.servlet.Filter;
% ]9 O) Z7 _! s4 M J8 L - import javax.servlet.FilterChain; . o9 c, j, N4 h! f
- import javax.servlet.FilterConfig; * l' a* B$ c' ?) I. H/ Y
- import javax.servlet.ServletException;
. W, I) k/ [! I0 Z - import javax.servlet.ServletRequest; ) Q( D( m! o7 d
- import javax.servlet.ServletResponse;
4 r: x4 d8 E% \8 F: {$ [# {2 t' r; M - import javax.servlet.http.Cookie; 2 Z, K$ c# D2 c. N2 `$ U
- import javax.servlet.http.HttpServletRequest; 9 A+ P* V0 D" Z( B/ R n5 P
- import javax.servlet.http.HttpServletResponse;
. f* u- T; y4 d5 [0 M% B" [ - import javax.servlet.http.HttpSession; 3 ^0 T2 ^& W+ ]1 G9 j0 L" K9 j" i
- import cn.itcast bean.User; + k) ~$ ^# {' ]8 ]5 l r5 B- c
- import cn.itcast.util.CookieUtil;
3 R+ o6 x E' L - 3 z. u, d# v: U' g3 K7 F" Y
- public class AutoLogonFilter implements Filter {% ]1 T1 @7 @1 P% T6 @
- u1 _' I1 V9 e! ?) w; Q- public void destroy() {$ b& W8 y8 R% e; @+ ]* W
5 b4 d' f9 Y7 S4 b" u& e- }
4 g7 `9 u* L! t) f0 c - ' K: ?- `/ r' V1 Y) L3 ]$ A
- //保存cookie时的cookieName,与CookieUtil.java中的设置相同8 ]& J9 h; \% z' |% ]' o$ w; g R' C
3 `3 S( l+ i- w( t& W1 s; W% J- private final static String cookieDomainName = “cn.itcast”;
7 E5 y4 _1 N$ Z4 A2 i# t
0 t8 a* T7 b0 Q& k, p6 W; K6 B-
]; y: M# Q. R8 K+ Y/ T - " z( M& I5 j) }* X, v
- public void doFilter(ServletRequest req, ServletResponse resp," J# [3 u8 [9 U+ s2 U/ \
- FilterChain chain) throws IOException, ServletException {9 n- V: `' c6 }# t
- HttpServletRequest request = (HttpServletRequest)req; : ~$ n8 `) A, r% U
- HttpServletResponse response = (HttpServletResponse)resp; ( Z H) }1 ^0 f* q7 n! d4 z
- HttpSession session = request.getSession(true); % r6 M% s/ U- M7 D& W8 X# n
- User user = (User)session.getAttribute("user");6 M G& T& Z; F, t3 E! A- E
' L% x5 }# c0 m5 b2 a5 B- " b4 ~2 o( J8 C( {( k/ R
- //如果封装的user不为空,说明已经登陆,则继续执行用户的请求.下面的就不处理了& E/ R, k9 ?) Y- \, \5 Q8 j
- f. A7 ? J: u- if(user!=null){) |, [, M0 i8 c% `
- chain.doFilter(request,response); . q. M! k) {$ G9 E/ z
- return; 2 L- X: P. Q9 E0 S \
- }2 _: J. [: p7 C+ x
- - H) K' G3 d3 Z) I; E6 g) m1 Y
- //user为空,说明用户还没有登陆,就尝试得到浏览器传送过来的Cookie- T2 F+ d9 R! `% s2 j/ m; |
- Cookie cookies[] = request.getCookies(); ; d" L0 A$ J0 n& |9 a* c( ?
- String cookieValue = null;
' x3 r" B3 }- b, M4 s5 e - if(cookies!=null){8 J! I6 `: J- X4 ^, f. @0 o
- for(int i=0; i<cookies.length; i++){
. ?; z; `4 p Y: p' I4 \: e! ? - if (cookieDomainName.equals(cookies[i].getName())) {: F2 ^! i7 m' L" m
- cookieValue = cookies[i].getValue();
7 Y' r$ E. L! U3 \5 _/ l6 | - break; * s. T Z" i& t2 W+ S
- }' d" p* `3 ?3 O; Q. G
- }
8 ]. Z7 K( h! c, p# v - }2 v* R: k5 J* t( E
- ' D8 Z( N3 ? B: _1 Z: a# _
- . O* S4 K( G9 w9 p
- //如果cookieValue为空,也继续执行用户请求
5 _3 w9 y5 C9 c7 f' g7 c - if(cookieValue==null){
' x+ R" v* j) l+ w0 v# U; b - chain.doFilter(request,response);
7 }; t9 m, t W a - return; / q2 w( H. ^# S8 X% s0 ^$ t
- }* f) w' F6 q( x+ @( X' e" i& E0 m: g
- ) N' S% W* g' e- R1 Z
- //cookieValue不为空执行下面的方法,调用CookieUtil.java中的readCookieAndLogon方法
; h% U) q/ B) J! m" D - try{
* ?2 K* @) l+ d- G: `) c# a - CookieUtil.readCookieAndLogon(cookieValue, request, response, chain);
- l4 V0 v5 k! o* T& K0 @ - }catch(Exception e){6 x# n( b9 }: T! u w' w
- e.printStackTrace(); 1 G) t) J3 k+ ]% _ C/ E3 y
- }
& s$ D: \6 P2 h& X! s- d! B# j; [ - }9 I0 M! C W0 @
- # O- k2 e/ y: D9 n! ^
- public void init(FilterConfig arg0) throws ServletException {
, P4 c3 J9 B! _; f - }
6 n7 X" D" s5 T H# M6 { - }
复制代码 $ k- |, _- }- j! f& q2 A
CheckLogonServlet.java
4 R8 g/ o, z* H4 N2 g
, G7 p& E; D3 d, w1 G2 L验证用户登陆信息的Servlet,此程序调用了CookieUtil.java中的saveCookie方法
$ J3 N L1 n% b0 Q# G& E
% M: O* n' _+ T& E: Ypackage cn.itcast.servlet;" ` `, c% R# b9 V! ?5 e& n) ^3 j
- import java.io.IOException;
$ X. \ U1 \ [5 o0 C% n% o* B - import javax.servlet.ServletException; 2 @4 d2 x+ V3 i8 B- x& h) N
- import javax.servlet.http.HttpServlet;
4 s* t5 _$ U9 ? - import javax.servlet.http.HttpServletRequest;
% M2 p I, ?: Q6 J - import javax.servlet.http.HttpServletResponse; / [0 l e( A1 Q! o
- import javax.servlet.http.HttpSession; % ?6 P5 ]0 e# l. \$ S+ {
- import cn.itcast.bean.User; / O% H+ _5 Y! o! R( C& Z
- import cn.itcast.dao.UserDAO; . e' B: K* M4 O& N% N; s$ i8 k
- import cn.itcast.factory.DaoImplFactory; 7 P0 V6 A1 k8 r1 d
- import cn.itcast.util.CookieUtil;# l- |. z' _5 t
- C& @7 h7 M* I& ^$ u- public class CheckLogonServlet extends HttpServlet {8 N5 n& w3 s! M2 y ?5 q' v; P. D
- ! X2 h0 M% K4 U# {+ }& ~/ w3 J+ b
- public void doGet(HttpServletRequest request, HttpServletResponse response)
$ ]9 C. s; g# h& R - throws ServletException, IOException {
; T9 i9 l( A) b$ K$ T- E - doPost(request, response);
$ O- I' n' w$ i3 O" c7 H - }+ u E) `/ k/ |' R- o$ k
- 6 e* i q( |+ I) `- ~ {
- public void doPost(HttpServletRequest request, HttpServletResponse response)
+ `: F! J0 g# _0 G9 A- V8 n1 q - throws ServletException, IOException {
! }/ A5 z, M: i* b+ n- z# y - request.setCharacterEncoding("utf-8"); F- G- A/ s+ u5 x( a4 r A
- String username = request.getParameter("username").trim();
( n: w0 k& o! v - String password = CookieUtil.getMD5(request.getParameter("password")); 3 n( r# h4 y% {, }+ X" `# W
- String remeberMe = request.getParameter("remeberMe"); " F' [$ |/ q. ^% e
- HttpSession session = request.getSession(false);/ E: F- Y. h# ?) w/ q
4 P" Q" H* k6 r1 ?+ d- // 将接收到的用户名传递到UserDao的checkUser方法中,检查用户
9 b+ }% J8 J8 r4 S& }0 r - // 返回一个User类型的对象
& C( e V! W' k' \; a0 [1 ]9 n - UserDAO ud = DaoImplFactory.getInstance(); ! z8 V6 X; F6 s6 ?, y6 c. R$ G9 A: w
- User user = ud.selectUserByUsername(username);
9 E1 n9 b y* d" r* x. P - if (user == null) {: |' m' ?# X0 Z0 `6 [% F: X
- request.setAttribute("checkUserError","<a href='register.jsp'><font color=red>用户名不存在,请先注册</font></a>"); " [; F( Z6 U3 n
- request.getRequestDispatcher("index.jsp").forward(request, response);
( Y% P; F, }5 `& N$ G - return;
7 \9 b# h) m! Y% H - }4 S$ r* O. z: T! e2 f$ J
& C7 [; e" N: I7 r5 o- if(!password.equals(user.getPassword())){3 \3 j1 O4 k+ |3 V8 w
- request.setAttribute("checkPasswordError","<font color=red>密码输入错误,请重新输入</font>"); $ s, [, | A5 v! p; A: u
- request.getRequestDispatcher("index.jsp").forward(request, response); ' s# m; h- y0 O* \" y
- return; ! h+ W& k& }! }5 b& q# G% I( E
- }6 v9 [9 T+ S* }% g
- , t! ^3 L) e! ]- [" h( z
0 x4 F Q8 W7 N. J! x9 L- //保存Cookie,这里调用了CookieUtil.java中的saveCookie方法,将上面的user对象作为参数传递
' t, h3 h' C1 Y E - if ("on".equals(remeberMe)) {
: p5 `% f! E- G6 h4 Y7 K( Z" O - CookieUtil.saveCookie(user, response); 4 c( i1 W3 e, w
- }
/ J0 N J' c/ r/ S9 u7 D - //在Session中保存用户信息,并转向用户的个人信息页面
& i$ n5 U2 R `# F- ^: ` - session.setAttribute("user", user); ! |" V9 q2 a4 g& s- s) V
- request.getRequestDispatcher("User/userInfo.jsp").forward(request,response); * c1 h$ Z; j" y* g T7 Y7 ^
- }
% S; P9 U& M q( I6 R - }
复制代码 / r2 j( n; N8 U& d) s7 n* r
UserDAO.java与DaoImplFactory.java属于持久层相关的程序,这里就不贴出来了,读者可根据自己需要选择不同的持久层框架,在本程序中只要实现查询用户的功能就可以了7 u: ]; n* o1 z, p
1 P/ ~3 Q# n! h- p0 U4 y. d* E1 z1 @0 u* |4 k: `" U
|
|