250225 TIL

2025. 2. 25. 16:40·TIL

예외 처리와 에러 핸들링

실행 중 예외가 일어났을 때 각각 예외를 받아 처리 해주는 컨트롤러 설정 

@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
'TIL' 카테고리의 다른 글
  • 250227 TIL
  • 250226 TIL
  • 250224 TIL
  • 250221 TIL
Jiyuuuuun
Jiyuuuuun
  • Jiyuuuuun
    Hello, World!
    Jiyuuuuun
  • 전체
    오늘
    어제
    • 분류 전체보기 (112)
      • TIL (56)
      • CS (17)
        • Network (4)
        • Algorithm (10)
      • JAVA (5)
      • Project (10)
        • HakPle (3)
        • JUSEYO (4)
      • Spring (2)
      • C (3)
      • C++ (16)
      • Snags (2)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JDBC
    HTML
    CSS
    javascript
    nginx
    java
    node.js
    부트캠프
    juseyo
    Docker
    react
    springboot
    멋쟁이사자처럼
    SQL
    JPA
    my_favorite_place
    back-end
    front-end
    hakple
    Kubernetes
    db
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jiyuuuuun
250225 TIL
상단으로

티스토리툴바