1、spring自定义注解实现登陆拦截器
原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解。没有,放行;有,要进行验证。从而实现方法加注解就需要验证是否登陆。
2、自定义注解
package com.oy.filter;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; // can be used to method @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface IsLogin { }
3、登陆拦截器
package com.oy.filter; import java.text.MessageFormat; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import amberai.jweb.utils.UtilFunctions; public class LoginInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Cookie[] cs = request.getCookies(); if (cs != null && cs.length > 0 ) { for (Cookie c : cs) { UtilFunctions.log.info("==== LoginInterceptor#preHandle, cookie.key:{}, cookie.value:{} ====", c.getName(), c.getValue()); } } request.setAttribute("resourceBundle", Utils.getResourceBundle(request)); String sessionId = Utils.getSessionId(request); Integer uid = Utils.getUserId(request); String controllerName = Utils.getClassName(handler); String methodName = Utils.getMethodName(handler); String handlerTypeName = handler.getClass().getName(); // String language = Utils.getLanguage(request); // if url?l=zh-cn1, then language = en-us // if url?l=zh-cn1, then language = zh-cn1. String language = request.getParameter("l"); if (language == null) { language = Utils.getLanguageByCookie(request); } String logMsg = MessageFormat.format("sessionId:{0}, uid:{1}, controllerName:{2}, methodName:{3}, handlerTypeName:{4}, language:{5}", sessionId, uid, controllerName, methodName, handlerTypeName, language); UtilFunctions.log.info("LoginInterceptor#preHandle LoginInterceptor work, " + logMsg); long begin = System.currentTimeMillis(); // target of request is method of controller if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Object object = handlerMethod.getMethodAnnotation(IsLogin.class); if (object == null) { // method without @IsLogin annotation long time = System.currentTimeMillis() - begin; UtilFunctions.log.info("LoginInterceptor#preHandle over, method[{}] without annotation, takes time:{} ms, " + logMsg, methodName, time); return true; } else { // method with @IsLogin annotation if (uid == null) { // visitor response.setStatus(401); long time = System.currentTimeMillis() - begin; UtilFunctions.log.info("LoginInterceptor#preHandle over, visitor request intercepted, takes time:{} ms, " + logMsg, time); return false; } // user request.setAttribute("uid", uid); } } long time = System.currentTimeMillis() - begin; UtilFunctions.log.info("LoginInterceptor#preHandle over, user request ok, takes time:{} ms, " + logMsg, time); return true; } }
spring配置文件中注册拦截器
<mvc:interceptors>
<bean class="com.oy.filter.LoginInterceptor" />
</mvc:interceptors>
4、Utils类
package com.oy.filter; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.springframework.web.method.HandlerMethod; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.mysql.jdbc.StringUtils; import amberai.jweb.utils.Config; import amberai.jweb.utils.RedisAccess; import amberai.jweb.utils.UtilFunctions; import redis.clients.jedis.Jedis; public class Utils { public static String getSessionId(HttpServletRequest request) { String sessionId = null; if (request == null) { return sessionId; } Cookie[] cookies = request.getCookies(); if (cookies == null || cookies.length == 0) { return sessionId; } for (Cookie cookie : cookies) { if ("PHPSESSID".equalsIgnoreCase(cookie.getName())) { sessionId = cookie.getValue(); } } return sessionId; } public static Integer getUserId(String sessionId) { Integer uid = null; if (null == sessionId) { return uid; } JSONObject userInfo = Utils.getUserInfoFromRedis(sessionId); if (null == userInfo || userInfo.getIntValue("userId") <= 0) { return uid; } uid = userInfo.getIntValue("userId"); return uid; } public static Integer getUserId(HttpServletRequest request) { Integer uid = null; if (null == request) { return uid; } String sessionId = getSessionId(request); if (sessionId == null) { return uid; } JSONObject userInfo = Utils.getUserInfoFromRedis(sessionId); if (null == userInfo || userInfo.getIntValue("userId") <= 0) { return uid; } uid = userInfo.getIntValue("userId"); return uid; } public static JSONObject getUserInfoFromRedis(String sessionId) { if (sessionId == null) { return null; } UtilFunctions.log.debug("checkLogin, sessionId:{}", sessionId); Jedis redisClient = null; try { redisClient = RedisAccess.getRedisClient(); String userInfo = redisClient.get("sess_" + sessionId); UtilFunctions.log.debug("checkLogin, userInfo:{}", userInfo); if (null == userInfo) { return null; } JSONObject jsonObj = null; try { jsonObj = JSONObject.parseObject(userInfo); } catch (JSONException e) { String errMsg = MessageFormat.format("can not cast to JSONObject. sessionId:{0}, userInfo:{1}", sessionId, userInfo); UtilFunctions.log.info(errMsg); UtilFunctions.reportError(errMsg, e); } return jsonObj; } finally { if (null != redisClient) { redisClient.close(); } } } public static String getMethodName(Object handler) { if (null == handler) { return ""; } if (HandlerMethod.class.equals(handler.getClass())) { HandlerMethod method = (HandlerMethod) handler; return method.getMethod().getName(); } return ""; } public static String getClassName(Object handler) { if (null == handler) { return ""; } if (HandlerMethod.class.equals(handler.getClass())) { // get controller HandlerMethod method = (HandlerMethod) handler; Object controller = method.getBean(); String className = controller.getClass().getName(); int idx = className.lastIndexOf("."); if (idx >= 0 && (idx + 1) < className.length()) { return className.substring(idx + 1); } return className; } return ""; } public static String getRemoteIp(HttpServletRequest request) { if (null == request) { return ""; } String ip = request.getHeader("x-forwarded-for"); if (StringUtils.isNullOrEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isNullOrEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isNullOrEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } public static String getLanguage(HttpServletRequest request) { String language = ""; if (request == null) return language; // priority: url?l=en-us > Cookie:language=zh-cn language = request.getParameter("l"); if (language == null || Config.LANGUAGECONFIG.get(language.toLowerCase()) == null) { language = Utils.getLanguageByCookie(request); } if (language == null || Config.LANGUAGECONFIG.get(language.toLowerCase()) == null) { language = "en-us"; // default "en-us" } return language; } public static String getLanguageByCookie(HttpServletRequest request) { String language = ""; if (request == null) return language; Cookie[] cookies = request.getCookies(); if (cookies == null || cookies.length == 0) { return language; } for (Cookie cookie : cookies) { if ("language".equalsIgnoreCase(cookie.getName())) { language = cookie.getValue(); } } return language; } public static ResourceBundle getResourceBundle(HttpServletRequest request) { String language = Utils.getLanguage(request); String[] languages = language.split("-"); Locale locale = null; if (languages.length >= 2) { locale = new Locale(language.split("-")[0], language.split("-")[1]); } else if (languages.length == 1) { locale = new Locale(language.split("-")[0], "ES"); } return ResourceBundle.getBundle("i18n/MessgesBundle", locale); } public static void setSessionAttrToRedis(String sessionId, String jsonStr) { Jedis redisClient = null; try { redisClient = RedisAccess.getRedisClient(); redisClient.set("sess_" + sessionId, jsonStr); redisClient.expire("sess_" + sessionId, 3600); } finally { if (null != redisClient) { redisClient.close(); } } } }
5、使用@IsLogin
@IsLogin @RequestMapping(value = "/xxx/xxx", method = RequestMethod.POST) @ResponseBody public JSONObject setPayPassword(HttpServletRequest request, @RequestParam(value = "xxx", required = true) String xxx, @RequestParam(value = "xxx", required = true) String xxx) { Integer userId = (Integer) request.getAttribute("uid"); ResourceBundle resourceBundle = (ResourceBundle) request.getAttribute("resourceBundle");
... }