Java – How to redirect URLs with trailing slash to the corresponding ones without it

javamodel-view-controllerredirectspringspring-mvc

Spring MVC (3.0) considers URLs with and without trailing slashes as the same URL.

For example:

http://www.example.org/data/something = http://www.example.org/data/something/

I need to redirect the URL with trailing slashes

http://www.example.org/data/something/

to the URL without it:

http://www.example.org/data/something

I need to do this internally the application (so not rewrite rules via Apache, etc).

A way to do it is:

@ResponseStatus(value=HttpStatus.MOVED_PERMANENTLY)
@RequestMapping(value = "/data/something/")
public String dataSomethingRedirect(...) {
    return "redirect:/data/something";
}

but this has generally 2 problems:

  1. too many controllers
  2. problem with parameters: like wrong encoding

Question

Is there a way to intercept all the URLs and in case they have a trailing slash, redirect them to the relative one without slash?

Best Answer

You could list all the rewrite rules you need in your web configuration

If there aren't many of those, you can configure redirect views like this

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addRedirectViewController("/my/path/", "/my/path")
      .setKeepQueryParams(true)
      .setStatusCode(HttpStatus.PERMANENT_REDIRECT); 
}

Or you could create a custom HandlerInterceptor

But interceptors occur before requests are mapped to a specific Controller.action and you've got no way of knowing Controllers and actions in that context.

All you've got is HTTPServlet API and request+response; so you can:

response.sendRedirect("http://example.org/whitout-trailing-slash");

The answer you don't want to read

This behavior (URL with trailing slash = URL without it) is perfectly "valid" when considering HTTP. At least this is the default behavior with Spring, that you can disable with useTrailingSlashMatch (see javadoc).

So using rewrite/redirect rules on the front-end server could a solution; but again, I don't know your constraints (maybe you could elaborate on this and we could figure out other solutions?).

Related Topic