Spring MVC redirect user to login page once session is expired

北战南征 提交于 2019-12-13 14:39:08

问题


I have stored a user bean in session as @SessionAttributes({"UserBean"}) in my controller.

My aim is to redirect user to login/error page if session is expired. Following is my code snippet

@RequestMapping(value = "searchOpportunity.htm", method = RequestMethod.GET)
public ModelAndView searchOpportunity(@ModelAttribute("UserBean") UserBean userBean) {
    functionName = "searchOpportunity";
    logger.info("HERE !!! In " + className + " - " + functionName + " ");
    System.out.println("HERE !!! In " + className + " - " + functionName + " ");
    try {
        if (userBean == null) {
            System.out.println(userBean);
            return new ModelAndView("userLogout", "command", null);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new ModelAndView("opportunity/opportunitySearch", "command", new SearchOpportunityBean());
}

However when the session is expired i get the following error.

org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet mintDispatcher threw exception
org.springframework.web.HttpSessionRequiredException: Session attribute 'UserBean' required - not found in session
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseSessionRequiredException(AnnotationMethodHandlerAdapter.java:761)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java:758)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:356)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Unknown Source)

Seems like the controller code is never executed if userbean is expired. What is the reason ? What can be a solution ?


回答1:


Why don't you try this with Spring Security?

<sec:session-management invalid-session-url="/login">
        <sec:concurrency-control expired-url="/login" />
</sec:session-management>

This will redirect to /login page when the user's session is expired or invalid.

Ref: http://docs.spring.io/spring-security/site/docs/3.0.x/reference/springsecurity.html




回答2:


You can do it by the help of HandlerInterceptorAdapter. The preHandle() method should return true if the execution chain should proceed with the next interceptor or the handler( your controller) itself. Else, DispatcherServlet assumes that this interceptor has already dealt with the response itself.

    public class YourInterceptor extends HandlerInterceptorAdapter {
        public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
            UserBean userBean = (UserBean) WebUtils.getSessionAttribute(request, "UserBean");
            if(userBean == null){
                //whatever you want to do
                return throw new ModelAndViewDefiningException(new ModelAndView("userLogout", "command", null));
            }else{
                return true;
            }
        }
    }

and specify this interceptor in your handler mapping definitions as:

    <bean id="yourInterceptor" class="package.YourInterceptor"/>
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="order" value="1" />
            <property name="interceptors">
                <list>
                    <ref bean="yourInterceptor" />
                </list>
            </property>
            <property name="mappings">
                <props>
                    <prop key="/searchOpportunity.htm">YourController</prop>    
                </props>
            </property>
        </bean>


来源:https://stackoverflow.com/questions/23195795/spring-mvc-redirect-user-to-login-page-once-session-is-expired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!