Springboot 사용자 정의 예외 처리 상세 정보

7223 단어 springboot이상
배경
Springboot은 기본적으로 이상한 처리를 모델 AndView에 집중시켰지만, 프로젝트의 실제 과정에서 이렇게 하면 우리의 요구를 만족시킬 수 없습니다.구체적인 사용자 정의 이상 처리는 다음과 같다.
구체적 실현
만약springboot의 이상 처리 상세한 설명을 자세히 보고 원본 코드를 연구한 후에 구체적인 실현은 보지 않아도 된다고 생각합니다...
오류 페이지를 정의하는 URL을 다시 씁니다. 기본값은/error입니다.

@Bean
  public EmbeddedServletContainerCustomizer containerCustomizer(){
    return new EmbeddedServletContainerCustomizer(){
      @Override
      public void customize(ConfigurableEmbeddedServletContainer container) {
        container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));
        container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
        container.addErrorPages(new ErrorPage(java.lang.Throwable.class,"/error/500"));
      }
    };
  }
다시 쓰기는 ErrorController를 실현하고 BasicErrorController를 다시 쓰는 기능을 통해 이루어진다

/**
 *  BasicErrorController, 
 * @see org.springframework.boot.autoconfigure.web.BasicErrorController
 * @see org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
 *
 * @author Jonathan
 * @version 2016/5/31 11:22
 * @since JDK 7.0+
 */
@Controller
@RequestMapping(value = "error")
@EnableConfigurationProperties({ServerProperties.class})
public class ExceptionController implements ErrorController {

  private ErrorAttributes errorAttributes;

  @Autowired
  private ServerProperties serverProperties;


  /**
   *  ExceptionController
   * @param errorAttributes
   */
  @Autowired
  public ExceptionController(ErrorAttributes errorAttributes) {
    Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
    this.errorAttributes = errorAttributes;
  }


  /**
   *  404 ModelAndView
   * @param request
   * @param response
   * @return
   */
  @RequestMapping(produces = "text/html",value = "404")
  public ModelAndView errorHtml404(HttpServletRequest request,
                 HttpServletResponse response) {
    response.setStatus(getStatus(request).value());
    Map<String, Object> model = getErrorAttributes(request,
        isIncludeStackTrace(request, MediaType.TEXT_HTML));
    return new ModelAndView("error/404", model);
  }

  /**
   *  404 JSON 
   * @param request
   * @return
   */
  @RequestMapping(value = "404")
  @ResponseBody
  public ResponseEntity<Map<String, Object>> error404(HttpServletRequest request) {
    Map<String, Object> body = getErrorAttributes(request,
        isIncludeStackTrace(request, MediaType.TEXT_HTML));
    HttpStatus status = getStatus(request);
    return new ResponseEntity<Map<String, Object>>(body, status);
  }

  /**
   *  500 ModelAndView
   * @param request
   * @param response
   * @return
   */
  @RequestMapping(produces = "text/html",value = "500")
  public ModelAndView errorHtml500(HttpServletRequest request,
                 HttpServletResponse response) {
    response.setStatus(getStatus(request).value());
    Map<String, Object> model = getErrorAttributes(request,
        isIncludeStackTrace(request, MediaType.TEXT_HTML));
    return new ModelAndView("error/500", model);
  }


  /**
   *  500 JSON 
   * @param request
   * @return
   */
  @RequestMapping(value = "500")
  @ResponseBody
  public ResponseEntity<Map<String, Object>> error500(HttpServletRequest request) {
    Map<String, Object> body = getErrorAttributes(request,
        isIncludeStackTrace(request, MediaType.TEXT_HTML));
    HttpStatus status = getStatus(request);
    return new ResponseEntity<Map<String, Object>>(body, status);
  }


  /**
   * Determine if the stacktrace attribute should be included.
   * @param request the source request
   * @param produces the media type produced (or {@code MediaType.ALL})
   * @return if the stacktrace attribute should be included
   */
  protected boolean isIncludeStackTrace(HttpServletRequest request,
                     MediaType produces) {
    ErrorProperties.IncludeStacktrace include = this.serverProperties.getError().getIncludeStacktrace();
    if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
      return true;
    }
    if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {
      return getTraceParameter(request);
    }
    return false;
  }


  /**
   *  
   * @param request
   * @param includeStackTrace
   * @return
   */
  private Map<String, Object> getErrorAttributes(HttpServletRequest request,
                          boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    return this.errorAttributes.getErrorAttributes(requestAttributes,
        includeStackTrace);
  }

  /**
   *  trace
   * @param request
   * @return
   */
  private boolean getTraceParameter(HttpServletRequest request) {
    String parameter = request.getParameter("trace");
    if (parameter == null) {
      return false;
    }
    return !"false".equals(parameter.toLowerCase());
  }

  /**
   *  
   * @param request
   * @return
   */
  private HttpStatus getStatus(HttpServletRequest request) {
    Integer statusCode = (Integer) request
        .getAttribute("javax.servlet.error.status_code");
    if (statusCode == null) {
      return HttpStatus.INTERNAL_SERVER_ERROR;
    }
    try {
      return HttpStatus.valueOf(statusCode);
    }
    catch (Exception ex) {
      return HttpStatus.INTERNAL_SERVER_ERROR;
    }
  }

  /**
   *  , 
   * @see ExceptionMvcAutoConfiguration#containerCustomizer()
   * @return
   */
  @Override
  public String getErrorPath() {
    return "";
  }

}

총결산
첫 번째 단계는containerCustomizer를 정의하여 이상 처리에 대응하는 보기를 다시 작성합니다.현재 404와 500이 정의되어 있으며, 계속 확장할 수 있습니다.
두 번째 단계는 Basic Error Controller를 다시 작성하면 일반적인 controller 클래스를 직접 정의하고 첫 번째 정의된 보기를 직접 실현하는 방법을 사용할 수 있다.다시 쓰는 목적은 ErrorAttributes를 다시 사용하는 것입니다.이렇게 하면 페이지에서status,message,exception,trace 등 내용을 직접 얻을 수 있습니다.
이상 처리된 보기만 정적 페이지로 하고 이상 정보 내용을 볼 필요가 없다면 첫 번째 단계에서 error/404,error/500 등 정적 보기를 정의하면 된다.
ErrorController는 Accept 헤더의 내용에 따라 다양한 형식의 오류 응답을 출력합니다.예를 들어 브라우저에 대한 요청은 html 페이지를 생성하고 다른 요청에 대한 json 형식의 반환을 생성한다
상기 두 단계의 조작은 인터넷에 떠도는 것보다 더욱 사용자 정의화를 실현할 수 있다.여러분의 학습에 도움이 되었으면 좋겠고, 여러분도 우리를 많이 지지해 주시기 바랍니다.

좋은 웹페이지 즐겨찾기