복붙노트

[SPRING] 자바 설정으로 Spring에서 404 에러 리디렉션

SPRING

자바 설정으로 Spring에서 404 에러 리디렉션

아시다시피, XML에서 이것을 구성하는 방법은 다음과 같습니다.

<error-page>
    <error-code>404</error-code>
    <location>/my-custom-page-not-found.html</location>
</error-page>

하지만 Java config에서이 작업을 수행하는 방법을 찾지 못했습니다. 내가 시도한 첫 번째 방법은 다음과 같습니다.

@RequestMapping(value = "/**")
public String Error(){
    return "error";
}

그리고 작동하는 것처럼 보였지만 자원을 검색하는 데 충돌이 있습니다.

그것을 할 수있는 방법이 있습니까?

해결법

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

    1.Spring Framework에는 예외 처리 방법 (특히 404 오류)이 많이 있습니다. 문서 링크가 있습니다.

    Spring Framework에는 예외 처리 방법 (특히 404 오류)이 많이 있습니다. 문서 링크가 있습니다.

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

    2.봄 4.2 이후 가장 깨끗한 솔루션 RC3는 AbstractDispatcherServletInitializer를 확장하는 클래스 내에서 (또는 AbstractAnnotationConfigDispatcherServletInitializer를 확장하여 간접적으로) 다음과 같이 새로운 createDispatcherServlet 훅을 사용합니다.

    봄 4.2 이후 가장 깨끗한 솔루션 RC3는 AbstractDispatcherServletInitializer를 확장하는 클래스 내에서 (또는 AbstractAnnotationConfigDispatcherServletInitializer를 확장하여 간접적으로) 다음과 같이 새로운 createDispatcherServlet 훅을 사용합니다.

    public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return null;
        }
    
        /* ... */
    
        @Override
        protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
            final DispatcherServlet dispatcherServlet = super.createDispatcherServlet(servletAppContext);
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
            return dispatcherServlet;
        }
    }
    

    그런 다음 참조 문서에 설명 된대로 전역 @ControllerAdvice (@ControllerAdvice로 주석 된 클래스)를 사용할 수 있습니다. 조언 내에서 여기에 설명 된대로 @ExceptionHandler를 사용하여 NoHandlerFoundException을 처리 할 수 ​​있습니다.

    이것은 다음과 같이 보일 수 있습니다.

    @ControllerAdvice
    public class NoHandlerFoundControllerAdvice {
    
        @ExceptionHandler(NoHandlerFoundException.class)
        public ResponseEntity<String> handleNoHandlerFoundException(NoHandlerFoundException ex) {
            // prepare responseEntity
            return responseEntity;
        }
    
    }
    
  3. ==============================

    3.doc에 설명 된대로 코드 기반 Servlet 컨테이너 초기화를 사용하고 registerDispatcherServlet 메서드를 재정 의하여 throwExceptionIfNoHandlerFound 속성을 true로 설정합니다.

    doc에 설명 된대로 코드 기반 Servlet 컨테이너 초기화를 사용하고 registerDispatcherServlet 메서드를 재정 의하여 throwExceptionIfNoHandlerFound 속성을 true로 설정합니다.

    public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return null;
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[] { WebConfig.class };
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[] { "/" };
        }
    
        @Override
        protected void registerDispatcherServlet(ServletContext servletContext) {
            String servletName = getServletName();
            Assert.hasLength(servletName, "getServletName() may not return empty or null");
    
            WebApplicationContext servletAppContext = createServletApplicationContext();
            Assert.notNull(servletAppContext,
                "createServletApplicationContext() did not return an application " +
                        "context for servlet [" + servletName + "]");
    
            DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
    
            // throw NoHandlerFoundException to Controller
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    
            ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
            Assert.notNull(registration,
                "Failed to register servlet with name '" + servletName + "'." +
                        "Check if there is another servlet registered under the same name.");
    
            registration.setLoadOnStartup(1);
            registration.addMapping(getServletMappings());
            registration.setAsyncSupported(isAsyncSupported());
    
            Filter[] filters = getServletFilters();
            if (!ObjectUtils.isEmpty(filters)) {
                for (Filter filter : filters) {
                    registerServletFilter(servletContext, filter);
                }
            }
    
            customizeRegistration(registration);
        }
    }    
    

    그런 다음 예외 처리기를 만듭니다.

    @ControllerAdvice
    public class ExceptionHandlerController {
        @ExceptionHandler(Exception.class)
        public String handleException(Exception e) {
            return "404";// view name for 404 error
        }   
    }
    

    Spring 설정 파일에서 @EnableWebMvc annotation을 사용하는 것을 잊지 마라.

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages= {"org.project.etc"})
    public class WebConfig extends WebMvcConfigurerAdapter {
        ...
    }
    
  4. ==============================

    4.웹 구성 클래스에서,

    웹 구성 클래스에서,

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter 
    

    다음과 같이 bean을 선언하십시오.

    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
    
      return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container)       
        {
          ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
          ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
          ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
    
          container.addErrorPages(error401Page,error404Page,error500Page);
        }
      };
    }
    

    언급 된 html 파일 (401.html .etc)을 / src / main / resources / static / 폴더에 추가하십시오.

    희망이 도움이

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

    5.100 % 무료 xml에 대한 간단한 대답 :

    100 % 무료 xml에 대한 간단한 대답 :

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

    6.Java 구성의 경우 DispatcherServlet에 setThrowExceptionIfNoHandlerFound (boolean throwExceptionIfNoHandlerFound) 메소드가 있습니다. 사실로 설정하면 똑같은 일을하고있는 것 같아요.

    Java 구성의 경우 DispatcherServlet에 setThrowExceptionIfNoHandlerFound (boolean throwExceptionIfNoHandlerFound) 메소드가 있습니다. 사실로 설정하면 똑같은 일을하고있는 것 같아요.

    <init-param>
        <param-name>throwExceptionIfNoHandlerFound</param-name>
        <param-value>true</param-value>
    </init-param>
    

    위의 대답에 명시된 것처럼 컨트롤러 조언에서이 NoHandlerFoundException.class를 수행 할 수 있습니다.

    그것은 마치 무언가와 같을 것이다.

    public class WebXml implements WebApplicationInitializer{
    
        public void onStartup(ServletContext servletContext) throws ServletException {
            WebApplicationContext context = getContext();
            servletContext.addListener(new ContextLoaderListener(context));
    
    
            DispatcherServlet dp =  new DispatcherServlet(context);
            dp.setThrowExceptionIfNoHandlerFound(true);
    
            ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dp);
            dispatcher.setLoadOnStartup(1);
            dispatcher.addMapping(MAPPING_URL);
        }
    }
    
  7. ==============================

    7.위의 주석에서 제안 된 솔루션은 실제로 작동합니다.

    위의 주석에서 제안 된 솔루션은 실제로 작동합니다.

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration)
    {
      registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
    }
    
  8. from https://stackoverflow.com/questions/23574869/404-error-redirect-in-spring-with-java-config by cc-by-sa and MIT license