该用户从未签到
|
现在很多网站都有为用户保存登陆信息(即保存Cookie)的功能,当用户下一次进入网站时,可以帮助用户自动登陆,使网站显得更加友好。笔者通过研究ACEGI项目的自动登陆源码,编写了一个安全有效的实现两星期自动登陆功能的java工具类,下面是具体的实现流程和实现代码。
5 W2 { v& E: L( _, U# H
" ]! v, O+ t/ l0 P) g/ K$ z# X 先说一下流程:0 m2 l6 Z/ i/ |/ u
" w/ H9 a# l, m+ K: K
1.保存用户信息阶段:
. L8 \0 b7 d! l
) I; e3 U- E' Z7 j0 ~; M 当用户登陆网站时,在登陆页面填写完用户名和密码后,如果用户在提交时还选择了“两星期内自动登陆”复选框,那么在后台程序中验证用户名和密码全都正确后,还要为用户保存这些信息,以便用户下一次可以直接进入网站;如果用户没有勾选“两星期内自动登陆”复选框,则不必为用户保存信息,那么用户在下一次登陆网站时仍需要填写用户名和密码。) D, ^3 V2 C, E- p' F# E
2 s% f# Y- f2 B* h' g& A
在保存用户信息阶段,主要的工作是对用户的信息进行加密并保存到客户端。加密用户的信息是较为繁琐的,大致上可分为以下几个步聚:
/ j- j& M- U' A3 q# |
- d$ G0 T: _/ }1 a$ j ① 得到用户名、经MD5加密后的用户密码、cookie有效时间(本文设置的是两星期,可根据自己需要修改)
q/ r7 _+ w( [9 c ② 自定义的一个webKey,这个Key是我们为自己的网站定义的一个字符串常量,这个可根据自己需要随意设置
4 ?" \. r" d' B, q/ e ③ 将上两步得到的四个值得新连接成一个新的字符串,再进行MD5加密,这样就得到了一个MD5明文字符串& B& E" _9 ` g* p+ ~" K2 D5 K6 A
④ 将用户名、cookie有效时间、MD5明文字符串使用“:”间隔连接起来,再对这个连接后的新字符串进行Base64编码
8 I( [* Z/ D7 d ⑤ 设置一个cookieName,将cookieName和上一步产生的Base64编码写入到客户端。
7 k& q( \( @6 a9 p; Q! F
2 |$ W0 }( ^, T; _3 B 2.读取用户信息:
# A Q! ]9 F: \& q' V* T$ k" Y: l" @
其实弄明白了保存原理,读取及校验原理就很容易做了。读取和检验可以分为下面几个步骤:( x2 @; U1 t3 M0 E1 k6 G
# i6 Z# U4 a d2 E- d% u* ? ① 根据设置的cookieName,得到cookieValue,如果值为空,就不帮用户进行自动登陆;否则执行读取方法
+ G1 t9 _# g4 |' ` ② 将cookieValue进行Base64解码,将取得的字符串以split(“:”)进行拆分,得到一个String数组cookieValues(此操作与保存阶段的第4步正好相反),这一步将得到三个值:. J4 u+ z3 {& ~* q9 O: l3 T
/ c6 H9 _- A" scookieValues[0] ---- 用户名7 L+ E' |1 E2 e$ _
cookieValues[1] ---- cookie有效时间+ F+ t3 W" p' {1 j0 I) j d
cookieValues[2] ---- MD5明文字符串
' B' u* }: c7 ^& H: a9 d% n' y9 X% h% O( I" [2 L- H4 [
③ 判断cookieValues的长度是否为3,如果不为3则进行错误处理。
) k! n& q" t* g+ _/ ? ④ 如果长度等于3,取出第二个,即cookieValues[1],此时将会得到有效时间(long型),将有效时间与服务器系统当前时间比较,如果小于当前时间,则说明cookie过期,进行错误处理。
9 @; w7 ?2 O0 n! d" x1 ` ⑤ 如果cookie没有过期,就取cookieValues[0],这样就可以得到用户名了,然后去数据库按用户名查找用户。
/ X/ l8 e! W+ Q7 X. n ⑥ 如果上一步返回为空,进行错误处理。如果不为空,那么将会得到一个已经封装好用户信息的User实例对象user; G. @5 ~% l- F; a
⑦ 取出实例对象user的用户名、密码、cookie有效时间(即cookieValues[1])、webKey,然后将四个值连接起来,然后进行MD5加密,这样做也会得到一个MD5明文字符串(此操作与保存阶段的第3步类似)
7 k$ \8 ^" n: @7 V, D3 J* w ⑧ 将上一步得到MD5明文与cookieValues[2]进行equals比较,如果是false,进行错误处理;如果是true,则将user对象添加到session中,帮助用户完成自动登陆
0 u8 y, ?' u# y
' I9 @2 k9 K! [ 完整的代码,用途请参见注释
3 V# J2 B" @, D7 T; L( ICookieUtil.java
) @" r5 B) h: O8 N8 u4 P- i5 g+ Y% W L u
处理cookie的工具类,包括读取,保存,清除三个主要方法。4 _( O% N2 `( ~3 [; [, W( A- F _% G ]
( M. j k- l" \
- public class CookieUtil {
+ f" D& ]& Y% U3 N3 r - //保存cookie时的cookieName
" g0 d/ f4 @' x' q$ ` - private final static String cookieDomainName = “cn.itcast”; : K/ A1 ?2 s# c) A L X0 n* L
- //加密cookie时的网站自定码
( k( t/ H2 [% h r/ T5 C - private final static String webKey = “itcast”; 5 `0 y( s% x( h. t/ M+ p4 ?* S
- //设置cookie有效期是两个星期,根据需要自定义( `2 K% N! Q) q" a1 k
- private final static long cookieMaxAge = 60 * 60 * 24 * 7 * 2; ' A: I! |* T: ^! Z0 N6 \' A& {: A
- //保存Cookie到客户端--------------------------------------------------------------------------------------------------------+ E( V6 h* x6 ]3 Z
- //在CheckLogonServlet.java中被调用% u8 K% o& y7 E+ u7 R' N
- //传递进来的user对象中封装了在登陆时填写的用户名与密码: g! p: l& K. t0 H" f% c
- public static void saveCookie(User user, HttpServletResponse response) {) Z: t7 m8 E" G0 ?$ E7 L
* Z3 m. ]6 k0 [; i2 {4 d1 ~- //cookie的有效期& \$ J e# N u. |
- long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000); * D4 F0 e0 f' t1 i& E8 W4 S
- //MD5加密用户详细信息
( ~% A2 c- i% s/ I5 b H - String cookieValueWithMd5 =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTime + ":" + webKey);
2 N) m# g2 S6 H4 g. k' e - //将要被保存的完整的Cookie值+ Y; C$ a |" E
- String cookieValue = user.getUserName() + ":" + validTime + ":" + cookieValueWithMd5;
/ n0 j5 G! \4 K3 j - //再一次对Cookie的值进行BASE64编码
, V5 g. j/ X3 M4 ]8 [; |# g - String cookieValueBase64 = new String(Base64.encode(cookieValue.getBytes())); 4 C+ o7 ~9 f% ^8 `: C( X
- //开始保存Cookie% K" F% n% g2 S
- Cookie cookie = new Cookie(cookieDomainName, cookieValueBase64);
$ k* ^- i0 j( z- o - ; `) ~/ k9 B( l) }& m5 o1 R& a" ?
- //存两年(这个值应该大于或等于validTime)+ `! u: I; X& i4 Y) x
- cookie.setMaxAge(60 * 60 * 24 * 365 * 2);
4 X; P" w, @# Q _2 J - //cookie有效路径是网站根目录
' f( _# G8 G: L6 p1 z5 h0 D - cookie.setPath("/"); , A7 w0 k( U; Z! v9 o$ S
- //向客户端写入0 r1 X2 }) C9 J
- response.addCookie(cookie);
+ }7 K+ h8 c# D0 z - ' i* F7 K7 F4 r
- }1 {" Z# {8 E, o7 z! q
% ]% Z& F) i: K& [& D$ T- //读取Cookie,自动完成登陆操作--------------------------------------------------------------------------------------------# [( A: y ^. Z0 E
- & s$ k( u% D4 t/ D; V* a
- //在Filter程序中调用该方法,见AutoLogonFilter.java: |/ S* w; N, b; s, ]* R1 i1 [& g4 B
- public static void readCookieAndLogon(HttpServletRequest request, HttpServletResponse response, ! N* Q ^$ }6 J& O* O) I6 A
- FilterChain chain) throws IOException, ServletException,UnsupportedEncodingException{
4 s' H* Y- ~8 }' x8 r - //根据cookieName取cookieValue
7 u& @* a$ D& a. Q: E3 U0 ?: X - Cookie cookies[] = request.getCookies(); : t8 |4 C: c* t$ S/ T5 U
- String cookieValue = null;
3 z( b- h7 W+ E - if(cookies!=null){
; f+ s$ J! n4 |7 i1 s! ]5 V5 ^ - for(int i=0; i<cookies.length; i++){0 c$ I. Y! ?4 n6 t4 R% E) p
- if (cookieDomainName.equals(cookies[i].getName())) {
7 A% m9 y! W4 Y* S/ }2 ^9 T; D - cookieValue = cookies[i].getValue();
* t1 Y: _' I0 U/ d3 d1 a5 b - break;
8 m1 s1 ]" ]$ _6 O5 o" C - } j/ r! Q8 a/ V% ?) _! A
- }
) d$ k, Q# t8 W9 v \8 ~ - }6 K1 u1 ~: T# C, U$ g% Y. W
- ' G7 v* ]# w7 |, l
& t1 ^$ }% z" B- //如果cookieValue为空,返回,% }" [$ n6 `% A+ U
% x% b- l8 p' F B) }: z3 v- if(cookieValue==null){1 Y1 t. { z, s. s8 b
7 A, `2 U7 N, F; ~+ N2 S+ M1 {4 i- return;
4 x' M) \) c2 `" H3 z4 B0 k: C - 3 ?2 f: E+ \! p+ c- o* ?5 i T6 i
- }
' T: x0 {0 Q- i$ v) U9 z) G
- d! W! `' C. `% y. z7 ]8 ]1 d, N2 c. m- //如果cookieValue不为空,才执行下面的代码
/ S" X/ c2 J; B: R6 \/ l1 P3 Q - & a' C6 `" Y) v- [/ S$ K
- //先得到的CookieValue进行Base64解码: ~6 ~5 P5 E+ r* N2 w, U+ @+ }
- L ~' ?8 @ \) T
- String cookieValueAfterDecode = new String (Base64.decode(cookieValue),"utf-8");
! m9 E. B- u- V5 d
) D% q& I2 |, C1 e. ^- //对解码后的值进行分拆,得到一个数组,如果数组长度不为3,就是非法登陆3 U* H! F2 p2 P6 |
- String cookieValues[] = cookieValueAfterDecode.split(":");
: x7 Z6 |+ c- z1 y* b, ^ - if(cookieValues.length!=3){! ]' W0 f# \2 U7 q6 q& d ]
- response.setContentType("text/html; charset=utf-8"); ; Q0 i y* W7 `2 y% U, `0 W
- PrintWriter out = response.getWriter(); 3 v8 v9 h0 r# E
- out.println("你正在用非正常方式进入本站..."); 2 V1 X% a/ X4 x
- out.close();
. z' K+ U, B) K - return;
- I# b- f+ b& P7 O% u - }
8 v: E9 M" q$ m$ s5 t - //判断是否在有效期内,过期就删除Cookie( a% ?8 Z1 g2 Z
- long validTimeInCookie = new Long(cookieValues[1]);
: B7 s; ]3 [3 |, M* j/ d - if(validTimeInCookie < System.currentTimeMillis()){
: q# m/ O) V1 T/ c5 B+ i - //删除Cookie
$ I! ^5 P! Q3 L8 y+ K - clearCookie(response);
- \' j1 m" b e% C- C. H - response.setContentType("text/html; charset=utf-8"); , s& z/ F+ V. L: i( Y% R
- PrintWriter out = response.getWriter(); - { ^1 f& w; |! z9 Z
- out.println("<a href=’logon.jsp’>你的Cookie已经失效,请重新登陆</a>"); ) J% I" S. k% a) `8 x9 n
- out.close(); 8 [9 B6 S6 n+ f5 d" K% Q& G) V/ E
- return;
0 [; u9 V4 L. l) b/ b/ ~$ H( O - }: ~8 H. h Z+ w. I$ S9 T! H
2 b9 y( S6 C9 s/ o- //取出cookie中的用户名,并到数据库中检查这个用户名,, h' d) |* A! M* s$ N1 @' G
- String username = cookieValues[0];
( N7 j. }9 d$ ~ - //根据用户名到数据库中检查用户是否存在
3 g/ e) Q! c s4 d - UserDAO ud = DaoImplFactory.getInstance();% K- L2 r/ X1 N3 u% q1 n7 ~0 C
7 X9 L' z, G4 U5 e/ ?$ @# q' N# d- User user = ud.selectUserByUsername(username);1 t: q9 N$ W/ b* C
- ]- ^6 W* T$ p, h- //如果user返回不为空,就取出密码,使用用户名+密码+有效时间+ webSiteKey进行MD5加密
$ x0 G4 S) E" n/ o% Y) U+ k2 _/ E$ s - if(user!=null){4 z- P$ R2 S" k$ h
- String md5ValueInCookie = cookieValues[2]; % w7 h( D: v/ _- N( i
- String md5ValueFromUser =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTimeInCookie + ":" + webKey);
' L; W& E! V* a. v+ { - //将结果与Cookie中的MD5码相比较,如果相同,写入Session,自动登陆成功,并继续用户请求$ f; x# @# o+ F$ Q8 s/ e
- if(md5ValueFromUser.equals(md5ValueInCookie)){4 o# w' Y) k5 Y: p' p2 v1 d | w' c
- HttpSession session = request.getSession(true); # O7 L. |! @& c) _+ G7 K4 C
- session.setAttribute("user", user); / O" f) l( M; q; w' v
- chain.doFilter(request, response); 6 R9 U* A: y, Z5 U: y R( m/ S
- }0 u4 _+ R6 I: [& t6 |, j) A
- }else{
2 p- z1 k% H* V: O - //返回为空执行
! u+ z: D) P4 p* |+ S - response.setContentType("text/html; charset=utf-8");
+ U4 v+ Z' t0 R/ Y' Z6 x - PrintWriter out = response.getWriter(); 0 ^$ ?. x3 |9 L. q9 l$ t3 s4 y
- out.println("cookie验证错误!"); ( s7 Z5 T( O; g& I* m& Q
- out.close(); + `6 I$ R# H, e( [, o$ H. P2 M& V
- return;
$ V) j. v/ m4 ?2 \7 b; A - }
^" {& T1 a, V5 _ - }
7 X5 D1 } S" U# e; |( q - //用户注销时,清除Cookie,在需要时可随时调用------------------------------------------------------------
! C) e3 Z8 j: i( ~" v7 u: E - public static void clearCookie( HttpServletResponse response){
6 ]& k; J" d( H4 s0 q& Q - Cookie cookie = new Cookie(cookieDomainName, null); / @$ p2 r' w' R ^; k9 r; ~
- cookie.setMaxAge(0); ) |. O* E" L6 p0 v' g' _
- cookie.setPath("/");
% [$ p2 ]1 v6 |' g; H5 O - response.addCookie(cookie);
5 E/ C% C6 A. ^. D- L5 ]- @ - }
7 q: }1 ^; l0 ?* E$ U - //获取Cookie组合字符串的MD5码的字符串----------------------------------------------------------------------------1 d! ?( B% ^3 r7 i
- public static String getMD5(String value) {9 s' K7 W. ?9 K
- String result = null;
1 L# M3 M) [3 t! H f8 A - try{
3 C6 H( T. @4 Z - byte[] valueByte = value.getBytes(); . D( B/ R G0 T/ [- a) r, u! K: p
- MessageDigest md = MessageDigest.getInstance("MD5"); 8 I6 O0 U0 l7 d" i1 G7 y& S
- md.update(valueByte); 8 [' z/ [- @0 T& k: }# ? W
- result = toHex(md.digest());
4 W; u* f4 b" u! c P - } catch (NoSuchAlgorithmException e2){
4 s2 S: e2 E. ] - e1.printStackTrace(); ! Y z7 m& \# k- d6 e
- }5 h1 v7 ?) U, y* ?7 V3 k
- return result; : Q1 Q6 ]1 l+ S/ Y& B
- }3 m9 l: P6 }) `" j% M
- 0 q3 ?1 b. }: W" R) X
- //将传递进来的字节数组转换成十六进制的字符串形式并返回 W' ]( b" w9 c% Q) j2 U
5 p$ h$ q. C4 T# k* s" z2 Y- private static String toHex(byte[] buffer){
2 W, z/ H6 a! E- o/ \ - StringBuffer sb = new StringBuffer(buffer.length * 2); 0 w; o8 B6 w5 l+ A, `
- for (int i = 0; i < buffer.length; i++){
1 S; F7 n \9 Z7 z% @ - sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16)); ) E% i0 N6 b9 a" E. q
- sb.append(Character.forDigit(buffer[i] & 0x0f, 16)); ' r4 E% D1 V: x; m/ Z
- }0 G- G% z+ `5 V- G; `0 }7 i
- return sb.toString();
6 N' w) x$ H4 _7 |4 ^ - }
1 w: k0 A$ l$ D. v" Z - }
$ K) @' q7 z" w( S5 b$ I5 m$ L4 _
9 z E6 S) y* u3 C- 下面的是对CookieUtil工具类各方法的调用演示:
" @8 l1 o! f: [5 p# F# y7 H$ K, p - . X. p4 x8 O' z8 p
- User.java0 Y2 b( h$ {1 J& o7 g) z. [2 W
- # a& S) o& u: E, V+ W
- 封装用户信息的JavaBean对象模型: \: `' ?! u. M4 z A, l
- package com.itcast.bean;
8 ^3 P: u$ g: [% r+ _ - public class User {9 K' B; B. f# B
- private int id;
5 o' p; H# ?3 a( ]$ K- F; d0 K - private String userName;
W1 v# ]3 |/ x# p - private String password; . B/ {! k# K Z; }
- public String getPassword() {
+ K# n/ E, t& ?$ c: F# L - + k7 c) [1 m: |$ y" K+ j
- return password;
6 c) i6 V+ W% {6 m/ N - ! M7 _* ~6 S3 J( I2 H4 Q
- }
8 e& b D) ]# N5 {( ~ - public void setPassword(String password) {: l) Z$ q% I$ j2 j, Q7 e6 |
- & K* L o( q3 o" f' X
- this.password = password;
6 f) Z! B* s% q7 m
" i x9 F9 Y# q! j7 v2 p- }- `# O. D" g) L3 T" c2 g7 r
0 e- ]4 {( z# P7 F6 M- public String getUserName() {# }$ Z1 U; r: m9 z, E) p. @0 w
( A* m2 A) {+ M8 I; R8 R7 | k& c4 v- return userName;
; w! T2 P& Y+ ?. t4 B' E) c - 6 U' C' o& l; v) o
- }# x6 i E" G# D" y N) i
, u4 F1 n, w, _: e* f1 @- public void setUserName(String userName) {7 E% Y5 B/ R d5 `" g: g
- & z6 r6 K7 ^; \( A5 x
- this.userName = userName;
# D) e2 U; P2 {: ^. N0 a) _
/ z: C' O! G* ?2 Q* d4 b4 @- }
) O' s: C! h2 N
4 v1 g$ {& l" u$ E# \- public int getId() {( P2 ?" L! G( B+ F. N
( z' ~. L/ g! j9 N4 j- return id;7 o) x, ]- z& S* ]* |
- `" A' Y5 C. Q9 d% L8 E
- }
+ V, a C: G0 o3 g: j' S- N& N8 {
' T2 p$ p- p' G- public void setId(int id) {
) Z& c/ e9 s) o- o0 t6 I4 h
) `. m' u3 J7 x0 f2 E+ u+ k4 B- this.id = id;
9 J! p! z' v3 z- c* ]# E2 ^
* b* Q/ D7 ]: s+ W1 g: v1 ]- }% ~' g- }( ]& c/ \: ?
- 1 D/ P: R9 t! |' H# `" Y
- }
复制代码
7 Q0 q- n! Q* ?. WAutoLogonFilter.java P, n7 @2 y2 d! p( g& \
3 u) t$ r$ N ?& U* g
过滤器程序,可在WEB-INF/web.xml中设置过滤规则,本文对过滤规则不作介绍,此程序主要作用是检查用户在上一次登陆时是否保存了Cookie,如果保存了,就处理Cookie信息,并帮助用户自动登陆! m; q1 ?3 e& c9 R. ?2 V! Y! R
8 t/ `$ @, ~, F5 w( U0 U
% E+ [0 R s( r- c5 @
本程序主要调用了CookieUtil.java中的读取与自动登陆方法,即readCookieAndLogon方法
8 t* t6 D- [' v% U P/ Z: d- package cn.itcast.filter;
! Q& E; v/ M* C: `8 n - ) P8 \7 a4 ^( L& I) j$ S8 L
- import java.io.IOException;
. ^" H# s; G( N2 l+ H - import javax.servlet.Filter;
6 `* W# A5 _% J- U- v - import javax.servlet.FilterChain;
( t) u, h+ M4 P& l1 {# k - import javax.servlet.FilterConfig;
. W5 Z+ I) ]1 Z! G1 X2 y - import javax.servlet.ServletException; ) ?0 a& p$ G/ k) ^: a
- import javax.servlet.ServletRequest;
$ E4 a* i/ W, p/ j0 @. E" E - import javax.servlet.ServletResponse; & M, u' ?0 X4 {! X* c. S! B" a
- import javax.servlet.http.Cookie; * S; }, I# R( b3 v" U
- import javax.servlet.http.HttpServletRequest;
$ S j3 a! j {* X3 }& g3 `3 X - import javax.servlet.http.HttpServletResponse;
" E" V1 j: {( W7 R' f3 ^ - import javax.servlet.http.HttpSession; , z7 h. }$ \. J7 \ p
- import cn.itcast bean.User; 8 |/ W. a; ~2 @2 N' ~/ p8 R. A
- import cn.itcast.util.CookieUtil;
* R! q$ J% w6 z4 Z, C; w
! `, h$ h/ A4 z ?- public class AutoLogonFilter implements Filter {2 G( Y0 Q* G) c- J. ~! k( `
- ' [9 x1 x- t/ D. n# [. J% M! |7 p
- public void destroy() {
! n9 G ^$ I% R/ T+ N* l
6 X D( m! b' c5 l- }
( R0 P5 f' M: Z Q$ h2 e
! @, c( {1 `5 B2 K- //保存cookie时的cookieName,与CookieUtil.java中的设置相同* [5 q; e2 u3 t* t. D3 N
; I; o7 E! j q7 q5 L7 v$ u6 h- private final static String cookieDomainName = “cn.itcast”;" ]% Z" @+ G: z
. \1 s) ^) }. n! u- 0 r) b$ I1 o7 y) E
0 w4 D( S7 J- {- public void doFilter(ServletRequest req, ServletResponse resp,! A% c' A% z: B: ?; D$ w8 O: k/ `
- FilterChain chain) throws IOException, ServletException {
" l, x2 L7 @/ m5 h J - HttpServletRequest request = (HttpServletRequest)req;
! d) K' X1 Y3 q5 J5 F! c - HttpServletResponse response = (HttpServletResponse)resp; ( i L( Y. \" w1 E0 h: E
- HttpSession session = request.getSession(true); & r* @( A- l D( M
- User user = (User)session.getAttribute("user");0 i# Z7 R6 X* E$ u) ]
g2 ~" I) l- U. t
' { k' z( L! {9 k* k1 b* ]7 m- //如果封装的user不为空,说明已经登陆,则继续执行用户的请求.下面的就不处理了
* @0 U" P; V9 w! ~7 p
$ i; @4 z( s& K, d& O9 }- if(user!=null){* P! Q Z( z' N5 K8 C& C9 h# U3 s
- chain.doFilter(request,response);
: i6 R" j: G; L' s - return; 5 w {* b7 f# M# `# c
- }2 R. ~; E, {# N- S
4 o6 }# V- G. N- |: m3 Y5 n/ i, n+ q& l- //user为空,说明用户还没有登陆,就尝试得到浏览器传送过来的Cookie
7 s% x8 u% {$ c1 ^ - Cookie cookies[] = request.getCookies();
; o/ Y- @9 O$ X& i% i - String cookieValue = null;
- m( w, b( g5 T& N& j) [ - if(cookies!=null){
, ^# s: G2 x" i/ {: t4 y1 e* D- U - for(int i=0; i<cookies.length; i++){: h8 C: d& W. O4 b% x3 t3 j
- if (cookieDomainName.equals(cookies[i].getName())) {
! K# G- O P! U" T) C5 S. }* N+ ~ - cookieValue = cookies[i].getValue(); 0 i, V2 [2 @" K* H/ h% j
- break; . l! I% n4 c: T7 N7 R
- }4 w% k, ?, X' y8 K! N9 [
- }3 b- f. w* I$ L- l+ X. F) V6 |
- }
( }$ k7 b- a$ A( m6 R4 X3 p1 m. ] - ) R( f" k; @4 C
- 2 z: h% K2 N0 X3 z* s- d
- //如果cookieValue为空,也继续执行用户请求
5 }; K, O1 p- Q- f5 U - if(cookieValue==null){7 Y- u2 ]; u2 j$ E: y8 V- x0 Y
- chain.doFilter(request,response); ( Q' U! l. R; ^
- return; , |( P, g/ B" j( g8 G/ f3 }" N
- }
4 Q1 }, y2 C G2 }, c0 Z* M
6 h! N$ F6 l! Q- //cookieValue不为空执行下面的方法,调用CookieUtil.java中的readCookieAndLogon方法
m% b# Y6 E/ n% o, Y - try{' a# Z Z' A) U
- CookieUtil.readCookieAndLogon(cookieValue, request, response, chain); ( ~ E; p" t0 u- `
- }catch(Exception e){8 Z, }% }% ]$ ?2 r; o
- e.printStackTrace();
5 X0 d' @& X! Y. X% W% g9 O& D - }
3 N, @! Y A! F. U - }
0 p( ~# Q1 h8 B2 G6 q - + a) [: L) f# p+ G" G
- public void init(FilterConfig arg0) throws ServletException {
! v; W9 {) Q r - }
0 T" V. J/ v9 V6 F - }
复制代码
0 S- P5 r6 i- {, K5 s1 ?% A' qCheckLogonServlet.java
C) F5 }9 ^3 c5 ]8 }9 \3 A( l, Q4 f/ W. G
验证用户登陆信息的Servlet,此程序调用了CookieUtil.java中的saveCookie方法5 G7 K& r% o/ J5 H( ^% j% J
- N, R+ u6 S0 |; `
package cn.itcast.servlet;
0 E$ n# \5 ^" k- import java.io.IOException; # g8 [- Z' m* M; w$ B0 @
- import javax.servlet.ServletException; 7 _/ J* _( q* d- z
- import javax.servlet.http.HttpServlet;
& [+ {8 Z' ?3 l" k8 N2 a - import javax.servlet.http.HttpServletRequest;
5 K, i$ W) }* y6 l - import javax.servlet.http.HttpServletResponse;
# q$ j4 x6 z7 M+ s6 Y& F: Q - import javax.servlet.http.HttpSession;
: H/ J2 r: b" W7 _# `: u5 u - import cn.itcast.bean.User; 5 g% H. y0 b% V, x+ T
- import cn.itcast.dao.UserDAO;
/ _4 i0 b3 f$ Z* L$ y6 b - import cn.itcast.factory.DaoImplFactory;
( `! g+ ?0 F! {% g { - import cn.itcast.util.CookieUtil;" C) j* n7 T$ U) |( r8 U" }' H
- ! Q3 O! R& {; T5 I% t3 t- Q, }
- public class CheckLogonServlet extends HttpServlet {4 k+ B! Z- x4 J. \
- |/ l! v: M+ H
- public void doGet(HttpServletRequest request, HttpServletResponse response)
6 Q- j2 u3 W9 q1 @5 ~ - throws ServletException, IOException {) \7 \# s$ z% i5 E& N7 X& d L
- doPost(request, response); & P8 y! e4 f: r y# ^
- }
$ J" s0 h, W$ L
$ S" B9 C$ k* E$ J& Y7 U, k2 y. y# F- public void doPost(HttpServletRequest request, HttpServletResponse response)
" Y/ r/ _, w/ q. g - throws ServletException, IOException {8 p( J: ?$ J3 J+ S1 w! ~$ V. _
- request.setCharacterEncoding("utf-8"); # r& `% J; C6 X; L: H
- String username = request.getParameter("username").trim();
1 s3 Y! m6 F9 o( V7 s; Z* g0 _" [ - String password = CookieUtil.getMD5(request.getParameter("password"));
; S2 r! H v2 U, A9 l8 ?( H+ \ - String remeberMe = request.getParameter("remeberMe");
1 D; Z8 E, L0 J5 _ V - HttpSession session = request.getSession(false);. O% r# {: x! s, \4 R2 Z) S
- 8 z* a' s+ H5 i1 k5 a* x& n
- // 将接收到的用户名传递到UserDao的checkUser方法中,检查用户+ [) ~( ?& ]+ P
- // 返回一个User类型的对象0 e; A7 D, {7 P' V W& x) R2 d
- UserDAO ud = DaoImplFactory.getInstance();
1 I) s, V! K- h7 Q& l - User user = ud.selectUserByUsername(username);
0 e- f1 H6 k8 Z+ H: f- o$ E - if (user == null) {
) `, L* j) V8 L+ \0 } - request.setAttribute("checkUserError","<a href='register.jsp'><font color=red>用户名不存在,请先注册</font></a>"); % _2 Q f& z# U# } G
- request.getRequestDispatcher("index.jsp").forward(request, response); l9 a" }* {9 s1 a' ^
- return;
0 [) L, @# e8 U; l1 D( o - }" V* a. o- y0 N
- 2 P7 t& D, j4 e0 m8 a& ]) g
- if(!password.equals(user.getPassword())){) \0 F* j9 U# a+ m/ k2 {
- request.setAttribute("checkPasswordError","<font color=red>密码输入错误,请重新输入</font>"); ) j) S! Y; E* X: z7 U& v
- request.getRequestDispatcher("index.jsp").forward(request, response);
9 x/ \& b! }) X9 s. K% Y - return; % z. l* l5 k! X4 r
- }# e9 g3 I: E2 G* L% L' D; h+ L: j( `
- \. V. @1 B8 u/ H
- : d) F% X! p: R
- //保存Cookie,这里调用了CookieUtil.java中的saveCookie方法,将上面的user对象作为参数传递
h2 E* e* j% c - if ("on".equals(remeberMe)) {0 Z3 ~& D! @) ]' y) u: C1 k( G1 B- |
- CookieUtil.saveCookie(user, response);
! B( f* l2 k) H& m: ? - }
2 j2 D; d5 S+ _- k5 t - //在Session中保存用户信息,并转向用户的个人信息页面
- q% N1 M9 s0 V$ L F2 ] - session.setAttribute("user", user);
7 H5 c( X; v9 m+ n+ G' N' w - request.getRequestDispatcher("User/userInfo.jsp").forward(request,response); - @ Y# S. k7 M! w& I
- }% O% K. |1 u. b1 |9 Z9 P
- }
复制代码 % B: Y7 e0 S* d
UserDAO.java与DaoImplFactory.java属于持久层相关的程序,这里就不贴出来了,读者可根据自己需要选择不同的持久层框架,在本程序中只要实现查询用户的功能就可以了, H# h* A" `* C1 h2 L; R$ k
# V, {# o9 M% J8 X1 a+ z& c
; _ i% `) K; X* A+ n
|
|