Redirect to an external URL from controller action in Spring MVC
JavaSpringJspSpring MvcJava Problem Overview
I have noticed the following code is redirecting the User to a URL inside the project,
@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "yahoo.com";
return "redirect:" + redirectUrl;
}
whereas, the following is redirecting properly as intended, but requires http:// or https://
@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "http://www.yahoo.com";
return "redirect:" + redirectUrl;
}
I want the redirect to always redirect to the URL specified, whether it has a valid protocol in it or not and do not want to redirect to a view. How can I do that?
Thanks,
Java Solutions
Solution 1 - Java
You can do it with two ways.
First:
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}
Second:
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
return new ModelAndView("redirect:" + projectUrl);
}
Solution 2 - Java
You can use the RedirectView
. Copied from the JavaDoc:
> View that redirects to an absolute, context relative, or current request relative URL
Example:
@RequestMapping("/to-be-redirected")
public RedirectView localRedirect() {
RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://www.yahoo.com");
return redirectView;
}
You can also use a ResponseEntity
, e.g.
@RequestMapping("/to-be-redirected")
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI yahoo = new URI("http://www.yahoo.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(yahoo);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
And of course, return redirect:http://www.yahoo.com
as mentioned by others.
Solution 3 - Java
Looking into the actual implementation of UrlBasedViewResolver and RedirectView the redirect will always be contextRelative if your redirect target starts with /. So also sending a //yahoo.com/path/to/resource wouldn't help to get a protocol relative redirect.
So to achieve what you are trying you could do something like:
@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = request.getScheme() + "://www.yahoo.com";
return "redirect:" + redirectUrl;
}
Solution 4 - Java
You can do this in pretty concise way using ResponseEntity
like this:
@GetMapping
ResponseEntity<Void> redirect() {
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create("http://www.yahoo.com"))
.build();
}
Solution 5 - Java
Another way to do it is just to use the sendRedirect
method:
@RequestMapping(
value = "/",
method = RequestMethod.GET)
public void redirectToTwitter(HttpServletResponse httpServletResponse) throws IOException {
httpServletResponse.sendRedirect("https://twitter.com");
}
Solution 6 - Java
For me works fine:
@RequestMapping (value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI uri = new URI("http://www.google.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(uri);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
Solution 7 - Java
For external url you have to use "http://www.yahoo.com" as the redirect url.
This is explained in the redirect: prefix of Spring reference documentation.
> redirect:/myapp/some/resource
will redirect relative to the current Servlet context, while a name such as
> redirect:http://myhost.com/some/arbitrary/path
will redirect to an absolute URL
Solution 8 - Java
Did you try [RedirectView][1] where you can provide the contextRelative parameter?
[1]: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/view/RedirectView.html#RedirectView%28java.lang.String,%20boolean%29 "RedirectView"
Solution 9 - Java
This works for me, and solved "Response to preflight request doesn't pass access control check ..." issue.
Controller
RedirectView doRedirect(HttpServletRequest request){
String orgUrl = request.getRequestURL()
String redirectUrl = orgUrl.replaceAll(".*/test/","http://xxxx.com/test/")
RedirectView redirectView = new RedirectView()
redirectView.setUrl(redirectUrl)
redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT)
return redirectView
}
and enable securty
@EnableWebSecurity
class SecurityConfigurer extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
}
}
Solution 10 - Java
In short "redirect://yahoo.com"
will lend you to yahoo.com
.
where as "redirect:yahoo.com"
will lend you your-context/yahoo.com
ie for ex- localhost:8080/yahoo.com