(spring) REST 관련
💼📝🔑⏰ 📙📓📘📒🎓
xml 예제 프로젝트 : sp5-chap16
💼 REST 란?
- REST(Representational State Transfer)
- 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식
- 자원을 정의하고 자원에 대한 주소를 지정하는 방법 전반을 의미하는 네트워크 아키텍처 원리의 모음
- 간단한 의미로 웹 상의 자료를 HTTP위에서 별도의 전송 계층 없이 전송하기 위한 아주 간단한 인터페이스
- 리소스
- 서비스를 제공하는 시스템의 자원으로 URI로 정의
- 리소스 URI 설계 규칙
- URI는 명사 사용
- 슬래시로 계층 관계 표현
- 마지막에 슬래시 사용 금지
- 소문자로 작성
- 가독성을 위해 하이픈(-)은 사용하지만 밑줄(_)는 사용 금지
ajax
와 관련있다.- html을 가져가지 않고 데이터만 가져다가 활용하는 방식
API
수요가 많아짐- 리소스를 어떤식으로 표현할 것인지를 고안해서 생긴 개념
📝 객체를 JSON으로
- GSON 라이브러리 사용
Serialization
: 객체에서 JSON으로 변환하는 역할을 한다.
🔑 JSON 응답 구현
@Controller
+@ResponseBody
- 요청 처리 메서드에 @ResponseBody를 선언하고 객체를 반환하면 json으로 변환
@RestController
- 컨트롤러 클래스에 @Controller 대신 @RestController를 선언하면 해당 컨트롤러 클래스에 포함된 모든 요청 처리 메서드에 자동으로 @ResponseBody가 선언된 효과
@JsonIgnore
- 패스워드와 같은 데이터의 노출을 막기 위해 필드에 선언
@JsonFormat
- 날짜 표현 형식 변경
HttpServletResponse
객체를 통해 응답 코드를 설정할 경우 404와 같이 서버에서 정한 응답 컨텐츠가 전송될 수 있음- 오류와 같은 특수한 상황에서도 일관되게 Json 형식의 데이터 전송 필요
ResponseEntity
객체를 통해 응답 코드와 메시지를 직접 관리할 수 있음@RequestBody
- 요청 처리 메서드의 전달인자에 @RequestBody를 선언해서 Json 요청 데이터를 객체로 변환
💼 웹 브라우저 요청 HTTP 메서드 활성화
-
웹 브라우저의 HTML은 POST와 GET 메서드만 지원
-
스프링은
HiddenHttpMethodFilter
를 통해 POST, GET 뿐만 아니라 PUT, DELETE 메서드를 사용할 수 있도록 지원 -
메서드 활성화를 위해 필터 등록
- HTML에 hidden method field 포함
- 각 컨트롤러에서 메서드 매핑
💼 세팅관련
1. p의존성 라이브러리 등록 (pom.xml)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<!-- java8 date/time -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.4</version>
</dependency>
<!-- java8 Optional, etc -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.9.4</version>
</dependency>
2. Controller 클래스 @RestController 어노테이션 등록
@RestController // @ResponseBody가 포함되어 있는 것이다.
public class RestMemberController {
private MemberDao memberDao;
private MemberRegisterService registerService;
@GetMapping("/api/members")
public List<Member> members() {
return memberDao.selectAll();
}
@GetMapping("/api/members/{id}")
public ResponseEntity<Object> member(@PathVariable Long id) {
Member member = memberDao.selectById(id);
if (member == null) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("no member"));
// return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(member);
}
@PostMapping("/api/members")
public ResponseEntity<Object> newMember(@RequestBody @Valid RegisterRequest regReq /*,Errors errors */) {
/*
if (errors.hasErrors()) {
String errorCodes = errors.getAllErrors()
.stream()
.map(error -> error.getCodes()[0])
.collect(Collectors.joining(","));
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse("errorCodes = " + errorCodes));
}
*/
try {
System.out.println(regReq.getEmail());
Long newMemberId = registerService.regist(regReq);
URI uri = URI.create("/api/members/" + newMemberId);
return ResponseEntity.created(uri).build();
} catch (DuplicateMemberException dupEx) {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
}
}
댓글남기기