SpringMVC 使用注解完成登录拦截

来源:互联网 发布:直销软件定制 编辑:程序博客网 时间:2024/06/06 00:29

  • 为了实现用户登录拦截你是否写过如下代码呢
    • 基于Filter
    • 基于Struts
    • 基于SpringMVC
  • 如何使用自定义注解完成自定义拦截呢
    • 登录注解
    • SpringMVC 拦截器设置
    • 最终 controller 写法
      • 不需要登录权限的
      • 整个 controller 内都需要登录权限
      • controller 某个方法需要登录权限

为了实现用户登录拦截你是否写过如下代码呢?

1. 基于Filter

import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;public class AuthenticationFilter implements Filter {    private FilterConfig filterConfig;    private String onErrorUrl;    public void init(FilterConfig filterConfig) throws ServletException {        // 从 filterConfig 中的得到错误页        this.filterConfig = filterConfig;        this.onErrorUrl = filterConfig.getInitParameter("onError");        if(this.onErrorUrl == null || "".equals(this.onErrorUrl))            this.onErrorUrl = "onError";    }    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest httpRequest = (HttpServletRequest)request;        session = httpRequest.getSession();        if(null == session.getAttribute("_LOGIN_USER_") && !"/login".equals(httpRequest.getServletPath())) {            httpRequest.getRequestDispatcher("/"+this.onErrorUrl).forward(request, response);        }else{            chain.doFilter(request, response);        }    }    public void destroy() {    }}

2. 基于Struts

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;@SuppressWarnings("serial")public class LoginInterceptor extends AbstractInterceptor {    @Override    public String intercept(ActionInvocation invocation) throws Exception {        String currentUser="currentUser";        HttpServletRequest request=ServletActionContext.getRequest();        HttpServletResponse response=ServletActionContext.getResponse();        HttpSession session=request.getSession();                           if(request.getRequestURI().endsWith("login.action")){            return invocation.invoke();        } else {              if(session.getAttribute(currentUser)!=null){                return  invocation.invoke();              }else{                 response.sendRedirect(request.getContextPath()+"/login.jsp");              }        }        return null;    }}

3. 基于SpringMVC

import javax.servlet.RequestDispatcher;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import cn.edu.hdc.util.Constants;/** * @ClassName: LoginInterceptor  * @Description: 登录拦截器 * @author loweir hbloweir@163.com * @date 2016年4月27日 上午8:06:11  */public class LoginInterceptor implements HandlerInterceptor {    /**     * 在目标方法前被调用,返回 true 继续      */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {        try {            String url = request.getRequestURI();            // 如果不是登录操作 判断 session            if (!url.endsWith("login")) {                if (request.getSession().getAttribute(Constants.CURRENT_USER) == null) {                    response.sendRedirect(request.getContextPath() + "/login.jsp");                    return false;                }               }           }             return true;        } catch (Exception e) {            e.printStackTrace();            return false;        }    }    @Override    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)            throws Exception {    }    @Override    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)            throws Exception {    }}

如何使用自定义注解完成自定义拦截呢?

登录注解

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by loweir on 2017/5/14 17:19 * <p> * author: 张瑀楠 * email: hbloweir@163.com * 负责登录拦截 */@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.METHOD})public @interface WebLoginRequired {    String value() default ""; // 未登录时需要跳转的路径}

SpringMVC 拦截器设置

import com.ainsoft.globalshoperp.component.constant.WebLogin;import org.apache.commons.lang3.StringUtils;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Created by loweir on 2017/5/14 17:14 * <p> * author: 张瑀楠 * email: hbloweir@163.com */public class LoginInterceptor implements HandlerInterceptor {    private static Log logger = LogFactory.getLog(LoginInterceptor.class);    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {        if (logger.isDebugEnabled()) {            logger.debug("拦截器启动");        }        /*         * 判断是否为 HandlerMethod.class        * 如果不是说明当前请求并不是 SpringMVC 管理,        * 如果不是再自行根据业务做响应操作,这里直接返回 true        */        if (HandlerMethod.class.isInstance(handler)) {            HandlerMethod handlerMethod = (HandlerMethod) handler;            // 判断该 handler 是否有WebLoginRequired注解            WebLoginRequired webLoginRequired = handlerMethod.getMethod().getDeclaredAnnotation(WebLoginRequired.class);            // 如果该 handler 没有WebLoginRequired注解,判断所属Controller 是否包含注解            if (null == webLoginRequired) {                webLoginRequired = handlerMethod.getBeanType().getAnnotation(WebLoginRequired.class);            }            // 如果需要 WebLoginRequired 判断 session            if (null != webLoginRequired) {                if (httpServletRequest.getSession().getAttribute(WebLogin.CURRENTUSER) == null) {                    String executeURL = webLoginRequired.value();                    if (StringUtils.isBlank(executeURL)) {                        executeURL = WebLogin.LOGIN;                    }                 httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + executeURL);                    return false;                }            }        }        return true;    }    public void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {        if (logger.isDebugEnabled()) {            logger.debug("postHandler");        }    }    public void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {        if (logger.isDebugEnabled()) {            logger.debug("afterCompletion");        }    }}

最终 controller 写法

1. 不需要登录权限的

类和方法都不需要注解

@Controller@RequestMapping("auth")public class AuthController {    @RequestMapping("login")    public String login() {        return "login";    }}

2. 整个 controller 内都需要登录权限

在类上添加注解即可

@Controller@WebLoginRequired@RequestMapping("order")public class OrderController {    @RequestMapping("index")    public String index() {        return "index";    }}

3. controller 某个方法需要登录权限

只在需要登录权限的方法上添加注解
在注解上可以指定需要重定向的链接
如果不指定则默认到 login

@Controller@RequestMapping("order")public class OrderController {    @RequestMapping("index")    public String index() {        return "index";    }    // 需要登录    @WebLoginRequired    @RequestMapping("add")    public String index() {        return "index";    }    // 需要登录,如果未登录跳到 error    @WebLoginRequired("error")    @RequestMapping("delete")    public String index() {        return "index";    }}