복붙노트

[SPRING] 후행 슬래시가있는 URL을 해당 URL없이 해당 URL로 리디렉션하는 방법은 무엇입니까?

SPRING

후행 슬래시가있는 URL을 해당 URL없이 해당 URL로 리디렉션하는 방법은 무엇입니까?

Spring MVC (3.0)는 슬래시가 있거나없는 URL을 동일한 URL로 간주합니다.

예 :

URL을 후행 슬래시로 리디렉션해야합니다.

그것없이 URL에 :

내부적으로이 작업을 수행해야합니다 (Apache 등을 통해 규칙을 다시 작성하지 않음).

그것을하는 방법은 다음과 같습니다.

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

그러나 이것은 일반적으로 2 가지 문제가 있습니다 :

모든 URL을 차단할 수있는 방법이 있습니까? 슬래시가없는 경우 슬래시가없는 상대 URL로 리디렉션 하시겠습니까?

해결법

  1. ==============================

    1.그 중 많은 수가없는 경우 다음과 같이 리디렉션 뷰를 구성 할 수 있습니다.

    그 중 많은 수가없는 경우 다음과 같이 리디렉션 뷰를 구성 할 수 있습니다.

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

    그러나 요청이 특정 Controller.action에 매핑되기 전에 인터셉터가 발생하므로 해당 컨텍스트에서 컨트롤러와 작업을 알 수있는 방법이 없습니다.

    HTTPServlet API와 요청 + 응답 만 있으면됩니다. 그래서 당신은 할 수 있습니다 :

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

    이 동작 (후행 슬래시가있는 URL = URL이없는 URL)은 HTTP를 고려할 때 완벽하게 "유효"합니다. 최소한 이것은 Spring의 기본 동작이며 useTrailingSlashMatch (javadoc 참고)로 해제 할 수 있습니다.

    따라서 프런트 엔드 서버에서 rewrite / redirect 규칙을 사용하면 해결할 수 있습니다. 그러나 다시, 나는 당신의 제약을 모른다. (어쩌면 당신은 이것에 대해 자세히 설명 할 수 있고 다른 해결책을 찾아 낼 수 있을까?).

  2. ==============================

    2.UrlRewriteFilter를 사용하여 Spring 웹 서블릿에 들어가기 전에 가장 좋은 방법이라고 생각한다. 이렇게하면 리디렉션 규칙이 컨트롤러에 영향을 미치지 않습니다.

    UrlRewriteFilter를 사용하여 Spring 웹 서블릿에 들어가기 전에 가장 좋은 방법이라고 생각한다. 이렇게하면 리디렉션 규칙이 컨트롤러에 영향을 미치지 않습니다.

    mod_rewrite가있는 아파치가 아닌 .war 프로젝트에 규칙을 작성한다는 점에 유의하십시오.

    도서관의 googlecode 프로젝트를 보려면 여기로 이동하십시오.

    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>
          <to type="redirect">$1</to>
        </rule>  
    </urlrewrite>
    

    애플리케이션의 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>
    

    웹.xml에서 필터의 선언 순서가 중요하므로 봄부터이 필터를 선언하십시오.

    물론 이것은 UrlRewriteFilter가 수행 할 수있는 것의 일부일뿐입니다.

    문안 인사.

  3. ==============================

    3.이것은 보통 Spring의 URLRewriteFilter에서 작동한다.

    이것은 보통 Spring의 URLRewriteFilter에서 작동한다.

    <?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>
    
  4. ==============================

    4.Spring 3.0에이 기능이 있는지는 모르지만 Spring 3.1 RequestMappingHandlerMapping을 사용하면 "useTrailingSlashMatch"속성을 설정할 수 있습니다. 기본적으로 그것은 사실입니다.

    Spring 3.0에이 기능이 있는지는 모르지만 Spring 3.1 RequestMappingHandlerMapping을 사용하면 "useTrailingSlashMatch"속성을 설정할 수 있습니다. 기본적으로 그것은 사실입니다.

    나는 false로 바꾸면 문제를 해결할 수 있다고 생각하지만, 애플리케이션 전반에 걸쳐 RequestMappingHandlerMapping이 처리하는 모든 매핑에 영향을 미칠 것입니다 ... 그래서 회귀해야 할 정도의 공정량이있을 수 있습니다.

  5. ==============================

    5.@Brian Clozel에 동의합니다. 나는 당신이 원하는 것을 할 생각이별로 없습니다. 그래서, 왜 그것을 필요로합니까?

    @Brian Clozel에 동의합니다. 나는 당신이 원하는 것을 할 생각이별로 없습니다. 그래서, 왜 그것을 필요로합니까?

    어쨌든, 가장 간단한 해결책은 사용자 정의 javax.servlet.Filter를 작성하는 것입니다. 따라서 스프링 의존성이 없습니다. 요청 URL이 슬래시로 끝나면 URL이없는 동일한 URL로 리디렉션하면됩니다. 그러나주의 :

    행운을 빕니다!

  6. ==============================

    6.SEO를 기반으로, 나는 구별하는 것이 중요하다고 생각합니다.

    SEO를 기반으로, 나는 구별하는 것이 중요하다고 생각합니다.

    후행 슬래시로 끝난 URL이 검색 엔진에서 인덱싱되고 인터넷에 링크가있는 경우 Uddhav Kambli가 말한 것처럼 영구 리디렉션 (301)이 필요합니다. 표준 리디렉션 (302)은 중복 된 URL을 갖는 것보다 낫지 만 충분히 좋지는 않습니다.

    그러나 URL이 절대로 존재하지 않으면 인터넷에서 색인이 생성되지 않고 외부 링크가 없으므로 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>
    

    그리고 구성을 완료하려면 ...

    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>
    

    메이븐

    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>4.0.3</version>
    </dependency>
    
  7. ==============================

    7.나는 @Configuration 어딘가에서 ErrorViewResolver 빈을 사용함으로써 훨씬 더 간단하게 처리 할 수 ​​있다는 것을 발견했다.

    나는 @Configuration 어딘가에서 ErrorViewResolver 빈을 사용함으로써 훨씬 더 간단하게 처리 할 수 ​​있다는 것을 발견했다.

    @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);
            }
        };
    }
    

    이것이 좋은지 나쁜지 잘 모르겠지만 내 상황에서는 효과적이며, 임의의 경로 인 'foo'에 대해 정확히 필요한 작업을 수행합니다. 요청시 / foo /에 302 리디렉션으로 응답합니다. / foo를 요청하고 / foo를 요청할 때 응답해야합니다.

  8. from https://stackoverflow.com/questions/8711392/how-to-redirect-urls-with-trailing-slash-to-the-corresponding-ones-without-it by cc-by-sa and MIT license