Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect with 301 status in Spring MVC 4 without ModelAndView

I try to have a redirect with 301 Status Code (you know I want to be SEO friendly etc).

I do use InternalResourceViewResolver so I wanted to use some kind of a code similar to return "redirect:http://google.com" in my Controller. This though would send a 302 Status Code

What I have tried is using a HttpServletResponse to set header

@RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public String detail(@PathVariable String seo, HttpServletResponse response){
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    return "redirect:http://google.com";
}

It does still return 302.

After checking documentation and Google results I've come up with the following:

@RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public ModelAndView detail(@PathVariable String seo){
    RedirectView rv = new RedirectView();
    rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
    rv.setUrl("http://google.com");
    ModelAndView mv = new ModelAndView(rv);
    return mv;
}

It does work perfectly fine and as expected, returning code 301

I would like to achieve it without using ModelAndView (Maybe it's perfectly fine though). Is it possible?

NOTE: included snippets are just parts of the detail controller and redirect does happen only in some cases (supporting legacy urls).

like image 226
SirKometa Avatar asked Feb 25 '15 17:02

SirKometa


2 Answers

I would suggest using redirectView of spring like you have it. You have to have a complete URL including the domain etc for that to work, else it will do a 302. Or if you have access to HttpServletResponse, then you can do the below as below.

public void send301Redirect(HttpServletResponse response, String newUrl) {
        response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
        response.setHeader("Location", newUrl);
        response.setHeader("Connection", "close");
    }
like image 104
minion Avatar answered Oct 21 '22 09:10

minion


Not sure when it was added, but at least on v4.3.7 this works. You set an attribute on the REQUEST and the spring View code picks it up:

@RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public String detail(@PathVariable String seo, HttpServletRequest request){
    request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.MOVED_PERMANENTLY);
    return "redirect:http://google.com";
}
like image 41
Alex R Avatar answered Oct 21 '22 09:10

Alex R