(spring) REST 관련

2 분 소요

💼📝🔑⏰ 📙📓📘📒🎓

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();
		}
	}
}

댓글남기기