복붙노트

[SPRING] REST 응용 프로그램이 아닌 웹 응용 프로그램에서 404 오류 처리

SPRING

REST 응용 프로그램이 아닌 웹 응용 프로그램에서 404 오류 처리

Javaconfig를 사용하여 완전히 구성된 Spring MVC 응용 프로그램에서 @ControllerAdvice를 사용하여 404 오류를 처리하려고합니다.

스프링 MVC 버전은 4.1.5입니다.

나는 이것을 읽었다.

그러나 불행히도 그것은 나를 위해 작동하지 않습니다.

여기에 내 conf가있다.

스프링 구성 초기화 프로그램

public class SpringConfigurationInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {



    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { AppConfiguration.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    public void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
    }
}

내가 사용하고있어.

registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");

GlobalExceptionHandler (버전 1)

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NoHandlerFoundException.class)
    public ModelAndView handleError404(HttpServletRequest request, Exception e) {
        System.out.println("handled!!!");
        ModelAndView mav = new ModelAndView("/errors/404");
        mav.addObject("exception", e);
        return mav;
    }
}

GlobalExceptionHandler (버젼 2)

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    public ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request) {
        System.out.println("handled¡¡¡");
        return null;
    }
}

내가 XML 구성 파일의 어떤 종류도 사용하지 않고 웹 애플리케이션 (REST가 아닌)을 빌드하려고 시도하고 있음을 명심하십시오.

AppConfiguration

@Configuration
@ComponentScan({ "org.moyanojv.opendata.*" })
@Import({ MvcConfiguration.class, RepositoryConfiguration.class, SecurityConfig.class })
public class AppConfiguration extends WebMvcConfigurerAdapter{

}

MVC 구성

@EnableWebMvc
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public UrlBasedViewResolver viewResolver() {
        UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
        viewResolver.setViewClass(TilesView.class);
        return viewResolver;
    }

    @Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/tiles.xml" });
        tilesConfigurer.setCheckRefresh(true);
        return tilesConfigurer;
    }



    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
         registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }


    /* Localization section is started */

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor(){
        LocaleChangeInterceptor localeChangeInterceptor=new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    @Bean(name = "localeResolver")
    public LocaleResolver getLocaleResolver(){
        return new CookieLocaleResolver();
    }

    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("i18n/messages");
        source.setUseCodeAsDefaultMessage(true);
        return source;
    }
}

저장소 구성

@Configuration
public class RepositoryConfiguration {

}

SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
    }

    @Override
    public void configure( WebSecurity web ) throws Exception
    {
        // This is here to ensure that the static content (JavaScript, CSS, etc)
        // is accessible from the login page without authentication
        web
            .ignoring()
                .antMatchers( "/resources/**" );
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        // access-denied-page: this is the page users will be
        // redirected to when they try to access protected areas.
        .exceptionHandling()
            .accessDeniedPage( "/403" )
            .and()
        // The intercept-url configuration is where we specify what roles are allowed access to what areas.
        // We specifically force the connection to https for all the pages, although it could be sufficient
        // just on the login page. The access parameter is where the expressions are used to control which
        // roles can access specific areas. One of the most important things is the order of the intercept-urls,
        // the most catch-all type patterns should at the bottom of the list as the matches are executed
        // in the order they are configured below. So /** (anyRequest()) should always be at the bottom of the list.
        .authorizeRequests()
            .antMatchers( "/admin" ).hasRole("ADMIN")
            .antMatchers("/login**").permitAll()
            .antMatchers("/home").permitAll()
            .antMatchers("/404").permitAll()
            .anyRequest().authenticated()
            .and()
        // This is where we configure our login form.
        // login-page: the page that contains the login screen
        // login-processing-url: this is the URL to which the login form should be submitted
        // default-target-url: the URL to which the user will be redirected if they login successfully
        // authentication-failure-url: the URL to which the user will be redirected if they fail login
        // username-parameter: the name of the request parameter which contains the username
        // password-parameter: the name of the request parameter which contains the password
        .formLogin()
            .loginPage( "/login" )
            .failureUrl( "/login?err=1" )
            .defaultSuccessUrl("/private")
            .usernameParameter( "username" )
            .passwordParameter( "password" )
            .permitAll()
            .and()
        // This is where the logout page and process is configured. The logout-url is the URL to send
        // the user to in order to logout, the logout-success-url is where they are taken if the logout
        // is successful, and the delete-cookies and invalidate-session make sure that we clean up after logout
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout=1")
            .invalidateHttpSession(true)
            //.deleteCookies("JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE")
            .and()
        .csrf()
            .disable()
        // The session management is used to ensure the user only has one session. This isn't
        // compulsory but can add some extra security to your application.
        .sessionManagement()
            .maximumSessions(1);
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception
    {
        return super.userDetailsServiceBean();
    }
}

SpringSecurityInitializer

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer{
    //do nothing
}

이 설정을 사용하면 404 오류 코드를 처리 할 수 ​​없습니다.

미리 감사드립니다.

구성 파일에 대한 자세한 정보를 추가하도록 업데이트되었습니다.

해결법

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

    1.결론은 throwExceptionIfNoHandlerFound를 true로 설정해도 핸들러가 발견되지 않으면 예외를 throw하지 않는 것 같습니다.

    결론은 throwExceptionIfNoHandlerFound를 true로 설정해도 핸들러가 발견되지 않으면 예외를 throw하지 않는 것 같습니다.

    해결책은 아주 간단합니다. javadoc에서 @ DispatcherServlet.setThrowExceptionIfNoHandlerFound. DefaultServletHttpRequestHandler가 사용되면 (자), NoHandlerFoundException는 throw되지 않습니다.

    해결책은 라인을 제거하는 것입니다.

       configurer.enable();
    

    귀하의 MvcConfiguration에서. 예외가 지금 발생하고 GlobalExceptionHandler가 나머지를 처리해야합니다!

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

    2.해결 방법은 AbstractAnnotationConfigDispatcherServletInitializer를 확장하고이 메서드를 재정의하는 것입니다.

    해결 방법은 AbstractAnnotationConfigDispatcherServletInitializer를 확장하고이 메서드를 재정의하는 것입니다.

    @Override
    protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
        final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        return dispatcherServlet;
    }
    

    또는이 하나 :

    @Override
    public void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
    }
    

    마지막으로 ControlerAdvice에서 다음을 사용하십시오.

    @ExceptionHandler(NoHandlerFoundException.class)
    public String error404(Exception ex) {
    
        return new ModelAndView("404");
    }
    
  3. ==============================

    3.해결 방법 : @RequestMapping ( "/ **") 추가

    해결 방법 : @RequestMapping ( "/ **") 추가

    @Controller
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
        @RequestMapping("/**")
        public String handlerNotMappingRequest(HttpServletRequest request, HttpServletResponse response, HttpHeaders httpHeaders)
                throws NoHandlerFoundException {
            throw new NoHandlerFoundException("No handler mapping found.", request.getRequestURL().toString(), httpHeaders);
        }
    
        @ExceptionHandler(Throwable.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public ModelAndView handleControllerException(Throwable ex) {
            logger.error("ErrorLog: ", ex);
            return new ModelAndView("error/exception", "exceptionMsg", "ExceptionHandler msg: " + ex.toString());
        }
    
        @ExceptionHandler(NoHandlerFoundException.class)
        @ResponseStatus(HttpStatus.NOT_FOUND)
        public ModelAndView handleNoHandlerFoundException(NoHandlerFoundException ex) {
            logger.error("ErrorLog: ", ex);
            return new ModelAndView("error/exception", "exceptionMsg", "NoHandlerFoundException msg: " + ex.toString());
        }
    }
    
  4. from https://stackoverflow.com/questions/30504905/handle-error-404-in-web-application-not-rest-application by cc-by-sa and MIT license