Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 905
Randomize Avatar asked Jan 03 '12 11:01

Randomize


People also ask

How do you add a trailing slash to a URL?

A trailing slash is a forward slash (“/”) placed at the end of a URL such as domain.com/ or domain.com/page/. The trailing slash is generally used to distinguish a directory which has the trailing slash from a file that does not have the trailing slash.

What happens if you skip the trailing slash?

When using APPEND_SLASH , if they accidently sent it without trailing slash, and your urlconf is WITH a trailing slash they would get an exception about data lose when redirecting POST requests.

Is trailing slash necessary in URL?

Historically, a trailing slash marked a directory and a URL without a trailing slash at the end used to mean that the URL was a file. Today, however, trailing slashes are purely conventional, and Google does not care whether you use them; as long as you're consistent.

What is a trailing slash redirect?

A trailing slash is a forward slash placed at the end of a URL. It's usually used to indicate a directory (as opposed to a file), but in SEO it can affect your rankings. Take a look at the URLs below and guess which one is 'correct'. Note that one of them has a trailing slash at the end.


2 Answers

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?).

like image 55
Brian Clozel Avatar answered Jan 02 '23 03:01

Brian Clozel


I think you best option would be to do this before entering in Spring web's servlet, using UrlRewriteFilter. This will ensure that your redirect rules would not impact your controllers.

Please note that you write the rules in your .war project, not in an apache with mod_rewrite.

Go here for the library's project on googlecode.

in the urlrewrite.xml write :

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.1//EN" "http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd"> <urlrewrite>     <rule match-type="regex">         <note>Remove trailing slash</note>       <from>^(.*)/$</from>       <to type="redirect">$1</to>     </rule>   </urlrewrite> 

In the web.xml of your application, add :

<filter>     <filter-name>UrlRewriteFilter</filter-name>     <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>        <init-param>             <param-name>confPath</param-name>             <param-value>/WEB-INF/urlrewrite.xml</param-value>         </init-param> </filter> <filter-mapping>     <filter-name>UrlRewriteFilter</filter-name>     <url-pattern>/*</url-pattern>     <dispatcher>REQUEST</dispatcher> </filter-mapping> 

Beware, the declaration order of the filters in the web.xml is important, so try to declare this one before anything from spring.

Of course, this is but a fraction of what UrlRewriteFilter can do.

Regards.

like image 28
Geraud Gratacap Avatar answered Jan 02 '23 03:01

Geraud Gratacap