서블릿(Servlet) API를 기반으로 클라이언트의 요청을 처리하는 모듈이 있는데, 이 모듈 이름이 바로 Spring Web MVC(Spring MVC)
👉 서블릿(Servlet)이란?
클라이언트의 요청을 처리하도록 특정 규약에 맞추어서 Java 코드로 작성하는 클래스 파일
아파치 톰캣(Apache Tomcat)은 이러한 서블릿들이 웹 애플리케이션으로 실행이 되도록 해주는 서블릿 컨테이너(Servlet Container) 중 하나
작업의 처리 결과 데이터
Model 데이터를 이용해서 웹브라우저 같은 클라이언트 애플리케이션의 화면에 보이는 리소스(Resource)를 제공하는 역할
View 형태는 Model 데이터를 JSON 프로토콜 데이터로 변환하는 것
클라이언트 측의 요청을 직접적으로 전달받는 엔드포인트(Endpoint)로써 Model과 View의 중간에서 상호 작용을 해주는 역할
👉 Model, View, Controller 간의 처리 흐름
Client가 요청 데이터 전송 → Controller가 요청 데이터 수신 → 비즈니스 로직 처리 → Model 데이터 생성 → Controller에게 Model 데이터 전달 → Controller가 View에게 Model 데이터 전달 → View가 응답 데이터 생성
개요
@RestController를 클래스에 추가함으로써 해당 클래스를 REST API의 리소스(자원, Resource)를 처리하기 위한 API 엔드포인트로 동작하게 해 준다.
@RequestMapping을 Controller 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL)을 설정할 수 있다.
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/v1/members", produces = {MediaType.APPLICATION_JSON_VALUE})
public class MemberController {
@PostMapping
public String postMember(@RequestParam("email") String email,
@RequestParam("name") String name,
@RequestParam("phone") String phone) {
System.out.println("# email: " + email);
System.out.println("# name: " + name);
System.out.println("# phone: " + phone);
// 코드 개선이 필요한 부분
String response =
"{\"" +
"email\":\""+email+"\"," +
"\"name\":\""+name+"\",\"" +
"phone\":\"" + phone+
"\"}";
return response;
}
@GetMapping("/{member-id}")
public String getMember(@PathVariable("member-id") long memberId) {
System.out.println("# memberId: " + memberId);
// not implementation
return null;
}
@GetMapping
public String getMembers() {
System.out.println("# get Members");
// not implementation
return null;
}
}
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/v1/members") // (1) produces 설정 제거됨
public class MemberController {
@PostMapping
public ResponseEntity postMember(@RequestParam("email") String email,
@RequestParam("name") String name,
@RequestParam("phone") String phone) {
// (2) JSON 문자열 수작업을 Map 객체로 대체
Map<String, String> map = new HashMap<>();
map.put("email", email);
map.put("name", name);
map.put("phone", phone);
// (3) 리턴 값을 ResponseEntity 객체로 변경
return new ResponseEntity<>(map, HttpStatus.CREATED);
}
@GetMapping("/{member-id}")
public ResponseEntity getMember(@PathVariable("member-id") long memberId) {
System.out.println("# memberId: " + memberId);
// not implementation
// (4) 리턴 값을 ResponseEntity 객체로 변경
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping
public ResponseEntity getMembers() {
System.out.println("# get Members");
// not implementation
// (5) 리턴 값을 ResponseEntity 객체로 변경
return new ResponseEntity<>(HttpStatus.OK);
}
}
@RestController
@RequestMapping("/v1/members")
public class MemberController {
// 회원 정보 등록
@PostMapping
public ResponseEntity postMember(@RequestBody MemberPostDto memberPostDto) {
return new ResponseEntity<>(memberPostDto, HttpStatus.CREATED);
}
// 회원 정보 수정
@PatchMapping("/{member-id}")
public ResponseEntity patchMember(@PathVariable("member-id") long memberId,
@RequestBody MemberPatchDto memberPatchDto) {
memberPatchDto.setMemberId(memberId);
memberPatchDto.setName("홍길동");
// No need Business logic
return new ResponseEntity<>(memberPatchDto, HttpStatus.OK);
}
// 한명의 회원 정보 조회
@GetMapping("/{member-id}")
public ResponseEntity getMember(@PathVariable("member-id") long memberId) {
System.out.println("# memberId: " + memberId);
// not implementation
return new ResponseEntity<>(HttpStatus.OK);
}
// 모든 회원 정보 조회
@GetMapping
public ResponseEntity getMembers() {
System.out.println("# get Members");
// not implementation
return new ResponseEntity<>(HttpStatus.OK);
}
// 회원 정보 삭제
@DeleteMapping("/{member-id}")
public ResponseEntity deleteMember(@PathVariable("member-id") long memberId) {
// No need business logic
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
}
public class MemberPatchDto {
private long memberId;
@NotSpace(message = "회원 이름은 공백이 아니어야 합니다") // (1)
private String name;
@Pattern(regexp = "^010-\\d{3,4}-\\d{4}$",
message = "휴대폰 번호는 010으로 시작하는 11자리 숫자와 '-'로 구성되어야 합니다")
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public long getMemberId() {
return memberId;
}
public void setMemberId(long memberId) {
this.memberId = memberId;
}
}