Removing default model attributes in the URL in Spring MVC while redirecting

Removing default model attributes in the URL in Spring MVC while redirecting

Recently I have come across a problem regarding page redirection. The application I was working on is using Spring security and also Spring MVC.

The problem was that when the user tries to access the /login.html the login page will be displayed if he is not logged in, but if he is already logged in then there was a problem with the URL being shown in the browser i.e. login.html (though his relevant page content is shown) as internally there was a jsp forward.

Jsp forward will not change the URL in the browser address bar. Only redirect will change the address as the browser will be asked to send another request to the server.

<div>
    <auth:authorize access="hasRole('ROLE_ADMIN')">
        <jsp:forward page="/admin/home.html"/>
    </auth:authorize>

    <auth:authorize access="hasRole('ROLE_USER')">
        <jsp:forward page="/user.html"/>
    </auth:authorize>
</div>

The above configuration from a JSP was used to forward the user to his relevant page. Since it was a jsp forward, the URL in the browser address bar was not changing.

To solve this problem I had to use Spring’s RedirectView class. So, this article shows the usage of that class and how we can avoid the default model attributes not being shown in the URL.

When we use the RedirectView class and set and return the view, it actually works fine and redirects to the specified view with the change in the URL of the browser.

But there is a caveat. It actually exposes the default model attributes in the URL like the following

http://localhost:8081/app/admin.html?total=48&loggedInUserRoles=207.

The data after ? is exposed in the URL as it the default model attribute in my application.

So, to strip off the extra data from the URL we have to set the exposeModelAttributes to false as in the following code.

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public View login(HttpServletRequest request) throws IOException {

        //Get the Spring Security authentication object
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        RedirectView view;
        String url = null;

        //Check if the user is already logged in (except the anonymous user)
        if (!(authentication instanceof AnonymousAuthenticationToken)) {
            //User is logged in
            List userRoles = AuthenticationUtils.getUserRoles();
            if (userRoles.contains("ROLE_ADMIN")) {
                url = "./admin/home.html";
            } else if (userRoles.contains("ROLE_USER")) {
                url = "./user.html";
            }
        }

        //If the user is not logged in, the url variable will be null
        //If the user is not logged in, send him to the application root, where login page will be shown
        if (url == null) {
            url = "/" + request.getContextPath();
        }

        view = new RedirectView(url);
        view.setExposeModelAttributes(false);
        return view;
    }

 

The line view.setExposeModelAttributes(false) removes the default model attributes from the URL.

Hope this article has helped you and wish you a happy coding.

Reference:

http://stackoverflow.com/questions/31187747
http://stackoverflow.com/questions/13247239

Rajasekhar
Java Developer
Helical IT Solutions