如何将带有斜杠的URL重定向到没有它的相应的URL?

Spring MVC(3.0)将带有和不带尾部斜杠的URL视为相同的URL。

例如:

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

我需要使用尾部斜杠重定向URL

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

到没有它的URL:

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

我需要在应用程序内部执行此操作(因此不要通过Apache重写规则等)。

一种方法是:

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

但这通常有两个问题:

  1. 控制器太多了
  2. 参数问题:喜欢错误的编码

有没有办法拦截所有的URL,如果他们有一个尾部斜杠,将它们重定向到没有斜线的相对URL?

您可以列出Web配置中所需的所有重写规则

如果没有那么多,您可以配置这样的重定向视图

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

或者您可以创建自定义HandlerInterceptor

但是拦截器在请求映射到特定的Controller.action之前发生,并且您无法知道该上下文中的控制器和操作。

你所拥有的只是HTTPServlet API和request + response; 所以你可以:

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

你不想读的答案

在考虑HTTP时,此行为(具有尾部斜杠的URL =没有它的URL)完全“有效”。 至少这是Spring的默认行为,您可以使用useTrailingSlashMatch禁用( 请参阅javadoc )。

因此,在前端服务器上使用重写/重定向规则可以提供解决方案; 但同样,我不知道你的约束(也许你可以详细说明这一点,我们可以找出其他解决方案?)。

我认为你最好选择在进入Spring web的servlet之前使用UrlRewriteFilter。 这将确保您的重定向规则不会影响您的控制器。

请注意,您在.war项目中编写规则,而不是在mod_rewrite的apache中编写规则。

去 googlecode的图书馆项目。

在urlrewrite.xml中写:

     Remove trailing slash ^(.*)/$ $1   

在应用程序的web.xml中,添加:

  UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter  confPath /WEB-INF/urlrewrite.xml    UrlRewriteFilter /* REQUEST  

请注意,web.xml中filter的声明顺序很重要,因此请尝试在spring之前声明这个filter。

当然,这只是UrlRewriteFilter可以做的一小部分。

问候。

这通常适用于Spring中的URLRewriteFilter。

     Remove trailing slash for SEO purposes /**/ %{context-path}/$1   

不确定spring 3.0是否有这个,但是Spring 3.1 RequestMappingHandlerMapping允许你设置一个“useTrailingSlashMatch”属性。 默认情况下是这样。

我认为将其切换为false将解决您的问题,但是它会影响您的应用程序中的RequestMappingHandlerMapping处理的所有映射…因此您可能需要进行相当多的回归。

我同意@Brian Clozel:我认为做你想做的事并不是一个好主意。 那么,为什么需要它呢?

无论如何,我认为最简单的解决方案是编写一个自定义的javax.servlet.Filter 。 所以,没有Spring依赖。 如果请求URL以斜杠结尾,则只需将其重定向到相同的URL即可。 但要小心:

  • 必须将所有参数(GET和POST)添加为GET参数。 您确定您的应用程序与方法无关吗?

  • 编码时可能会遇到一些问题。 在filter中,您可以将POST参数编码为所需的编码。 但是,您的应用程序中未配置GET参数的默认编码。 在server.xml中配置(如果是Tomcat),默认值为ISO-8859-1。

祝你好运!

基于SEO,我认为区分是很重要的。

如果在尾部斜杠中结束的URL存在,在搜索引擎中被索引并且在因特网上有链接,则需要永久重定向(301),如Uddhav Kambli所说。 标准重定向(302)将比具有重复的URL更好,但还不够好。

但是,如果URL从不存在,则不在Internet上编制索引,并且没有外部链接,URL不存在。 因此,未找到的404页面更适合。

WEB-INF / urlrewrite.xml

     Remove trailing slash ^(.+)/$ 404 null   

并且为了完成配置……

添加到WEB-INF / web.xml

  UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter  confPath /WEB-INF/urlrewrite.xml    UrlRewriteFilter /* REQUEST  

Maven的

  org.tuckey urlrewritefilter 4.0.3  

我发现通过在@Configuration中的某处使用ErrorViewResolver bean,可以更简单地处理这个问题:

 @Autowired private DefaultErrorViewResolver defaultErrorViewResolver; @Bean ErrorViewResolver errorViewResolver() { return new ErrorViewResolver() { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map model) { if(model.containsKey("path") && !model.get("path").toString().endsWith("/")) { return new ModelAndView("redirect:"+model.get("path") + "/"); } return defaultErrorViewResolver.resolveErrorView(request, status, model); } }; } 

我不确定这是好的还是坏的做法,但它在我的情况下是有效的,并且正是我需要它为任意路径’foo’做的事情:当你请求时用302重定向响应/ foo / / foo并在你请求/ foo时响应它。