복붙노트

[SPRING] Spring MVC에서 뷰를 렌더링 할 때 발생하는 예외를 처리하는 방법은 무엇입니까?

SPRING

Spring MVC에서 뷰를 렌더링 할 때 발생하는 예외를 처리하는 방법은 무엇입니까?

뷰 기술로 FreeMarker를 사용하는 Spring MVC 응용 프로그램이 있습니다 (하지만 뷰 기술은 내 질문에별로 중요하지 않음). 요청하는 동안 throw 될 수있는 모든 예외를 가로 챌 필요가 있습니다.

HandlerExceptionResolver를 구현했지만이 해결자는 컨트롤러 내에서 예외가 발생할 때만 실행됩니다. 그러나 컨트롤러가 ModelAndView를 반환하고 뷰를 렌더링하는 동안 예외가 발생하면 (예외적으로 변수가 없거나 이와 유사하므로) 예외 확인자가 호출되지 않고 대신 브라우저 윈도우에서 스택 추적을 얻습니다.

또한보기를 반환하고 @ExceptionHandler 주석을 달았지만이 또한 작동하지 않는 컨트롤러 내에서 예외 처리기 메서드를 사용하여 시도했다. 예외가 컨트롤러에서 있지만보기에서 throw되지 않기 때문에 가능성이 높습니다.

그래서 거기에 몇 가지 스프링 메커니즘을 어디에 내가보기 오류를 캡처 예외 처리기를 등록 할 수 있습니까?

해결법

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

    1.단어 앞부분 : 많은 로직과 모델 준비없이 "정적"오류 페이지 만 있으면 web.xml에 <오류 페이지> 태그를 넣으면 충분합니다 (아래 예제 참조).

    단어 앞부분 : 많은 로직과 모델 준비없이 "정적"오류 페이지 만 있으면 web.xml에 <오류 페이지> 태그를 넣으면 충분합니다 (아래 예제 참조).

    그렇지 않으면이 작업을 수행하는 더 좋은 방법이있을 수 있지만 이것이 우리에게 효과적입니다.

    우리는 모든 예외를 포착하고 Spring HandlerExceptionResolver 내에서 사용하는 사용자 정의 ErrorHandler를 호출하는 web.xml의 서블릿 를 사용합니다.

    <filter>
       <filter-name>errorHandlerFilter</filter-name>
       <filter-class>org.example.filter.ErrorHandlerFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>errorHandlerFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    구현은 기본적으로 다음과 같습니다.

    public class ErrorHandlerFilter implements Filter {
    
      ErrorHandler errorHandler;
    
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        try {
          filterChain.doFilter(request, response);
        } catch (Exception ex) {
          // call ErrorHandler and dispatch to error jsp
          String errorMessage = errorHandler.handle(request, response, ex);
          request.setAttribute("errorMessage", errorMessage);
          request.getRequestDispatcher("/WEB-INF/jsp/error/dispatch-error.jsp").forward(request, response);
        }
    
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
        errorHandler = (ErrorHandler) WebApplicationContextUtils
          .getRequiredWebApplicationContext(filterConfig.getServletContext())
          .getBean("defaultErrorHandler");
      }
    
      // ...
    }
    

    FreeMarker 템플릿과 거의 동일하게 작동해야한다고 생각합니다. 물론 오류보기에서 오류가 발생하면 옵션이 다소 벗어납니다.

    404와 같은 오류를 잡아서 모델을 준비하려면 ERROR 디스패처에 매핑 된 필터를 사용합니다.

    <filter>
       <filter-name>errorDispatcherFilter</filter-name>
       <filter-class>org.example.filter.ErrorDispatcherFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>errorDispatcherFilter</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    
    <error-page>
      <error-code>404</error-code>
      <location>/WEB-INF/jsp/error/dispatch-error.jsp</location>
    </error-page>
    <error-page>
      <exception-type>java.lang.Exception</exception-type>
      <location>/WEB-INF/jsp/error/dispatch-error.jsp</location>
    </error-page>
    

    doFilter-Implementation은 다음과 같습니다.

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
      final HttpServletRequest request = (HttpServletRequest) servletRequest;
    
      // handle code(s)
      final int code = (Integer) request.getAttribute("javax.servlet.error.status_code");
      if (code == 404) {
        final String uri = (String) request.getAttribute("javax.servlet.error.request_uri");
        request.setAttribute("errorMessage", "The requested page '" + uri + "' could not be found.");
      }
    
      // notify chain
      filterChain.doFilter(servletRequest, servletResponse);
    }
    
  2. ==============================

    2.DispatcherServlet을 확장 할 수 있습니다.

    DispatcherServlet을 확장 할 수 있습니다.

    web.xml에서 자신의 클래스에 대한 일반 DispatcherServlet을 대체하십시오.

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>com.controller.generic.DispatcherServletHandler</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    나중에 자신의 클래스 인 DispatcherServletHandler를 만들고 DispatcherServlet에서 확장합니다.

    public class DispatcherServletHandler extends DispatcherServlet {
    
        private static final String ERROR = "error";
        private static final String VIEW_ERROR_PAGE = "/WEB-INF/views/error/view-error.jsp";
    
        @Override
        protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
            try{
                super.doService(request, response);
            } catch(Exception ex) {
                request.setAttribute(ERROR, ex);
                request.getRequestDispatcher(VIEW_ERROR_PAGE).forward(request, response);
            }
         }
    }
    

    그리고 그 페이지에서 우리는 사용자에게 메시지를 보여줘야합니다.

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

    3.내 솔루션이 당신이 가진 문제와 관련이 있는지 확실하지 않습니다. 아쉽게도 스택 추적이 브라우저 내부에 표시되지 않도록 예외를 잡는 방법을 게시합니다.

    내 솔루션이 당신이 가진 문제와 관련이 있는지 확실하지 않습니다. 아쉽게도 스택 추적이 브라우저 내부에 표시되지 않도록 예외를 잡는 방법을 게시합니다.

    다음과 같이 특정 충돌을 처리 할 메소드로 AbstractController 클래스를 만들었습니다.

    public class AbstractController {
    
        @ResponseStatus(HttpStatus.CONFLICT)
        @ExceptionHandler({OptimisticLockingFailureException.class})
        @ResponseBody
        public void handleConflict() {
        //Do something extra if you want
        }
    }
    

    예외가 발생할 때마다 사용자는 기본 HTTP 응답 상태를 볼 수 있습니다. (예 : 404 찾을 수 없음 ..)

    나는 모든 컨트롤러 클래스에서이 클래스를 확장하여 오류가 AbstractController로 리디렉션되는지 확인합니다. 이렇게하면 특정 컨트롤러에서 ExceptionHandler를 사용할 필요가 없지만 모든 컨트롤러에 전역으로 추가 할 수 있습니다. (AbstractController 클래스를 확장하여).

    편집하다: 다른 질문을 한 후, 당신이보기에 오류가 있다는 것을 알았습니다. 이 방법으로 그 오류를 잡을 지 모르겠다.

    희망이 도움이 !!

  4. from https://stackoverflow.com/questions/11245932/how-to-handle-exceptions-thrown-while-rendering-a-view-in-spring-mvc by cc-by-sa and MIT license