📌 @Controller 및 @RestController의 차이
@Controller
: SpringMVC의 기본 컨트롤러 어노테이션으로
웹 어플리케이션에서 HTTP 요청을 처리하는 역할
- 특징 및 사용법
- View 템플릿을 반환(MVC 패턴의 V)
ModelAndView
,String
,Model
,Map
등을 반환할 수 있음- 이를 통해 데이터를 뷰로 전달하고 뷰를 렌더링할 수 있음
- 반환된 뷰 이름은
ViewResolver
에 의해 해석되어 최종적으로 사용자에게 보여질 페이지를 생성함
@RestController
: @Controller와 @ResponseBody를 결합한 것으로, RESTful 웹서비스를 쉽게 만들 수 있도록 함
클래스가 HTTP 요청을 처리하고 데이터를 JSON or XML 형태로 클라이언트에게 직접 반환
- 특징 및 사용법
- 각 메서드가 기본적으로 HTTP 응답 본문에 데이터 매핑
HTTPMEssageCOnverter
사용해 반환된 객체를 HTTP 응답 본문으로 사용함. 이 과정에서 객체는 JSON, XML로 자동 변환- REST API를 개발할 때 주로 사용되며, 클라이언트에게 데이터 모델 자체를 반환하는데 적합
1️⃣ 차이점
- 응답 처리
Controller
은 View 반환에 중점을 두고, 웹페이지를 반환하는 데 사용RestController
는 RESTful API 구현에 사용, JSON이나 XML 등의 형태로 데이터를 직접 반환
- 뷰 렌더링
@Controller
와 함께 사용되는 메서드는 View 이름을 반환하고, ViewREsolver
통해 뷰를 렌더링함.@REstController
의 메서드는 뷰 렌더링 없이 데이터 자체를 반환
2️⃣ RESTController의 처리 과정
Client가 지정 URL로 GET 요청을 보냄
-> DispatcherServlet이 요청을 받아 처리 ->
HANdlerMapping 사용해 요청 URL에 해당하는 핸들러 찾음
-> HandlerMapping은 요청 처리할 RestController의 메서드에 관한 정보를 DispatcherServlet에 반환
-> DispatcherServlet이 HandlerAdapter 통해 실제 메서드 호출
RestController의 메서드가 요청을 처리하고 응답 맵을 생성해 반환
DispatcherSErvlet이 HttpMessageConverter을 사용해 반환된 맵을 JSON 형식으로 변환
JSON 데이터는 DispathcerServlet을 통해 클라이언트에게 반환
📌 RESTful
1️⃣ 서비스 개념
웹 서비스의 한 형태로 Representational State Transfer(REST) 아키텍처 스타일을 따름
웹 서비스를 구성하는데 사용되는 잉ㄹ련의 제약 조건을 기반으로, 시스템의 단순화, 확장 가능성, 상호 운용 가능성을 위해 설계됨
✅ 주요 원칙
- 자원(Resource) 기반 :
- 모든 콘텐츠가 자원으로 표시되어, URI(Uniform Resource Identifier)로 식별됨.
- 무상태
- 각 요청은 독립적이며, 서버는 클라이언트의 상태 정보를 저장하지 않음.
- 서버 설계의 단순화 및 서비스 확장성을 위함
- 연결성
- 자원은 하이퍼링크를 통해 서로 연결될 수 있음
- HATEOAS(Hypermedia As The Engine Of Application State)
- 표준 메서드 사용
- HTTP 표준 메서드(GET, POST, PUT, DELETE) 통해 리소스에 대한 CURD 작업을 수행함.
- 다양한 표현
- JSON, XML 등 여러 형태의 데이터 포맷을 지원해 클라이언트의 요구에 맞춰 데이터 제공 가능
✅ Spring MVC와 RESTful 서비스
@RestController
: RESTful web service의 컨트롤러임을 명시
@RequetMapping
및 HTTP 메소드 별 어노테이션(@GetMapping
, @PostMapping
등) :
URL, HTTP 메소드, 요청 헤더, 매개 변수 등에 따라 핸들러 메소드를 매핑
2️⃣ JSON/XML 데이터 처리
✅ JSON 데이터
- Jackson 라이브러리
- JSON 데이터를 자바 객체로 직렬화, 역직렬화
@RestController
나@ResponseBody
의 메소드에서 자동으로 처리됨- 클라이언트가 JSON 형식의 데이터 POST 요청 -> 자바 객체로 변환 -> 메소드 파라미터
- 메소드가 자바 객체 반환 -> JSON 자동 변환 -> 클라이언트 응답
@RequestBody
와@ResponseBody
@RequestBody
: HTTP 요청 본문을 자바 객체로 매핑@ResponseBody
: 반환값을 HTTP 응답 본문에 쓰고, JSON 형식으로 클라이언트에게 전송
✅ XML 데이터 처리
- JAXB 라이브러리
- 자바 객체와 XML 사이의 매핑
@XmlROotElement
,@XmlElement
통해 클래스와 필드를 XML 요소에 매핑
- Content Negotiation
Accept
헤더 기반으로 클라이언트가 요청한 데이터 형식에 따라 응답 형식 결정RequestMapping
어노테이션의produces
속성 통ㅇ해 특정 컨트롤러 메소드가 생성할 수 있는 응답 타입 지정
3️⃣ ResponseEntity
Spring MVC에서 HTTP 요청에 대한 응답을 구성할 때 사용
HTTP 응답( 상태 코드, 헤더, 응답 본문) 전체적으로 제어
RESTful API를 보다 세밀하게 조정할 수 있고, 클라이언트에게 명확한 상태 정보와 데이터 제공 가능
✅ 기본 사용법
status
: 상태 코드 설정body
: 응답 본문 설정headers
: HTTP 헤더를 추가할 수 있음
@RestController
public class ExampleController {
@GetMapping("/example")
public ResponseEntity<STring> getExample(){
return ResponseEntity.status(HttpStatus.OK).header("Custom-Header","value")
.body("Hello World");
}
}
✅ HTTP 상태 코드 관리
HttpStatus.CREATED
나 HTTPStatus.NOT_FOUND
반환
@GetMapping("/user/{id}")
public ResponseEntity<User> getUSerById(@PathVariable Long id){
User user = userSErvice.findById(id);
if (user==null){
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}
4️⃣ 예외 처리 및 에러 헨들링
- Controller Advice
- Spring Application 전체에서 예외 처리 메서드를 선언할 수 있는 스프링 빈
- 주로 웹 애플리케이션의 HTML 기반 View나 API에서 발생할 수 있는 예외를 일괄적으로 처리할 때 사용
- 해당 스프링 빈 내부에 @ExceptionHandler를 설정해 예외 처리 메서드를 동작하게 함
- ResstControllerAdvice
- @ControllerAdvice + @ResponseEntity 기능 제공
- 예외 처리 + 에러 메세지를 클라이언트에게 응답
💬 Builder 패턴
- 디자인 패턴 중 하나인 생성 패턴에 해당
- 복잡한 객체를 생성하는 방법 중 하나
- 객체의 생성 코드와 사용 코드를 분리해 코드의 가독성과 유지 보수성을 향상시키는 패턴
1️⃣ 목적
객체 생성 시 필요한 매개변수를 모두 포함하는 생성자를 사용하는데, 이때 생성자의 매개변수가 많아질 경우 문제가 발생함.telescoping constructor pattern
이라고도 하는데, 이는 매개변수 순서가 혼동되거나•일부 매개변수에 대해 null혹은 기본값을 할당할 때 그 의미를 파악하기 어렵게 만들 수 있음.
2️⃣ 방법
별도의 클래스를 만들어 필수 값에 대해서는 생성자를 사용하고, 다른 값에 대해서는 메소드를 통해 필요한 값을 입력받고 bulid()
메서드를 사용해 인스턴스를 리턴 받는 방식
3️⃣ 특징
- 장점
- 생성할 객체 속성 자유롭게 지정 가능
- 생성할 객체의 속성이 많거나 복잡한 경우에도 코드 가독성 유지 가능
- 재사용 가능
- 단점
- 코드량 증가( 각 속성에 대한 setter 메서드 작성해야 하므로, 클래스의 코드량이 증가함)
4️⃣ 구현
Builder 클래스를 선언하고, 생성할 객체 속성에 대한 setter 메서드를 구현함
public class User {
private String name;
private int age;
public static class Builder {
private String name;
private int age;
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withAge(int age) {
this.age = age;
return this;
}
public User build() {
User user = new User();
user.name = this.name;
user.age = this.age;
return user;
}
}
public static void main(String[] args) {
User user = new User.Builder().withName("Henry").withAge(30).build();
}
}
Lombok 라이브러리의 @Builder
어노테이션 사용 가능
@Builder
@Getter
@Setter
public class User {
private String name;
private int age;
}
public static void main(String[] args) {
User user = User.builder().name("Henry").age(30).build();
}
'🏕 멋사 Java 백엔드 13기 > TIL' 카테고리의 다른 글
250218 TIL | 상속 매핑 전략과 임베디드 타입 (0) | 2025.02.18 |
---|---|
250205 TIL | 람다식 (1) | 2025.02.05 |
250121 TIL | AOP (2) | 2025.01.21 |
240117 TIL : DI (1) | 2025.01.17 |
[멋쟁이사자처럼 부트캠프 TIL 회고] 241231 백엔드 Java 부트캠프 21일차 (2) | 2024.12.31 |