Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use RedirectAttributes or FlashMap in Interceptor of Spring MVC

I have an interceptor to handle the user session. If the user attribute does not exist, then the interceptor will redirect to the signin page. I want to send a session timeout message with the redirect url, but I don't want the message in the url. I google a lot for the RedirectAttributes or FlashMap, but I can't find any good solution.

public class UserSessionInterceptor extends HandlerInterceptorAdapter {
        protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = (User)request.getSession().getAttribute(CommonConstants.USER_SESSION_KEY);
        if (user == null) {
            String msg = String.format("session timeout");
            logger.error(msg);

    //      response.sendRedirect("/signin?errorMessage=" + msg); //I don't want to do this..

            return false;
        }

        return true;
    }    
}

signinController snippet:

@Controller
@SessionAttributes(CommonConstants.KAPTCHA_SESSION_KEY)
public class SigninController extends BaseController {

    @RequestMapping(value = "/signin", method = RequestMethod.GET)
    public String signinPage() {
        return "forward:/index.jsp";
    }

    @RequestMapping(value = "/signin", method = RequestMethod.POST)
    public String signin(UserForm userForm, @ModelAttribute(CommonConstants.KAPTCHA_SESSION_KEY) String captchaExpected, RedirectAttributes redirectAttributes, HttpServletRequest request) {
    userForm.setCaptchaExpected(captchaExpected);
    try {
        loginValidator.validate(userForm);
    } catch (ValidateFailedException e) {
        logger.error(e.getMessage(), e);
        redirectAttributes.addFlashAttribute(ERROR_MESSAGE_KEY, e.getMessage());
        return "redirect:/signin";
    }

    User user = userService.getByUsername(userForm.getUsername());
    if (user == null || !user.getPassword().equals(DigestUtils.md5Hex(userForm.getPassword()))) {
        redirectAttributes.addFlashAttribute(ERROR_MESSAGE_KEY, "username or password is invalid");
        return "redirect:/signin";
    }
    request.getSession().setAttribute(CommonConstants.USER_SESSION_KEY, user);
    return "redirect:/dashboard";
}
}

index.jsp snippet:

<%@page contentType="text/html; charset=utf-8"%>
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>welcome</title>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="keywords" content="" />
<meta http-equiv="description" content="" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="${ctx}/css/bootstrap.min.css">
<link rel="stylesheet" href="${ctx}/css/main.css">
<script src="${ctx}/js/jquery-1.11.1.min.js"></script>
<script src="${ctx}/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="login-box text-center" >
    <div class="login-single-panel-header">
        <h5 style="color:red">${errorMessage}</h5>
    </div>
</div>
</div>
</body>
</html>

Thank you very much!

like image 328
qatang Avatar asked Jun 29 '14 11:06

qatang


People also ask

How to Configure Interceptor in Spring MVC?

We have to wire the spring interceptor to the requests, we can use mvc:interceptors element to wire all the interceptors. We can also provide URI pattern to match before including the spring interceptor for the request through mapping element. Our final spring bean configuration file (spring. xml) looks like below.

What is RedirectAttributes Spring MVC?

You can use RedirectAttributes to store flash attributes and they will be automatically propagated to the "output" FlashMap of the current request. A RedirectAttributes model is empty when the method is called and is never used unless the method returns a redirect view name or a RedirectView.

How do I redirect to another controller in spring boot?

We can use a name such as a redirect: http://localhost:8080/spring-redirect-and-forward/redirectedUrl if we need to redirect to an absolute URL.

How to get Flash attribute in Spring?

In order to use Flash attribute in your Spring MVC application make sure you using version 3.1 or above. Also add mvc:annotation-driven to spring-servlet. xml file. Once this is done, Flash attribute is automatically set “on” for usage.


2 Answers

I just encountered the same problem. I debuged the spring source code,looking for how spring mvc same the flashmap attributes,and came up with that it same flashmap attributes in sessions.

here is my last solution:

// create a flashmap
FlashMap flashMap = new FlashMap();

// store the message
flashMap.put("ERROR_MESSAGE", "this is the message");

// create a flashmapMapManger with `request`
FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);

// save the flash map data in session with falshMapManager
flashMapManager.saveOutputFlashMap(flashMap, request, response);
  • the code above referd the method org.springframework.web.servlet.view.RedirectView#renderMergedOutputModel,you may check it youself

wish this will help you!

like image 144
yuankui Avatar answered Sep 18 '22 01:09

yuankui


Here is another way of doing it in Spring 5.0

public class LoginInterceptor extends HandlerInterceptorAdapter{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String loginUrl = request.getContextPath() + "/login";
        if(request.getSession().getAttribute("loggedInUser") == null) {
            FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
            outputFlashMap.put("loginError", "Please login to continue");
            //New utility added in Spring 5
            RequestContextUtils.saveOutputFlashMap(loginUrl, request, response);
            response.sendRedirect(loginUrl);
            return false;
        }
        return true;
    }
}
like image 30
Vinodhini Chockalingam Avatar answered Sep 21 '22 01:09

Vinodhini Chockalingam