Spring forward with added parameters?

The simplest way is to add the data to the request. Since this is a forward, the same request is passed around to different handlers within the server.

As example, let’s start with a simple setup of two controllers, one forwarding to the other:

@Controller
public class TestController {
    @RequestMapping(value="/test")
    public String showTestPage() {
        return "forward:/test2";
    }
}

@Controller
public class TestController2 {
    @RequestMapping(value="/test2")
    public String showTestPage() {
        return "testPageView";
    }
}

First way to add the data is to set it as attributes on the request. The new controllers will look like this (A):

@Controller
public class TestController {
    @RequestMapping(value="/test")
    public String showTestPage(HttpServletRequest request) {
        request.setAttribute("param1", "foo");
        request.setAttribute("param2", "bar");
        return "forward:/test2";
    }
}

@Controller
public class TestController2 {
    @RequestMapping(value="/test2")
    public String showTestPage(HttpServletRequest request) {
        String param1 = (String) request.getAttribute("param1");
        String param2 = (String) request.getAttribute("param2");
        return "testPageView";
    }
}

Since the view name in the forward prefix is basically an URL, you can also have the following versions (attribute changed to parameter) (B):

@Controller
public class TestController {
    @RequestMapping(value="/test")
    public String showTestPage() {
        return "forward:/test2?param1=foo&param2=bar";
    }
}

@Controller
public class TestController2 {
    @RequestMapping(value="/test2")
    public String showTestPage(HttpServletRequest request) {
        String param1 = request.getParameter("param1");
        String param2 = request.getParameter("param2");
        return "testPageView";
    }
}

You can also further simplify the second controller by using annotations instead:

@Controller
public class TestController2 {
    @RequestMapping(value="/test2")
    public String showTestPage(@RequestParam String param1, @RequestParam String param2) {
        return "testPageView";
    }
}

And just for the fun of it, and to show Spring’s binding behavior in action, you could do it even like this (C):

@Controller
public class TestController {
    @RequestMapping(value="/test")
    public String showTestPage() {
        return "forward:/test2?param1=foo&param2=bar";
    }
}

@Controller
public class TestController2 {
    @RequestMapping(value="/test2")
    public String showTestPage(@ModelAttribute DummyBinder params) {
        String param1 = params.getParam1();
        String param2 = params.getParam2();
        return "testPageView";
    }
}

class DummyBinder {
    private String param1;
    private String param2;

    public String getParam1() {
        return param1;
    }

    public void setParam1(String param1) {
        this.param1 = param1;
    }

    public String getParam2() {
        return param2;
    }

    public void setParam2(String param2) {
        this.param2 = param2;
    }
}

I would personally go with solution A for many parameters, and solution B for a few. Solution C has a sort of “huh…?!” effect so I would avoid it (also it works with parameters added to the URL so a few of those or you get a messy URL).

Adding the data in the session would also work off course, but would extend the data’s life time unnecessarily, so the best place is to add it on the request during the transition to the second controller.

Leave a Comment