1. ProrityQueue
- Treeset과 Queue를 합쳐놓았다고 생각하면 편하다.
- 이진 정렬 법에 의해 원소를 넣으면서 정렬을 해준다.
- 아래 메서드 외에는 대체로 다른 큐와 set, list 등과 사용법은 비슷하다.
- poll() : iterater.next()와 같다고 생각하면 편하다. 우선순위가 제일 높은 원소를 추출하면서 큐에서 제거한다.
1) 클라이언트 패킷 전달, 서버 패킷 전달
- 출발지와 목적지를 가지고 노드들을 통해 전달된다.
2) IP 프로토콜의 한계
- 비연결성 : 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷 전송
- 비신뢰성 : 패킷이 중간에 사라지거나 패킷이 순서대로 안오면?
- 순서대로 명령을 보내도 각 패킷은 다른 노드를 탈 수 있다.
- 프로그램 구분 : 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상이면?
2. GlobalExceptionHandler
- GEH(globalExceptionHandler) 편의상 줄여서 작성
- GEH를 만들기전 'exception' package를 만들어 주자
- 패키지 경로와 import 들은 적어주지 않았다.
1) GlobalExceptionHandler작성
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
Map<String, String> errors = new HashMap<>();
List<FieldError> allErrors = exception.getBindingResult().getFieldErrors();
log.error("MethodArgumentNotValidException throw Exception : {}", BAD_REQUEST);
for (int i = allErrors.size() - 1; i >= 0; i--) {
errors.put(allErrors.get(i).getField(), allErrors.get(i).getDefaultMessage());
}
return ResponseEntity
.status(BAD_REQUEST)
.body(errors);
}
@ExceptionHandler(value = {CustomException.class})
public ResponseEntity<ErrorResponse> handleCustomException(CustomException exception) {
log.error("CustomException throw Exception : {}", exception.getErrorCode());
return ErrorResponse.toResponseEntity(exception.getErrorCode());
}
}
2) CustomException 작성
@Getter
public class CustomException extends RuntimeException{
private final ErrorCode errorCode;
public CustomException(ErrorCode errorCode){
super(errorCode.getMsg());
this.errorCode = errorCode;
}
}
3) ErrorCode 작성
@Getter
@AllArgsConstructor
public enum ErrorCode {
NOT_CONGITION_USERNAME(HttpStatus.BAD_REQUEST, "닉네임이 조건에 맞지 않습니다."),
NOT_CONGITION_PASSWORD(HttpStatus.BAD_REQUEST, "비밀번호가 조건에 맞지 않습니다."),
INVALID_TOKEN(HttpStatus.UNAUTHORIZED, "토큰이 유효하지 않습니다."),
AUTHORIZATION(HttpStatus.UNAUTHORIZED, "수정/삭제할 수 있는 권한이 없습니다."),
DUPLICATED_USERNAME(HttpStatus.BAD_REQUEST, "중복된 username 입니다"),
NOT_FOUND_USER(HttpStatus.NOT_FOUND, "회원을 찾을 수 없습니다."),
NOT_FOUND_BOARD(HttpStatus.NOT_FOUND, "게시글을 찾을 수 없습니다."),
NOT_FOUND_REPLY(HttpStatus.NOT_FOUND, "댓글을 찾을 수 없습니다."),
DUPLICATE_USER(HttpStatus.BAD_REQUEST, "중복된 닉네임입니다."),
NOT_MATCH_PASSWORD(HttpStatus.BAD_REQUEST, "비밀번호가 일치하지 않습니다."),
NOT_MATCH_USERNAME(HttpStatus.BAD_REQUEST, "토큰이 일치하지 않습니다."),
INVALID_ADMIN_TOKEN(HttpStatus.BAD_REQUEST, "관리자 등록 비밀번호가 일치하지 않습니다."),
NOT_FOUND_TOKEN (HttpStatus.NOT_FOUND, "토큰을 찾을 수 없습니다."),
NO_AUTHORITY(HttpStatus.NOT_FOUND, "토큰을 찾을 수 없습니다.");
private final HttpStatus httpStatus;
private final String msg;
}
- 커스텀한 에러코드들에 대해서 알맞은 HttpStatus를 지정해주고, msg도 작성해주어야한다.
4) ErrorResponse
@Getter
@Builder
public class ErrorResponse {
private final int status;
private final String message;
public static ResponseEntity<ErrorResponse> toResponseEntity(ErrorCode errorCode) {
return ResponseEntity
.status(errorCode.getHttpStatus())
.body(ErrorResponse.builder()
.status(errorCode.getHttpStatus().value())
.message(errorCode.getMsg())
.build());
}
}