zuul 이상 처리
우선, 우 리 는 다음 과 같은 몇 가 지 를 알 아야 한다.
SendErrorFilter
입 니 다. 이 필 터 는 실제 적 으로 이상 처 리 를 '/ error' 라 는 경로 로 전송 하 는 것 입 니 다 BasicErrorController
입 니 다. '/ error' 라 는 경 로 를 비 추 었 습 니 다. 이 contrller 는 이상 한 처리 에 대해 다음 과 같 습 니 다. 비 rest 방식 에 대해 오류 페이지 를 되 돌려 줍 니 다.rest 방식 에 대해 json 을 되 돌려 줍 니 다.(spring boot 를 해 본 사람 은 어떤 오류 페이지 나 어떤 json 인지 알 것 이다) 전제 가 끝 난 후에 우 리 는 본 고의 배경 을 이야기 합 니 다. 업무 의 실제 수요 에 따라 우 리 는 zuul 에서 filter 를 정 의 했 습 니 다. 만약 에 어떤 요청 이 이 filter 의 여과 조건 을 만족 시 키 지 못 하면 클 라 이언 트 에 게 사용자 정의 json 형식의 오류 코드 를 되 돌려 줍 니 다.
필터 에 설 정 된 조건 이 충족 되 지 않 을 때 사용자 정의 이상 을 던 지 는 것 이 우리 의 사고방식 이다.앞서 소개 한 바 에 따 르 면 이 이상 은 zuul 에 내 장 된 처리 이상 filter
SendErrorFilter
에 의 해 포착 되 어 spring boot 에 맡 길 수 있 습 니 다.그러나 springboot 의 기본 반환 결 과 는 우리 가 원 하 는 것 이 아 닙 니 다. 사용자 정의 오류 코드 와 오류 메 시 지 를 포함 한 json 을 되 돌려 주 고 싶 습 니 다.그렇다면 우 리 는 어떻게 이 룰 수 있 을 까?본 논문 의 사 고 는 springboot 의 기본 처리 이상 한 contrller BasicErrorController
를 덮어 쓰 는 것 입 니 다.다음은 코드 를 보 겠 습 니 다.
@Component
public class AccessTimeFilter extends ZuulFilter {
/**
*
*/
private static final LocalTime NOW = LocalTime.now();
/**
*
*/
private static final LocalTime ZERO_CLOCK = LocalTime.of(0, 0);
/**
*
*/
private static final LocalTime TWENTY_CLOCK = LocalTime.of(20, 0);
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER - 5;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
if (NOW.isAfter(ZERO_CLOCK) && NOW.isBefore(TWENTY_CLOCK)) {
// 0-20 ,
throw new GatewayException(ApiResponseCode.CODE_INVALID_ACCESS_TIME);
}
return null;
}
}
GatewayException
을 살 펴 보 세 요. 이 이상 은 우리 의 오류 와 오류 메 시 지 를 포장 합 니 다 /**
*
*
* {@link ZuulException}
*
* {@link com.netflix.zuul.FilterProcessor#processZuulFilter(ZuulFilter)}
*/
public class GatewayException extends ZuulException {
public GatewayException(ApiResponseCode apiResponseCode) {
super(apiResponseCode.getMessage(), apiResponseCode.getCode(),
apiResponseCode.getMessage());
}
public GatewayException(int code, String message) {
super(message, code, message);
}
}
@RestController
public class GatewayErrorController implements ErrorController {
/**
* zuul
*
* @param request HTTP
* @return API
*/
@RequestMapping
public ApiResponse error(HttpServletRequest request, HttpServletResponse response) {
Integer code = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
String message = " ";
if (exception instanceof ZuulException) {
message = exception.getMessage();
}
response.setStatus(HttpStatus.OK.value());
return new ApiResponse<>(code, message);
}
@Override
public String getErrorPath() {
return "/error";
}
}
핵심 코드 는 여기까지 입 니 다. 효 과 를 보 겠 습 니 다.
{
"code": 912,
"message": " , "
}
마지막 으로 코드 에 대해 다음 과 같은 몇 가지 설명 이 필요 합 니 다.
ZuulException
.최초 로 제 가 쓴 사용자 정의 이상 은 계승 되 지 않 았 습 니 다 ZuulException
. 이때 돌아 오 는 오류 코드 가 항상 500 인 것 을 발 견 했 습 니 다. 조 사 를 통 해 원인 을 찾 았 습 니 다. FilterProcessor
에는 다음 몇 줄 의 코드 가 있 습 니 다.이 를 통 해 알 수 있 듯 이 포 획 된 이상 이 ZuulException
의 인 스 턴 스 라면 직접 던 집 니 다.그렇지 않 으 면 포 획 된 이상 포장 을 ZuulException
으로 만들어 다시 던진다.문 제 는 캡 처 된 이상 ZuulException
의 인 스 턴 스 가 아 닐 때 zuul 은 오류 코드 를 500 으로 설정 합 니 다 (아래 코드 참조).그래서 우 리 는 사용자 정의 이상 계승 ZuulException
을 선택 합 니 다. } catch (Throwable e) {
if (bDebug) {
Debug.addRoutingDebug("Running Filter failed " + filterName + " type:" + filter.filterType() + " order:" + filter.filterOrder() + " " + e.getMessage());
}
usageNotifier.notify(filter, ExecutionStatus.FAILED);
if (e instanceof ZuulException) {
throw (ZuulException) e;
} else {
ZuulException ex = new ZuulException(e, "Filter threw Exception", 500, filter.filterType() + ":" + filterName);
ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);
throw ex;
}
}
Integer code = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
그럼 왜 이렇게 할 수 있 을까요?
SendErrorFilter
에서 어떻게 처 리 했 는 지 보면 알 수 있다.request.setAttribute("javax.servlet.error.status_code", exception.getStatusCode());
log.warn("Error during filtering", exception.getThrowable());
request.setAttribute("javax.servlet.error.exception", exception.getThrowable());
RequestContext
에 이런 코드 가 있 습 니 다. /**
* Use this instead of response.setStatusCode()
*
* @param nStatusCode
*/
public void setResponseStatusCode(int nStatusCode) {
getResponse().setStatus(nStatusCode);
set("responseStatusCode", nStatusCode);
}
이 를 통 해 알 수 있 듯 이 HTTP 응답 코드 의 값 을
nStatusCode
의 값 으로 설정 합 니 다. 이상 이 발생 했 을 때 이 nStatusCode
의 값 은 이상 한 상태 코드 (아래 SendErrorFilter
의 코드 참조) 입 니 다.이것 은 분명히 우리 가 원 하 는 것 이 아니다.그래서 간단하게 말하자면, 우 리 는 컨트롤 러 에서 응답 코드 를 200 으로 설정 합 니 다. if (dispatcher != null) {
ctx.set(SEND_ERROR_FILTER_RAN, true);
if (!ctx.getResponse().isCommitted()) {
// HTTP
ctx.setResponseStatusCode(exception.getStatusCode());
dispatcher.forward(request, ctx.getResponse());
}
}
request.setAttribute("javax.servlet.error.status_code", exception.getStatusCode());
위 코드 의
exception.getStatusCode()
기본 값 은 다음 과 같 습 니 다. default int getStatusCode() {
return HttpStatus.INTERNAL_SERVER_ERROR.value();
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.