예외 처리와 에러 핸들링
실행 중 예외가 일어났을 때 각각 예외를 받아 처리 해주는 컨트롤러 설정
@ControllerAdvice
▪️@Controller가 붙은 일반 컨트롤러 (@RestController 포함) 을 대상으로 사용
▪️ 뷰와 데이터 모두 응답 가능
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public String handleIllegalArgumentException(IllegalArgumentException ex, Model model) {
model.addAttribute("errorMessage", ex.getMessage());
return "error-page"; // 뷰 이름 반환
}
}
▪️ IllegalArgumentException이 발생하면 "error-page"라는 뷰를 반환
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRunTimeException(RuntimeException e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error : "+ e.getMessage());
}
▪️ RuntimeException이 발생하면 JSON 응답을 반환
@RestControllerAdvice
▪️ @ControllerAdvice와 동일한 역할,
▪️ @RestController에서 발생하는 예외를 처리하고, 반환 타입을 JSON 형태로 응답
@RestControllerAdvice
public class GlobalRestExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Map<String, String>> handleIllegalArgumentException(IllegalArgumentException ex) {
Map<String, String> errorResponse = new HashMap<>();
errorResponse.put("error", "Invalid Argument");
errorResponse.put("message", ex.getMessage());
return ResponseEntity.badRequest().body(errorResponse);
}
}
▪️ IllegalArgumentException이 발생하면 JSON 응답을 반환
| 비교 항목 | @ControllerAdvice | @RestControllerAdvice |
| 적용 대상 | @Controller (일반 컨트롤러) | @RestController (REST API 컨트롤러) |
| 기본 응답 타입 | 뷰(String으로 뷰 이름 반환) | JSON (@ResponseBody 자동 포함) |
| 주 사용 목적 | HTML 페이지 기반 예외 처리 | REST API 응답(JSON) 예외 처리 |
public class ErrorTestController {
@GetMapping("/api/e")
public String test() {
throw new RuntimeException("API에서 에러가 발생");
}
}
파일 다운로드
@GetMapping("/download")
public void download(HttpServletResponse response) {
Path path=Paths.get("c:/LikeLion/cat.jpg");
response.setContentType("image/jpeg"); // 응답 타입을 JPEG 이미지로 지정
try (InputStream inputStream=Files.newInputStream(path)) {
StreamUtils.copy(inputStream, response.getOutputStream()); // 파일 데이터를 HTTP 응답 스트림에 복사
response.flushBuffer(); // 버퍼에 있는 데이터를 즉시 전송
} catch (IOException e) {
log.error("파일 다운로드 중 오류 발생" + e.getMessage()); // 예외 발생 시 로그 출력
}
}
📌 주요 개념
| Path path = Paths.get("c:/LikeLion/cat.jpg") | 하드 드라이브의 특정 경로에 저장된 파일을 Path 객체로 지정 |
| response.setContentType("image/jpeg") | 응답하는 데이터의 타입을 image/jpeg로 지정 |
| Files.newInputStream(path) | 파일을 읽기 위한 InputStream 생성 |
| StreamUtils.copy(inputStream, response.getOutputStream()) | 파일 데이터를 HTTP 응답 스트림으로 전송 |
| response.flushBuffer() | 버퍼에 있는 데이터를 즉시 클라이언트에게 전달 |
| log.error("파일 다운로드 중 오류 발생" + e.getMessage()); | 예외가 발생하면 로그를 기록 |
➕서버의 경로에 있는 파일을 보내면 서버를 재시작 해야 파일이 보임
▶️그래서 서버 밖 경로에 파일을 저장 해야 함
파일 업로드
GET 방식은 보낼 수 있는 데이터의 크기가 제한적이므로 POST 방식 사용
@PostMapping("/upload")
public ResponseEntity<String> upload(@RequestParam(name = "file") MultipartFile file) {
log.info(file.getContentType()); // 파일의 MIME 타입 출력
log.info(file.getOriginalFilename()); // 원본 파일명 출력
try (InputStream inputStream = file.getInputStream()) {
StreamUtils.copy(inputStream,
new FileOutputStream("c:/LikeLion/" + UUID.randomUUID().toString() + file.getOriginalFilename())); // 파일 저장
return ResponseEntity.ok().body("파일 저장 성공" + file.getOriginalFilename());
} catch (IOException e) {
return ResponseEntity.badRequest().body("파일 업로드 실패" + file.getOriginalFilename());
}
}
Spring Boot에서 파일 업로드를 처리할 때 MultipartFile을 사용
📌MultipartFile 주요 메서드
| getOriginalFilename() | 원본 파일명 반환 |
| getName() | <input type="file" name="file">에서 name 속성 값 반환 |
| getSize() | 파일 크기 반환 (byte 단위) |
| getContentType() | 파일의 MIME 타입 반환 (예: image/png, application/pdf) |
| getBytes() | 파일 데이터를 byte[] 배열로 반환 |
| getInputStream() | 파일 데이터를 읽을 수 있는 InputStream 반환 |
| transferTo(File dest) | 업로드된 파일을 dest 경로로 저장 |
📌 주요 개념
| @RequestParam(name = "file") MultipartFile file | 클라이언트에서 보낸 파일을 받음 |
| file.getInputStream() | 업로드된 파일을 읽기 위한 InputStream 생성 |
| new FileOutputStream("c:/LikeLion/" + UUID.randomUUID().toString() + file.getOriginalFilename()) | 파일을 UUID + 원본 파일명 형식으로 저장 |
| StreamUtils.copy(inputStream, new FileOutputStream(...)) | 파일 데이터를 새로운 파일로 복사 |
| ResponseEntity.ok().body("파일 저장 성공" + file.getOriginalFilename()) | 성공 시 200 OK 응답 반환 |
| ResponseEntity.badRequest().body("파일 업로드 실패" + file.getOriginalFilename()) | 실패 시 400 Bad Request 응답 반환 |
spring:
application:
name: restexam
servlet:
multipart:
max-file-size: 2MB
max-request-size: 4MB
한 요청 당 보낼 수 있는 파일 크기 제한 설정
'TIL' 카테고리의 다른 글
| 250227 TIL (0) | 2025.02.27 |
|---|---|
| 250226 TIL (0) | 2025.02.26 |
| 250224 TIL (1) | 2025.02.24 |
| 250221 TIL (1) | 2025.02.21 |
| 250220 TIL (0) | 2025.02.20 |