在我們的網(wǎng)站平臺(tái)上,主要有兩類頁面,,一類是非登錄也能查看的頁面,,另一類是登錄后才能查看的頁面
通過使用 spring攔截器來實(shí)現(xiàn),,當(dāng)用戶沒有登錄時(shí)訪問需要登錄的頁面時(shí)自動(dòng)實(shí)現(xiàn)跳轉(zhuǎn)至登錄頁 1,、添加接口用于攔截器與控制器交互數(shù)據(jù)(包括上下文與登錄賬號(hào)信息)
View
Code IWebContext
/**
* 用于實(shí)現(xiàn)上下文連接 用于在過濾器中實(shí)現(xiàn)注入Request與Response * @author Administrator * */ public interface IWebContext { /** * 設(shè)置請(qǐng)求與應(yīng)答上下文 * @param request 請(qǐng)求 * @param response 應(yīng)答 * @param userType 用戶類型 * @param loginUrl 登錄頁面的URL */ public void setWebContext(HttpServletRequest request, HttpServletResponse response, UserTypeEnum userType, String loginUrl); /** * 獲取登錄賬號(hào) * @return 返回當(dāng)前的登錄賬號(hào),如果沒有登錄則返回空 */ public LoginAccount getLoginAccount(); }
2,、所有的Controller都繼承自BaseController
View
Code BaseController
@Controller
public class BaseController implements IWebContext { private static final Logger log = Logger.getLogger(BaseController.class); /*********************獲取Request與Response*******************/ /** * 請(qǐng)求上下文 */ private HttpServletRequest request; /** * 應(yīng)答上下文 */ private HttpServletResponse response; /** * 校驗(yàn)當(dāng)前登錄用戶的用戶類型 */ private UserTypeEnum userType; /** * 登錄的頁面 當(dāng)訪問需要登錄的頁面時(shí),,自動(dòng)轉(zhuǎn)到該頁面 */ private String loginUrl; /** * 設(shè)置請(qǐng)求與應(yīng)答的上下文 */ @Override public void setWebContext(HttpServletRequest request, HttpServletResponse response, UserTypeEnum userType, String loginUrl){ this.request = request; this.response = response; this.userType = userType; this.loginUrl = loginUrl; //重置當(dāng)前訪問的數(shù)據(jù) this.loginAccount = null; this.remoteIp = null; } /** * 當(dāng)前的請(qǐng)求對(duì)象 * @return */ protected HttpServletRequest getRequest(){ //((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); return this.request; } /** * 獲取當(dāng)前的應(yīng)答對(duì)象 * @return */ protected HttpServletResponse getResponse(){ return this.response; } /*********************獲取Request與Response*******************/ /*********************用戶登錄相關(guān)*******************/ /** * 當(dāng)前登錄的賬號(hào) */ private LoginAccount loginAccount = null; /** * 該對(duì)象在調(diào)用isLogged方法后才有效 * @return */ @Override public LoginAccount getLoginAccount(){ if (this.loginAccount == null){ this.loginAccount = new LoginAccount(); if (!this.getCookieObject(LoginAccount.USERCOOKINAME, this.loginAccount)){ this.loginAccount = null; return null; } if (!UserLoginBLL.verifyToken(this.loginAccount, this.userType)){//校驗(yàn)令牌 this.loginAccount = null; return null; } } return this.loginAccount; } /** * 判斷用戶是否已經(jīng)登錄 * @return */ protected boolean isLogged(){ return this.getLoginAccount() != null; } /** * 跳轉(zhuǎn)到登錄頁面 * @return */ protected ModelAndView toLoginView(){ return new ModelAndView(new RedirectView(this.loginUrl), "tourl", this.getRequest().getRequestURI()); } /*********************用戶登錄相關(guān)*******************/ /*********************獲取訪問IP*******************/ /** * 獲取遠(yuǎn)程訪問IP */ private String remoteIp = null; /** * 獲取遠(yuǎn)程訪問IP * @return */ protected String getRemoteIp(){ HttpServletRequest request = this.getRequest(); if (this.remoteIp==null || this.remoteIp.length()==0) { this.remoteIp = request.getHeader("x-forwarded-for"); if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getHeader("X-Real-IP"); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getHeader("Proxy-Client-IP"); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getHeader("WL-Proxy-Client-IP"); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getHeader("HTTP_CLIENT_IP"); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getHeader("HTTP_X_FORWARDED_FOR"); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getRemoteAddr(); } if (this.remoteIp == null || this.remoteIp.isEmpty() || "unknown".equalsIgnoreCase(this.remoteIp)) { this.remoteIp= request.getRemoteHost(); } } return remoteIp; } /*********************獲取訪問IP*******************/ /*********************獲取訪問參數(shù)*******************/ /** * 獲取所有參數(shù) * @return */ protected Map<String,String[]> getParams(){ HttpServletRequest request = this.getRequest(); return request.getParameterMap(); } /** * 獲取指定的配置 * @param name * @return */ protected String getParam(String name){ return getParam(name, ""); } /** * 根據(jù)參數(shù)名稱獲取參數(shù)值,,如果沒有找到則以默認(rèn)值返回 * @param name * @param defaultValue * @return */ protected String getParam(String name, String defaultValue){ HttpServletRequest request = this.getRequest(); String strValue = request.getParameter(name); return strValue == null ? defaultValue : strValue; } /** * 獲取整形的參數(shù)值 * @param name * @param defaultValue * @return */ protected int getIntParam(String name){ return getParam(name, 0); } /** * 獲取整形的參數(shù)值 * @param name * @param defaultValue * @return */ protected int getParam(String name, Integer defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Integer.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取長(zhǎng)整形的參數(shù)值 * @param name * @param defaultValue * @return */ protected long getLongParam(String name){ return getParam(name, 0L); } /** * 獲取長(zhǎng)整形的參數(shù)值 * @param name * @param defaultValue * @return */ protected long getParam(String name, Long defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Long.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取單精度的參數(shù)值 * @param name * @param defaultValue * @return */ protected float getFloatParam(String name){ return getParam(name, 0F); } /** * 獲取單精度的參數(shù)值 * @param name * @param defaultValue * @return */ protected float getParam(String name, Float defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Float.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取雙精度的參數(shù)值 * @param name * @param defaultValue * @return */ protected double getDoubleParam(String name){ return getParam(name, 0D); } /** * 獲取雙精度的參數(shù)值 * @param name * @param defaultValue * @return */ protected double getParam(String name, Double defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Double.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取字節(jié)的參數(shù)值 * @param name * @param defaultValue * @return */ protected byte getByteParam(String name){ return getParam(name, (byte)0); } /** * 獲取字節(jié)的參數(shù)值 * @param name * @param defaultValue * @return */ protected byte getParam(String name, Byte defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Byte.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取字節(jié)的參數(shù)值 * @param name * @param defaultValue * @return */ protected short getShortParam(String name){ return getParam(name, (short)0); } /** * 獲取字節(jié)的參數(shù)值 * @param name * @param defaultValue * @return */ protected short getParam(String name, Short defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Short.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取布爾的參數(shù)值 * @param name * @param defaultValue * @return */ protected boolean getBooleanParam(String name){ return getParam(name, false); } /** * 獲取布爾的參數(shù)值 * @param name * @param defaultValue * @return */ protected boolean getParam(String name, Boolean defaultValue){ String strValue = getParam(name, defaultValue.toString()); try{ return Boolean.valueOf(strValue); } catch(Exception e){ return defaultValue; } } /** * 獲取日期的參數(shù)值 * @param name * @param defaultValue * @return */ protected Date getDateParam(String name){ return getParam(name, new Date()); } /** * 獲取日期的參數(shù)值 * @param name * @param defaultValue * @return */ protected Date getParam(String name, Date defaultValue){ String strValue = getParam(name); if (strValue == null || strValue.length() == 0) return defaultValue; try{ return DateUtil.getDateFromString(strValue); } catch(Exception e){ return defaultValue; } } /*********************獲取訪問參數(shù)*******************/ /*******************操作Cookie********************/ /** * 獲取指定鍵的Cookie * @param cookieName * @return 如果找到Cookie則返回 否則返回null */ protected Cookie getCookie(String cookieName){ if (StringUtil.isNullOrWhiteSpace(cookieName) || this.getRequest().getCookies() == null) return null; for(Cookie cookie : this.getRequest().getCookies()){ if (cookieName.equals(cookie.getName())) return cookie; } return null; } /** * 獲取指定鍵的Cookie值 * @param cookieName * @return 如果找到Cookie則返回 否則返回null */ protected String getCookieValue(String cookieName){ Cookie cookie = this.getCookie(cookieName); return cookie == null ? null : cookie.getValue(); } /** * 刪除指定的Cookie * @param cookieName */ protected void removeCookie(String cookieName){ HttpServletResponse response = this.getResponse(); Cookie cookie = new Cookie(cookieName, null); cookie.setMaxAge(0); response.addCookie(cookie); } /** * 保存一個(gè)對(duì)象到Cookie里 Cookie只在會(huì)話內(nèi)有效 * @param cookieName * @param inst */ protected void setCookie(String cookieName, Object inst){ this.setCookie(cookieName, "/", inst); } /** * 保存一個(gè)對(duì)象到Cookie Cookie只在會(huì)話內(nèi)有效 * @param cookieName * @param path * @param inst */ protected void setCookie(String cookieName, String path, Object inst){ if (StringUtil.isNullOrWhiteSpace(cookieName) || inst == null) return; String strCookieString = this.object2CookieString(inst); this.setCookie(cookieName, path, strCookieString); } /** * 保存一個(gè)對(duì)象到Cookie * @param cookieName * @param inst * @param expiry (秒)設(shè)置Cookie的有效時(shí)長(zhǎng),, 負(fù)數(shù)不保存,,0刪除該Cookie */ protected void setCookie(String cookieName, Object inst, int expiry){ this.setCookie(cookieName, "/", inst, expiry); } /** * 保存一個(gè)對(duì)象到Cookie * @param cookieName * @param path * @param inst * @param expiry (秒)設(shè)置Cookie的有效時(shí)長(zhǎng), 負(fù)數(shù)不保存,,0刪除該Cookie */ protected void setCookie(String cookieName, String path, Object inst, int expiry){ if (StringUtil.isNullOrWhiteSpace(cookieName) || inst == null || expiry < 0) return; String strCookieString = this.object2CookieString(inst); this.setCookie(cookieName, path, strCookieString, expiry); } /** * 保存一個(gè)對(duì)象到Cookie里 Cookie只在會(huì)話內(nèi)有效 * @param cookieName * @param cookieValue */ protected void setCookie(String cookieName, String cookieValue){ this.setCookie(cookieName, "/", cookieValue); } /** * 保存一個(gè)對(duì)象到Cookie Cookie只在會(huì)話內(nèi)有效 * @param cookieName * @param path * @param cookieValue */ protected void setCookie(String cookieName, String path, String cookieValue){ HttpServletResponse response = this.getResponse(); if (StringUtil.isNullOrWhiteSpace(cookieName) || cookieValue == null) return; Cookie cookie = new Cookie(cookieName, cookieValue); if (!StringUtil.isNullOrWhiteSpace(path)){ cookie.setPath(path); } response.addCookie(cookie); } /** * 保存一個(gè)對(duì)象到Cookie * @param cookieName * @param cookieValue * @param expiry (秒)設(shè)置Cookie的有效時(shí)長(zhǎng),, 負(fù)數(shù)不保存,0刪除該Cookie */ protected void setCookie(String cookieName, String cookieValue, int expiry){ this.setCookie(cookieName, "/", cookieValue, expiry); } /** * 保存一個(gè)對(duì)象到Cookie * @param cookieName * @param path * @param cookieValue * @param expiry (秒)設(shè)置Cookie的有效時(shí)長(zhǎng),, 負(fù)數(shù)不保存,0刪除該Cookie */ protected void setCookie(String cookieName, String path, String cookieValue, int expiry){ if (StringUtil.isNullOrWhiteSpace(cookieName) || cookieValue == null || expiry < 0) return; HttpServletResponse response = this.getResponse(); if (StringUtil.isNullOrWhiteSpace(cookieName) || cookieValue == null) return; Cookie cookie = new Cookie(cookieName, cookieValue); if (!StringUtil.isNullOrWhiteSpace(path)){ cookie.setPath(path); } cookie.setMaxAge(expiry); response.addCookie(cookie); } /** * 把對(duì)象轉(zhuǎn)換為Cookie存貯字串 * @param inst * @return */ private String object2CookieString(Object inst){ if (inst == null) return ""; StringBuilder strCookieValue = new StringBuilder(); for(java.lang.reflect.Field field : inst.getClass().getDeclaredFields()){ try{ if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || java.lang.reflect.Modifier.isFinal(field.getModifiers())){ continue; } if (!this.isSimpleProperty(field.getType())) continue;//不是元數(shù)據(jù) field.setAccessible(true);// 提升權(quán)限 Object objValue = field.get(inst); String strValue; if (field.getType().equals(Date.class)){ strValue = DateUtil.getLongStrFromDate((Date)objValue); }else{ strValue = objValue == null ? "" : objValue.toString(); } if (strCookieValue.length() > 0){ strCookieValue.append(String.format("&%s=%s", field.getName(), URLEncoder.encode(strValue,"UTF-8"))); } else{ strCookieValue.append(String.format("%s=%s", field.getName(), URLEncoder.encode(strValue,"UTF-8"))); } } catch(Exception e){ log.fatal("object2CookieString faild", e); continue; } } return strCookieValue.toString(); } /** * 從Cookie中獲對(duì)對(duì)象 * @param cookieName * @param inst * @return 如果獲取轉(zhuǎn)換成功,,則返回true, 否則返回false */ protected boolean getCookieObject(String cookieName, Object inst){ if (inst == null){ return false; } String cookieValue = this.getCookieValue(cookieName); if (cookieValue == null){ return false; } for(java.lang.reflect.Field field : inst.getClass().getDeclaredFields()){ try{ if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || java.lang.reflect.Modifier.isFinal(field.getModifiers())){ continue; } if (!this.isSimpleProperty(field.getType())) continue;//不是元數(shù)據(jù) field.setAccessible(true);// 提升權(quán)限 Pattern pattern = Pattern.compile(String.format("(^|&)%s=([^(&|$)]+)", field.getName())); Matcher matcher = pattern.matcher(cookieValue); String strValue = ""; if (matcher.find()){ strValue = matcher.group(2); strValue = URLDecoder.decode(strValue, "UTF-8"); } field.set(inst, ConvertUtil.convertSimpleValue(field.getType(), strValue)); } catch(Exception e){ log.fatal("getCookieObject faild", e); return false; } } return true; } /** * 是否是簡(jiǎn)單的數(shù)據(jù)類型 * @param type * @return */ private boolean isSimpleProperty(Class<?> propType){ if (!propType.isPrimitive() && !propType.isEnum() && (!propType.equals(String.class) && !propType.equals(Date.class))) { return false; } return true; } /*******************操作Cookie********************/ }
3,、編寫攔截器
View
Code LoggedInterceptor
/**
* 已經(jīng)登錄攔截器 * @author Administrator * */ public class LoggedInterceptor extends HandlerInterceptorAdapter { /** * 登錄頁面的URL */ private UserTypeEnum userType = UserTypeEnum.Personal; /** * 登錄的頁面URL 當(dāng)未登錄訪問已登錄的頁面時(shí),自動(dòng)跳轉(zhuǎn)到該頁面 * @param loginUrl */ public void setUserType(UserTypeEnum userType){ this.userType = userType; } /** * 登錄頁面的URL */ private String loginUrl; /** * 登錄的頁面URL 當(dāng)未登錄訪問已登錄的頁面時(shí),,自動(dòng)跳轉(zhuǎn)到該頁面 * @param loginUrl */ public void setLoginUrl(String loginUrl){ this.loginUrl = loginUrl; } /** * 利用正則映射到需要攔截的路徑 */ private String[] regexUrls; /** * 利用正則映射到需要攔截的路徑 * @param mappingURL */ public void setRegexUrls(String[] regexUrls) { this.regexUrls = regexUrls; } /** * 在Controller方法前進(jìn)行攔截 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //如果handler controller實(shí)現(xiàn)了接口,,則設(shè)置上下文 LoginAccount loginAccount = null; if (handler != null && handler instanceof IWebContext){ ((IWebContext)handler).setWebContext(request, response, userType, this.loginUrl); loginAccount = ((IWebContext)handler).getLoginAccount(); } String strUrl = request.getRequestURI(); if (loginAccount == null && !StringUtil.isNullOrEmpty(strUrl) && regexUrls != null && regexUrls.length >0){ for(String regex : regexUrls){ if (StringUtil.isNullOrEmpty(regex)){ continue; } if (strUrl.matches(regex)){ //當(dāng)前頁面需要登錄 String strToUrl = "/login.htm?tourl=" + URLEncoder.encode(strUrl, "utf-8"); if ("GET".equalsIgnoreCase(request.getMethod())){ response.sendRedirect(strToUrl);//轉(zhuǎn)到登錄頁 }else{ //Json返回?cái)?shù)據(jù) JsonResponse jsonResponse = new JsonResponse(); jsonResponse.setFaildMsg(JsonResponse.Nologin, "請(qǐng)登錄后操作", strToUrl); Gson gson = null; PrintWriter printWriter = null; try{ gson = new Gson(); String strJson = gson.toJson(jsonResponse); response.setContentType("application/json"); printWriter = response.getWriter(); printWriter.print(strJson); printWriter.flush(); } finally{ if (printWriter != null){ printWriter.close(); } gson = null; } } return false; } } } return true; } /** * This implementation is empty. */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (handler != null && handler instanceof IWebContext && modelAndView != null && "GET".equalsIgnoreCase(request.getMethod())){ //當(dāng)get的時(shí)候,系統(tǒng)自動(dòng)封閉loginAccount到modelAndView里 modelAndView.addObject("loginAccount", ((IWebContext)handler).getLoginAccount()); } } /** * 在Controller方法后進(jìn)行攔截 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
4,、修改配置文件
View
Code SpringMvc-servelet.xml
<!-- 以下正則符合的頁面必須登錄后才能訪問 --> <bean id="loggedInterceptor" class="com.zufangbao.web.base.LoggedInterceptor"> <!-- 用戶類型 注入 --> <property name="userType"> <bean class="com.zufangbao.enums.UserTypeEnum" factory-method="fromValue"> <constructor-arg> <value>1</value> </constructor-arg> </bean> </property> <!-- 登錄頁面 --> <property name="loginUrl" value="login.htm"/> <!-- 必須登錄后才能訪問的頁面 --> <property name="regexUrls"> <list> <value>/rentlist.*</value> <value>/rentdetail.*</value> <value>/getrentpagelist.*</value> <value>/cancelrentrecord.*</value> </list> </property> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <ref bean="loggedInterceptor"/> </list> </property> </bean> <!-- Json支持 --> <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jacksonMessageConverter"/> </list> </property> </bean> |
|