다연이네

[days15] REST 방식으로 전환 본문

Spring

[days15] REST 방식으로 전환

 다연  2021. 2. 23. 20:20
반응형

앱에서 서버에 기대하는 것은 완성된 HTML이 아니라 그저 자신에게 필요한 순수한 데이터만을 요구하게 되어 있다. 이처럼 서버의 역할은 점점 더 순수하게 데이터에 대한 처리를 목적으로 하는 형태로 진화하고 있다.

 

- URL : 이 곳에 가면 당신이 원하는 것을 찾을 수 있습니다. (URI의 하위개념)

- URI : 당신이 원하는 주소는 여기입니다.

 

REST는 하나의 URI는 하나의 고유한 리소스를 대표하도록 설계된다는 개념에 전송방식을 결합해서 원하는 작업을 지정한다.

URI + GET/POST/PUT/DELETE...

REST관련 어노테이션들

@RestController   Controller가 REST 방식을 처리하기 위한 것임을 명시

@ResponseBody    일반적인 JSP와 같은 뷰로 전달되는게 아니라 데이터 자체를 전달하기 위한 용도

@PathVariable       URL 경로에 있는 값을 파라미터로 추출하려고 할 때 사용

@CrossOrigin        Ajax의 크로스 도메인 문제를 해결

@RequestBody      JSON 데이터를 원하는 타입으로 바인딩 처리

 

 

@RestController

메소드의 리턴 타입으로 사용자가 정의한 클래스 타입을 지정할 수 있고, 이를 JSON이나 XML로 자동으로 처리 가능

사용하기 위한 준비

1. pom.xml에 필요 라이브러리 추가

     <!-- p 147 jackson-databind -->
      <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-databind</artifactId>
         <version>2.12.1</version>
      </dependency>
      <!-- 추가-->
      <dependency>
         <groupId>com.fasterxml.jackson.dataformat</groupId>
         <artifactId>jackson-dataformat-xml</artifactId>
         <version>2.9.6</version>
      </dependency>
      <!-- 추가 -->
      <dependency>
         <groupId>com.google.code.gson</groupId>
         <artifactId>gson</artifactId>
         <version>2.8.2</version>
      </dependency>

위 라이브러리는 JSON 데이터를 처리하기 위해, 또 니중에 브라우저에 객체를 JSON이라는 포맷의 문자열로 변환시켜 전송하기 위해 필요하다. 또한, 테스트 시 직접 Java 인스턴스를 JSON 타입의 문자열로 변환해야 하는 일들도 있으므로 gson 라이브러리도 추가한다.

 

SampleController 생성

- 기존의 @Controller는 문자열을 반환하는 경우 JSP 파일의 이름으로 처리하지만, @RestController의 경우 순수한 데이터가 된다.

- @GetMapping에 사용된 produces 속성은 해당 메소드가 생산하는 MIME 타입을 의미한다. 문자열로 직접 지정할 수 도 있고, 메소드 내의 MediaType이라는 클래스를 이용할 수도 있다.

package org.zerock.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zerock.domain.SampleVO;
import org.zerock.domain.Ticket;

import lombok.extern.log4j.Log4j;


@RestController
@RequestMapping("/sample")
@Log4j
public class SampleController {
	
	// p.359
	   @GetMapping(value = "/getText", produces = "text/plain; charset=UTF-8")   
	   public String getText() {
	      log.info("MIME TYPE : " + MediaType.TEXT_PLAIN_VALUE);
	      return "안녕하세요";
	   }  
	   
}

 

객체의 반환

객체를 반환하는 작업은 JSON이나 XML을 이용한다. 

 

SampleVO

- @NoArgsConstructor 비어있는 생성자 만들기

package org.zerock.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SampleVO {
   
   private Integer mno;
   private String firstName;
   private String LastName;

}

 

컨트롤러에 메소드 추가

	// p.361
	   @GetMapping(value = "/getSample", produces = {
	         //MediaType.APPLICATION_JSON_UTF8_VALUE, 
	         MediaType.APPLICATION_JSON_VALUE,
	         MediaType.APPLICATION_XML_VALUE
	   }) 
	   public SampleVO getSample() {
	      return new SampleVO(112, "스타", "로드");
	   }
	   //url 뒤에 .json 붙히면 자동으로 json으로 출력
	   //안붙히면 기본은 xml

@GetMapping이나 @RequestMapping의 procedures 속성은 반드시 지정해야 하는 것은 아니므로 생략해도 된다.

 

컬렉션 타입의 객체 반환

배열, 리스트, 맵 타입의 객체 전송

 

컨트롤러 추가

	// p.364
	   @GetMapping("/getMap")
	   public Map<String, SampleVO> getMap(){
	      
	      Map<String, SampleVO> map = new HashMap<String, SampleVO>();
	           //  key              value
	      map.put("First", new SampleVO(1, "f", "l"));            
	      map.put("Second", new SampleVO(2, "f", "l"));
	      
	      return map;
	   }

	   
	// p.363
	   @GetMapping("/getList")
	   public List<SampleVO> getList(){
	      return IntStream
	            .range(1, 10)
	            .mapToObj(i -> new SampleVO(i, "first " + i, "last "+i))
	            .collect(Collectors.toList());
	   } //포폴 스프링 REST 방식으로 처리했다 써야함 (꼭 사용하기)

 

ResponseEntity 타입

Rest방식으로 호출하는 경우는 화면 자체가 아니라 데이터 자체를 전송하는 방식으로 처리되기 때문에 데이터를 요청한 쪽에서는 정상 데이터인지 비정상 데이터인지를 구분할 수 있는 확실한 방법을 제공해야 한다.

ResponseEntity는 데이터와 함께 HTTP 헤더의 상태메시지 등을 같이 전달하는 용도로 사용한다. 

 

컨트롤러

	// p.365
	   @GetMapping(value = "/check", params = {"height", "weight"})
	   public ResponseEntity<SampleVO> check(Double height, Double weight){
	      SampleVO vo = new SampleVO(1, ""+height, ""+weight);
	      ResponseEntity<SampleVO> result = null;
	      
	      if (height < 150) {
	         result = ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(vo);
	      } else {
	         result = ResponseEntity.status(HttpStatus.OK).body(vo);
	      }
	      return result;
	   }

 

@PathVariable

REST 방식에서는 URL 내에 최대한 많은 정보를 담으려고 노력한다. 예전에는 ? 뒤에 추가되는 쿼리 스트링 형태로 파라미터를 전달되던 데이터들이 REST 방식에서는 경로의 일부로 차용되는 경우가 많다.

스프링 MVC에서는 @PathVariable 어노테이션을 이용해 URL 상에 경로의 일부를 파라미터로 사용할 수 있다.

 

컨트롤러

	// p.366
	   //     /sample/product/bags/1234"
	   @GetMapping("/product/{cat}/{pid}")
	   public String[] getPath(@PathVariable("cat") String cat
	         , @PathVariable("pid") Integer pid) {
	      return new String[] { "category: " + cat, "productid: " + pid };
	   }

요청 URL

<a href="/sample/product/bags/1234">/sample/product/bags/1234</a>

 

 

 

@RequestBody

전달된 요청의 내용을 이용해 해당 파라미터의 타입으로 변환을 요구한다.

 

Ticket 클래스 추가

package org.zerock.domain;

import lombok.Data;

@Data
public class Ticket {

  private int tno;
  private String owner;
  private String grade;
}

컨트롤러

	// p.368
	   // 클라이언트에서 [json 데이터]를 파라미터로 ajax 요청
	   //    {"tno":1,"owner":"kenik","grade":"mvp"}   -->     Ticket 자바객체로 변환
	   //                   @RequestBody
	   @PostMapping("/ticket")
	   public Ticket convert(@RequestBody Ticket ticket) {
	      log.info("> convert..........ticket " + ticket);
	      return ticket;
	   }	

jsp (뷰)

<!-- p.369 -->
<%
  Ticket ticket = new Ticket();
  ticket.setTno(1);
  ticket.setOwner("kenik");
  ticket.setGrade("mvp");
  
  //자바 객체Ticket 을 json 데이터로 변환하는 코딩
  String jsonTicket = new Gson().toJson(ticket);
%>
jsonTicket : <%= jsonTicket %><br>

 

다양한 전송방식

REST 방식의 데이터 교환에서 가장 특이한 점은 기존의 GET/POST 외에 다양한 방식으로 데이터를 전달한다는 점이다.

Create POST
Read GET
Update PUT
Delete DELETE

 

반응형
Comments