Springboot 오류 처리 메커니즘 실현 원리 분석
기본 효과
① 브 라 우 저 에서 존재 하지 않 는 요청 에 접근 할 때 springboot 는 기본적으로 빈 페이지 로 돌아 갑 니 다.
브 라 우 저의 요청 헤더
② 클 라 이언 트 가 접근 할 때 json 데 이 터 를 되 돌려 줍 니 다.
{
"timestamp": "2020-03-24T02:49:56.572+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/"
}
클 라 이언 트 접근 요청 헤더의 원리
ErrorMvcAutoConfiguration 오류 처리 자동 설정 참조
용기 에 다음 구성 요 소 를 추가 하 였 습 니 다.
1.DefaultErrorAttributes
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap();
errorAttributes.put("timestamp", new Date());
this.addStatus(errorAttributes, webRequest);
this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
this.addPath(errorAttributes, webRequest);
return errorAttributes;
}
@RequestMapping(
produces = {"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = this.getStatus(request);
// model ,
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
return modelAndView != null ? modelAndView : new ModelAndView("error", model);
}
// AbstractErrorController#getErrorAttributes
protected Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
WebRequest webRequest = new ServletWebRequest(request);
return this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
}
DefaultErrorAttributes#getErrorAttributes
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
2.Basic ErrorController:기본/error 요청 처리
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
private final ErrorProperties errorProperties;
public String getErrorPath() {
return this.errorProperties.getPath();
}
@RequestMapping(
produces = {"text/html"} // html ,
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
//
HttpStatus status = this.getStatus(request);
//
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
// ,
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
return modelAndView != null ? modelAndView : new ModelAndView("error", model);
}
@RequestMapping // json ,
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = this.getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity(status);
} else {
Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
return new ResponseEntity(body, status);
}
}
3.ErrorPageCustomizer
public class ErrorProperties {
@Value("${error.path:/error}")
private String path = "/error"; // /error ,( web.xml )
4.DefaultErrorViewResolver
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model);
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model);
}
return modelAndView;
}
private ModelAndView resolve(String viewName, Map<String, Object> model) { // springboot error/404
String errorViewName = "error/" + viewName; //
TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext); // errorViewName
return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model);
}
// errorViewName error/404.html
private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
String[] var3 = this.resourceProperties.getStaticLocations();
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
try {
Resource resource = this.applicationContext.getResource(location);
resource = resource.createRelative(viewName + ".html"); // ,
if (resource.exists()) {
return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model);
}
} catch (Exception var8) {
}
}
return null;
}
단계:시스템 에 4xx 또는 5xx 와 같은 오류 가 발생 하면 ErrorPageCustomizer 가 유효 합 니 다(잘못된 응답 규칙 을 맞 춤 형 으로 설정)./error 에 요청 하면 Basic ErrorController 에 의 해 발생 합 니 다.
처리
① 응답 페이지 에서 어느 페이지 로 갈 지 는 Default ErrorView Resolver 가 결정 합 니 다.
protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map<String, Object> model) {
Iterator var5 = this.errorViewResolvers.iterator(); // ErrorViewResolver modelAndView
ModelAndView modelAndView;
do {
if (!var5.hasNext()) {
return null;
}
ErrorViewResolver resolver = (ErrorViewResolver)var5.next();
modelAndView = resolver.resolveErrorView(request, status, model);
} while(modelAndView == null);
return modelAndView;
}
2.잘못된 정보의 맞 춤 형 제작① 잘못된 페이지 를 만 드 는 방법
1>템 플 릿 엔진 이 있 는 경우:error/상태 코드;[오류 페이지 를 오류 코드 라 고 명명 합 니 다.html 를 템 플 릿 엔진 폴 더 아래 에 있 는 error 폴 더 아래 에 놓 습 니 다.]이 상태 코드 의 오류 가 발생 하면 옵 니 다.
대응 하 는 페이지;
우 리 는 4xx 와 5xx 를 오류 페이지 의 파일 이름 으로 사용 하여 이러한 유형의 원 하 는 오 류 를 일치 시 킬 수 있 습 니 다.정확 한 상태 코드 를 우선 찾 습 니 다.html).
페이지 에서 얻 을 수 있 는 정보
타임 스탬프:타임 스탬프
status:상태 코드
예외:예외 대상
메시지:이상 메시지
errors:JSR 303 데이터 검증 오류 가 여기 있 습 니 다.
2>.템 플 릿 엔진 이 없습니다(템 플 릿 엔진 에서 이 페이지 를 찾 을 수 없습니다).정적 자원 폴 더 에서 찾 습 니 다.
3>.이상 오류 페이지 가 없 으 면 기본적으로 springboot 기본 오류 페이지 로 갑 니 다.
②、사용자 정의 이상 처리&맞 춤 형 제 이 슨 데이터 되 돌려 주기;
@ControllerAdvice
public class MyExceptionHandler {
@ResponseBody
@ExceptionHandler(UserNotExistException.class)
public Map<String,Object> handleException(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","user.notexist");
map.put("message",e.getMessage());
return map;
}
}
// , ( , json )
2),전송/error 적응 응답 효과 처리
@RequestMapping(
produces = {"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { // , , ? =======》 , ……
HttpStatus status = this.getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value()); // , , ( 200 , 4xx 5xx )
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
return modelAndView != null ? modelAndView : new ModelAndView("error", model);
}
@ExceptionHandler(UserNotExistException.class)
public String handleException(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
<strong>// 4xx 5xx, </strong>
/**
* Integer statusCode = (Integer) request
.getAttribute("javax.servlet.error.status_code");
*/
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code","user.notexist");
map.put("message",e.getMessage());
// /error
return "forward:/error";
}
3)、우리 의 맞 춤 형 데 이 터 를 가지 고 나 간다.model 의 값 을 수정 하면 됩 니 다.오류 가 발생 하면/error 요청 이 올 것 입 니 다.Basic ErrorController 에 의 해 처 리 됩 니 다.응답 하면 얻 을 수 있 는 데 이 터 는 getErrorAttributes 에서 얻 을 수 있 습 니 다(AbstractErrorController(ErrorController)에 규정된 방법 입 니 다).
1.ErrorController 의 실현 클래스 를 완전히 작성 하거나 AbstractErrorController 의 하위 클래스 를 작성 하여 용기 에 넣 습 니 다.
2.페이지 에 사용 할 수 있 는 데이터 나 json 이 사용 할 수 있 는 데 이 터 를 되 돌려 주 는 것 은 모두 error Attributes.getError Attributes 를 통 해 얻 을 수 있 습 니 다.
용기 에 있 는 DefaultErrorAttributes.getErrorAttributes();기본적으로 데이터 처리 하기;
사용자 정의 오류 속성
// ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
map.put("company","atguigu");
return map;
}
}
최종 효과:응답 은 자가 적응 입 니 다.ErroAttributes 를 통 해 되 돌아 갈 내용 을 바 꿀 수 있 습 니 다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.