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