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