如何将带有斜杠的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"; }
但这通常有两个问题:
- 控制器太多了
- 参数问题:喜欢错误的编码
题
有没有办法拦截所有的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时响应它。