Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将带有尾随斜杠的URL重定向到不带斜杠的相应URL?_Java_Spring_Spring Mvc_Redirect_Model View Controller - Fatal编程技术网

Java 如何将带有尾随斜杠的URL重定向到不带斜杠的相应URL?

Java 如何将带有尾随斜杠的URL重定向到不带斜杠的相应URL?,java,spring,spring-mvc,redirect,model-view-controller,Java,Spring,Spring Mvc,Redirect,Model View Controller,SpringMVC(3.0)将带有或不带有斜杠的URL视为同一URL 例如: = 我需要用后面的斜杠重定向URL 不带URL的URL: 我需要在应用程序内部执行此操作(因此不要通过Apache等重写规则) 一种方法是: @ResponseStatus(value=HttpStatus.MOVED_PERMANENTLY) @RequestMapping(value = "/data/something/") public String dataSomethingRedirect(...) {

SpringMVC(3.0)将带有或不带有斜杠的URL视为同一URL

例如:

=

我需要用后面的斜杠重定向URL

不带URL的URL:

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

一种方法是:

@ResponseStatus(value=HttpStatus.MOVED_PERMANENTLY)
@RequestMapping(value = "/data/something/")
public String dataSomethingRedirect(...) {
    return "redirect:/data/something";
}
但这通常有两个问题:

  • 控制器太多
  • 参数问题:比如编码错误
  • 问题:
    有没有办法截取所有URL,如果它们有一个尾随斜杠,将它们重定向到没有斜杠的相对URL?

    我认为最好的选择是在进入SpringWeb的servlet之前,使用UrlRewriteFilter这样做。这将确保重定向规则不会影响控制器

    请注意,这些规则是在.war项目中编写的,而不是在带有mod_rewrite的apache中编写的

    图书馆的谷歌代码项目

    在urlrewrite.xml文件中写入:

    
    删除尾部斜杠
    ^(.*)/$
    $1
    
    在应用程序的web.xml中,添加:

    
    URL重写过滤器
    org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
    confPath
    /WEB-INF/urlrewrite.xml
    URL重写过滤器
    /*
    要求
    
    请注意,web.xml中过滤器的声明顺序很重要,因此请在spring中的任何内容之前声明此过滤器

    当然,这只是URLEwriteFilter功能的一小部分

    注意。

    您可以在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); 
    }
    
    或者您可以创建一个自定义 但是拦截器发生在请求映射到特定的
    控制器.action
    之前,您无法了解该上下文中的控制器和操作

    您所拥有的只是HTTPServlet API和请求+响应;因此,您可以:

    response.sendRedirect("http://example.org/whitout-trailing-slash");
    
    你不想读的答案 当考虑HTTP时,这种行为(带有尾随斜杠的URL=URL不带斜杠)是完全“有效”的。至少这是Spring的默认行为,您可以使用
    useTrailingSlashMatch
    ()禁用它


    因此,在前端服务器上使用重写/重定向规则可能是一个解决方案;但是,我也不知道你的限制(也许你可以详细说明一下,我们可以找出其他解决方案?)

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

    无论如何,我认为最简单的解决方案是编写一个定制的
    javax.servlet.Filter
    。因此,没有Spring依赖性。如果请求URL以斜杠结尾,您只需重定向到没有斜杠的相同URL即可。但请注意:

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

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


    祝你好运

    这通常适用于我在春天使用URLEwriteFilter

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN" 
     "http://www.tuckey.org/res/dtds/urlrewrite3.2.dtd">
    <urlrewrite>
        <rule>
             <note>Remove trailing slash for SEO purposes</note>
             <from>/**/</from>
             <to type="permanent-redirect">%{context-path}/$1</to>
        </rule>
    </urlrewrite>
    
    
    删除尾部斜杠以进行搜索引擎优化
    /**/
    %{上下文路径}/$1
    
    不确定spring 3.0是否有此功能,但spring 3.1允许您设置“useTrailingSlashMatch”属性。默认情况下,这是真的


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

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

    如乌德哈夫·坎布里所说,如果在尾部斜杠中结束的URL存在,在搜索引擎中被索引,并且在互联网上有链接,则需要永久重定向(301)。标准重定向(302)比使用重复的URL要好,但还不够好

    但是,如果URL不存在,它不会在Internet上建立索引,并且没有外部链接,则URL不存在。因此,404(未找到页面)更适合

    WEB-INF/urlrewrite.xml

    <?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>
            <set type="status">404</set>
            <to>null</to>
        </rule>
    </urlrewrite>
    
    
    删除尾部斜杠
    ^(.+)/$
    404
    无效的
    
    为了完成配置

    添加到WEB-INF/WEB.xml

    <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>
    
    
    URL重写过滤器
    org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
    confPath
    /WEB-INF/urlrewrite.xml
    URL重写过滤器
    /*
    要求
    
    马文

    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>4.0.3</version>
    </dependency>
    
    
    org.tuckey
    URL重写过滤器
    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<String, Object> model) {
                if(model.containsKey("path") && !model.get("path").toString().endsWith("/")) {
                    return new ModelAndView("redirect:"+model.get("path") + "/");
                }
                return defaultErrorViewResolver.resolveErrorView(request, status, model);
            }
        };
    }
    
    @Autowired
    私有DefaultErrorViewResolver DefaultErrorViewResolver;
    @豆子
    ErrorViewResolver ErrorViewResolver(){
    返回新的ErrorViewResolver(){
    @凌驾
    公共模型和视图resolveErrorView(HttpServletRequest请求、HttpStatus状态、映射模型){
    if(model.containsKey(“path”)&&!model.get(“path”).toString().endsWith(“/”){
    返回新的ModelAndView(“重定向:”+model.get(“路径”)+“/”;
    }
    返回defaultErrorViewResolver.resolveErrorView(请求、状态、模型);
    }
    };
    }
    

    我不确定这是好的还是坏的做法,但在我的情况下,它是有效的,并且正是我需要它对任意路径“foo”所做的:当你请求/foo时,用302重定向到/foo/进行响应,当你请求/foo时,用它应该的方式进行响应。

    如果一个总是重定向到另一个,它们不是类似地等效吗?为实现这一目标所付出的努力可能很高。如果你的担心完全是c