TIL 23 [ Spring ( 응답 데이터, 메모장 만들기 실습 ) + 스탠다드반 ( 예외처리 )]

2025. 3. 20. 21:29·[내일배움캠프-Sparta]/Spring 6기
반응형

1. 학습내용
16:00 ~ 17:00 스탠다드반 특강 ( 김재연 튜터님 )

응답 데이터

Server에서 Client로 Data를 전달하는 방법

[1] 정적 리소스

  • 정적인 HTML, CSS, JS, Image 등을 변경 없이 그대로 반환한다.

[2] View Template

  • SSR(Server Side Rendering)을 사용할 때 View가 반환된다.

📌 View Template

  • View Template은 Model을 참고하여 HTML 등이 동적으로 만들어지고 Client에 응답된다.
  • Spring Boot는 기본적으로 View Template 경로(src/main/resources/templates)를 설정한다.
  • build.gradle에 Thymeleaf 의존성을 추가하면 ThymeleafViewResolver와 필요한 Spring Bean들이 자동으로 등록된다. 
  1. @Controller의 응답으로 String을 반환하는 경우
    • @ResponseBody 가 없으면 View Resolver가 실행되며 View를 찾고 Rendering한다.
    • @ResponseBody 가 있으면 HTTP Message Body에 return 문자열 값이 입력된다.
  2. 반환 타입이 void인 경우
    • 잘 사용하지 않는다.
    • @Controller + (@ResponseBody, HttpServletResponse, OutputStream)과 같은 HTTP Message Body를 처리하는 파라미터가 없으면 RequestMapping URL을 참고하여 View Name으로 사용한다.

[3] HTTP Message Body

  • 응답 데이터를 직접 Message Body에 담아 반환한다.

▶ HTTP Message Body(응답) 

[1] HttpServletResponse 사용

@Controller
public class ResponseBodyController {
	
    @GetMapping("/v1/response-body")
    public void responseBodyV1 (
    	HttpServletResponse response
    )  
    throws IOException {
    	response.getWriter().write("data");
    }
}

[2] ResponseEntity<> 사용 

@GetMapping("/v2/response-body")
public ResponseEntity<String> responseBodyV2() {
	return new ResponseEntity<>("data", HttpStatus.OK);
}

 

  • Response Body에 data라는 문자열과 HttpStatus.OK에 해당하는 상태 코드를 반환한다. ★
  • ResponseEntity는 HttpEntity 를 상속받았다.
    • HttpEntity는 HTTP Message의 Header, Body 모두 가지고 있다.

[3] @ResponseBody(TEXT, JSON) 사용

@Data
@NoArgsConstructor // 기본 생성자
@AllArgsConstructor // 전체 필드를 인자로 가진 생성자
public class Tutor {

    private String name;
    private int age;

}

Tutor 클래스

// TEXT 데이터 통신
@ResponseBody
@GetMapping("/v3/response-body-text")
public String responseBodyText() {
		
	return "data"; // HTTP Message Body에 "data"
}
// JSON 데이터 통신
@ResponseStatus(Httpstatus.OK)
@ResponseBody
@GetMapping("/v3/response-body-json")
public Tutor responseBodyJson() {
		
	Tutor tutor = new Tutor("wonuk", 100);
		
	return tutor; // HTTP Message Body에 Tutor Object -> JSON
}
  • View를 사용하는 것이 아닌 HTTP Message Converter를 통해 HTTP Message Body를 직접 입력할 수 있다. → ResponseEntity와 같음(==)
  • @ResponseStatus 를 사용하여 상태 코드를 지정할 수 있다

[4] ResponseEntity<Object>(JSON)  ★ ★

@ResponseBody
@GetMapping("/v5/response-body")
public ResponseEntity<Tutor> responseBody() {
		
	Tutor tutor = new Tutor("wonuk", 100);
	
	return new ResponseEntity<>(tutor, HttpStatus.OK);
}
  • ResponseEntity<> 두 번째 파라미터에 Enum을 사용하여 상태 코드를 바꿀 수 있다.
  • HTTP Message Converter를 통하여 JSON 형태로 변환되어 반환된다.
  • 동적으로 응답 코드를 변경할 수 있다.

정리

Client에서 Server로 Data를 전달하는 세가지 방법

[1] GET - Query Param, Query String

ex) http://localhost:8080/tutor?name=wonuk&age=100

  • 사용하는 어노테이션
    • @RequestParam, @ModelAttribute

[2] POST - HTML Form(x-www-form-urlencoded)

 

 

Server(Spring)에서 HTTP 응답을 Client에 전달하는 세가지 방법

  1. 정적 리소스
    • 정적인 HTML, CSS, JS, Image 등을 변경없이 그대로 반환한다.
  2. View Template
    • SSR(Server Side Rendering)을 사용할 때 View가 반환된다.
    • 사용하는 어노테이션
      • @Controller
  3. HTTP Message Body
    • 응답 데이터를 직접 Message Body에 담아 반환한다.
    • 사용하는 어노테이션
      • @ResponseBody, ResponseEntity<Object>

  • 요청
    • @RequestParam, @ModelAttribute, @RequestBody
  • 응답
    • 정적 리소스, View Template(@Controller), @ResponseBody, ResponseEntity<Object>

메모장 만들기 (실습)

[1] 요구사항 분석 및 설계

  • 메모장 API 요구사항
    1. 통신 데이터 형태는 JSON이다.
    2. 각각의 메모는 식별자(id), 제목(title), 내용(contents)으로 구성되어 있다.
    3. 응답을 각각의 API에 알맞게 해야 한다.
    4. 메모를 생성할 수 있다. (CREATE)
      • 메모 생성 시 제목, 내용이 필요하다.
      • 생성된 데이터(식별자, 제목, 내용)가 응답된다.
    5. 메모 전체 목록을 조회할 수 있다. (READ)
      • 여러 개의 데이터를 배열 형태로 한번에 응답한다.
      • 데이터가 없는 경우 비어있는 배열 형태로 응답한다.
    6. 메모 하나를 조회할 수 있다. (READ)
      • 조회할 memo에 대한 식별자 id값이 필요하다.
      • 조회된 데이터가 응답된다.
      • 조회될 데이터가 없는 경우 Exception이 발생한다.
    7. 메모 하나를 전체 수정(덮어쓰기)할 수 있다. (UPDATE)
      • 수정할 memo에 대한 식별자 id값이 필요하다.
      • 수정할 요청 데이터(제목, 내용)가 꼭 필요하다.
      • 수정된 데이터가 응답된다.
      • 수정될 데이터가 없는 경우 Exception이 발생한다.
    8. 메모 하나의 제목을 수정(일부 수정)할 수 있다. (UPDATE)
      • 수정할 memo에 대한 식별자 id값이 필요하다.
      • 수정할 요청 데이터(제목)가 꼭 필요하다.
      • 수정된 데이터가 응답된다.
      • 수정될 데이터가 없는 경우 Exception이 발생한다.
    9. 메모를 삭제할 수 있다. (DELETE)
      • 삭제할 memo에 대한 식별자 id값이 필요하다.
      • 삭제될 데이터가 없는 경우 Exception이 발생한다.

HTTP API 설계

== 메모장 다루는 기능관련은  ( 생략 )==  

♣ 일반 void와 Void타입 차이점

  • void: 반환값이 없는 메서드를 정의할 때 사용되는 키워드
  • Void: 반환 타입이지만 실제로는 값이 없는 상황에서 사용되는 클래스, 주로 제네릭 타입에서 사용

문제점

  • Controller에 책임이 너무 많다.(요청, 비지니스 로직, 응답, 예외 처리 등)
  • 서버가 종료된 후 다시 켜지면 데이터가 모두 초기화 된다.  ( DB가 없기 때문 )

{ 스탠다드반 }  

예외처리

자바의 예외처리

예외 자체를 의미하는 Exception 클래스, 그리고 예외를 핸들링하기 위한 try-catch가 있다.

자바에서 Exception은 다시 2가지로 나뉩니다.

 

Checked Exception

  • 반드시 try-catch나 상위 메소드로 throws 처리를 해야 하는 예외를 말합니다. 처리를 하지 않고 컴파일을 시도하면 오류가 발생하며 실패 합니다.

UnChecked Exception

  • Exception을 처리하지 않아도 컴파일이 가능하고 프로그램 실행도 정상적으로 됩니다.

 

  장점 단점
Checked Exception - 예외 처리 강제 → 코드 안정성 향상
- 예외 발생 가능성을 명확히 문서화
- 가독성이 떨어짐 → 코드 생산성 하락
- 불필요한 예외 처리로 코드 복잡성 증가
UnChecked Exception - 단순하고 가독성 높은 코드 작성 가능
- 필요할 때만 예외 처리
- 예외를 누락할 가능성 존재
- 시스템의 신뢰도 하락

 

Spring Boot의 예외처리

  • Exception을 발생시킨다
  • 유효성 검증을 한다

Spring Boot 예외처리 방법

  1. try-catch (Spring은 자바 기반이므로 자바와 동일한 try-catch를 씁니다)
  2. @ExceptionHandler, @ControllerAdvice
  3. @Valid, @Validated
  4. 그 외 유용한 유효성 어노테이션

@ExceptionHandler, @ControllerAdvice ★

  • @ExceptionHandler : 하나의 Controller 만 예외 핸들링 
  • @ControllerAdvice : 모든 Controller에서 발생하는 예외 핸들링
/* @ExceptionHandler */
@RestController
public class SampleController {
    @GetMapping("/test")
    public String test() {
        throw new IllegalArgumentException("Invalid input!");
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
        return ResponseEntity.badRequest().body("Error: " + ex.getMessage());
    }
}

@RestController
public class DemoController {
    @GetMapping("/demo")
    public String demo() {
        throw new IllegalArgumentException("Invalid input!");
    }
}

/* @ControllerAdvice */

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
        return ResponseEntity.badRequest().body("Global Error: " + ex.getMessage());
    }
}

@RestController
public class SampleController {
    @GetMapping("/test")
    public String test() {
        throw new IllegalArgumentException("Invalid input!");
    }
}

@RestController
public class DemoController {
    @GetMapping("/demo")
    public String demo() {
        throw new IllegalArgumentException("Invalid input!");
    }
}

@Valid, @Validated ★

데이터를 검증하기 위한 어노테이션 입니다.

이를 활성화 하기 위해서는 아래 의존성을 추가 해야 합니다.

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
implementation 'org.springframework.boot:spring-boot-starter-validation:3.3.5'

@Valid 예시

@RestController
public class UserController {
  @PostMapping("/user")
  public ResponseEntity<String> createUser(@RequestBody @Valid UserDto userDto){
        return ResponseEntity.ok("User is valid!");
  }
}

@Getter
public class UserDto {
    private Long id;
    @Min(20)
    private Long age;

    @Override
    public String toString() {
        return "UserDto{id=" + id + ", age=" + age + '}';
    }
}

@Validated 예시

@Validated
@RestController
public class ValidatedController {
    @PostMapping("/test-validated/number")
    public String testValid(@Min(10) Integer number, @RequestBody @Valid UserDto userDto) {
        return number + " : " + userDto.toString();
    }
}

@Getter
public class UserDto {
    private Long id;
    @Min(20)
    private Long age;

    @Override
    public String toString() {
        return "UserDto{id=" + id + ", age=" + age + '}';
    }
}

그외 유용한 검증 어노테이션

보통 클래스내 필드위에 선언한다. 이 외에도 많이 존재 @Notnull 등

 - 새롭게 알게 된 점 ★

요청 값들은 매개변수로 응답 값은 반환타입으로 주로 쓰인다.
@RequestBody는 거의 j문자열, JSON (90%이상) 형태의 데이터들이 무수히 반환되는 값이며,

@RequestParam은 QueryParameter (?name=kim&age=20) 나 Form x-www-form-urlencoded

@ResponseEntity<{객체}>는 상태코드를 나타낼떄 많이 쓰임 Httpstatus.OK(200) , Httpstatus.NOT_FOUND(404) 등.

2. 내일 학습 할 것: 스프링 입문(6주차) , 알고리즘, 일정관리 앱 과제 명세서 만들기 

 

반응형

'[내일배움캠프-Sparta] > Spring 6기' 카테고리의 다른 글

TIL 25 [ Spring 일정 관리 앱 과제 ( 필수 . . . JDBC..??) + 미니세션 ( API, ERD ) ]  (0) 2025.03.24
TIL 24 [ Spring ( 3 Layer 아키텍처, DB, SQL, JDBC, SQL Mapper ) ]  (0) 2025.03.21
TIL 22 [ Spring ( 어노테이션II, Request Mapping, 요청 데이터) ]  (0) 2025.03.19
TIL 21 [ Spring( 어노테이션, lombok, 프레임워크, 빌드 도구, 웹 기술 역사 + 스탠다드반 (Spring MVC) ]  (0) 2025.03.18
TIL 20 [ Spring( 네트워크, 용어, HTTP, Rest API ) ]  (0) 2025.03.17
'[내일배움캠프-Sparta]/Spring 6기' 카테고리의 다른 글
  • TIL 25 [ Spring 일정 관리 앱 과제 ( 필수 . . . JDBC..??) + 미니세션 ( API, ERD ) ]
  • TIL 24 [ Spring ( 3 Layer 아키텍처, DB, SQL, JDBC, SQL Mapper ) ]
  • TIL 22 [ Spring ( 어노테이션II, Request Mapping, 요청 데이터) ]
  • TIL 21 [ Spring( 어노테이션, lombok, 프레임워크, 빌드 도구, 웹 기술 역사 + 스탠다드반 (Spring MVC) ]
dimenshun
dimenshun
한 소년의 개발 일기
    반응형
  • dimenshun
    Dev Life Notes
    dimenshun
  • 전체
    오늘
    어제
    • 분류 전체보기 (268)
      • CS (23)
        • 자료구조 (0)
        • 알고리즘 (0)
        • 컴퓨터 구조 (8)
        • 네트워크 (6)
        • 운영체제 (3)
        • DB ( + SQLD ) (5)
        • SW공학 (1)
      • 프로그래밍 (3)
        • Java (0)
        • Spring (0)
        • HTML,CSS (3)
        • JavaScript (0)
      • 개발 툴 (7)
        • Git(버전관리) (1)
        • Docker (3)
        • AWS (2)
        • JSP (1)
      • 코딩테스트(Algorithm) (125)
        • 백준 (6)
        • 프로그래머스 (119)
      • [내일배움캠프-Sparta] (110)
        • Spring 6기 (106)
        • KPT 회고 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    개발자
    AWS
    OS
    운영체제
    백엔드
    컴퓨터구조
    Java
    It
    웹
    세션
    SQLD
    트랜잭션
    메모리
    spring
    SQL
    network
    docker
    Testcode
    알고리즘
    cs
    내일배움캠프
    배포
    web
    KPT
    Til
    Python
    네트워크
    코딩테스트
    db
    CPU
  • hELLO· Designed By정상우.v4.10.3
dimenshun
TIL 23 [ Spring ( 응답 데이터, 메모장 만들기 실습 ) + 스탠다드반 ( 예외처리 )]
상단으로

티스토리툴바