본문 바로가기

BackEnd/Spring

[코드로 배우는 스프링 웹 프로젝트] ch16 REST 방식으로 전환 3(@RestController, 테스트 방법)

728x90
반응형

https://bobo12.tistory.com/315

 

3. @RestController에서 파라미터

   ▷ @Controller에서 사용하던 일반적인 타입이나 사용자가 정의한 타입(클래스)을 사용

      ▶ @PathVariabel : 일반 컨트롤러에서도 사용이 가능하지만 REST 방식에서 자주 사용 됨

          URL 경로의 일부를 파라미터로 사용할 때 이용

      ▶ @RequestBody : JSON 데이터를 원하는 타입의 객체로 변환해야 하는 경우 주로 사용

 

(1) @PathVariable

   ▷ REST 방식에서는 URL 내에 최대한 많은 정보를 담으려고 노력함

   ▷ '?' 뒤에 추가되는 쿼리 스트링이라는 형태로 파라미터 전달되던 데이터들이 REST 방식에서는 경로의 일부로 차용되는 경우가 많음

   ▷ @PathVariable 어노테이션을 이용해 URL 상에 경로의 일부를 파라미터로 사용 가능

http://localhost:8080/sample/{sno}
http://localhost:8080/sample/{sno}/page/{pno}


위의 URL에서 '{ }'로 처리된 부분은 컨트롤러의 메소드에서 변수로 처리 가능
@PathVariable는 '{ }'의 이름을 처리할 때 사용

 

◎ SampleController 수정

...(생략)...
	@GetMapping(value = "/product/{cat}/{pid}")
	public String[] getPath(
			@PathVariable("cat") String cat,
			@PathVariable("pid") Integer pid) {
		
		return new String[] {"category: " + cat, "productid: " + pid};
	}
...(생략)...


http://localhost:8080/sample/product/bags/1234

위 주소를 입력하면 아래와 같은 결과가 출력됩니다.

 

(2) @RequestBody

   ▷ 전달된 요청(requset)의 내용(body)을 이용해 해당 파라미터의 타입으로 변환 요구

   ▷ 내부적으로 HttpMessageConverter 타입의 객체들을 이용해 다양한 포맷의 입력 데이터를 변환할 수 있음

 

◎ src/main/java/org.codehows.domain → Ticket 클래스 생성

package org.codehows.domain;

import lombok.Data;

@Data
public class Ticket {
	private int tno;
	private String owner;
	private String grade;
}


Ticket 클래스 번호, 소유주, 등급 지정

 

◎ src/main/java/org.codehows.controller → SampleController 클래스 수정

...(생략)...
	@PostMapping("/ticket")
	public Ticket convert(@RequestBody Ticket ticket) {
		log.info("convert.......ticket" + ticket);
		
		return ticket;
	}
...(생략)...


다른 메소드와 달리 @PostMapping이 적용된 것을 볼 수 있음
@RequestBody가 요청(request)한 내용(body)을 처리하기 때문에 일반적인 파라미터 전달방식 사용할 수 없음

 

 

4. REST 방식의 테스트

   ▷ @RestController를 쉽게 테스트할 수 있는 방법은 주로 REST 방식의 데이터를 전송하는 툴을 이용하거나

        JUnit과 spring-test를 이용해서 테스트하는 방식을 고려

 

◎ src/test/java/org.codehows.controller → SampleControllerTests 클래스 생성

package org.codehows.controller;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.codehows.domain.Ticket;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.google.gson.Gson;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)

//Test for Controller
@WebAppConfiguration

@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml", 
		"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})

@Log4j
public class SampleControllerTests {
	
	@Setter(onMethod_ = {@Autowired} )
	private WebApplicationContext ctx;
	
	private MockMvc mockMvc;
	
	@Before
	public void setup() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
	}
	
	@Test
	public void testConvert() throws Exception {
		
		Ticket ticket = new Ticket();
		ticket.setTno(123);
		ticket.setOwner("Admin");
		ticket.setGrade("AAA");
		
		String jsonStr = new Gson().toJson(ticket);
		
		log.info(jsonStr);

		mockMvc.perform(post("/sample/ticket")
				.contentType(MediaType.APPLICATION_JSON)
				.content(jsonStr))
				.andExpect(status().is(200));
	}
}


▷ testConvert()로 convert() 메소드 테스트
SampleController의 convert()는 JSON으로 전달되는 데이터를 받아 Ticket 타입으로 변환
   ▶ 해당 데이터가 JSON이라는 것을 명시
MockMvc는 contentType()을 이용해 전달하는 데이터가 무엇인지 알려줌
코드 내의 Gson 라이브러리는 Java의 객체를 JSON 문자열로 변환하기 위해 사용

 배경 우클릭 → Run As → JUnit Test 클릭하면 아래와 같은 결과 창이 나타납니다.


JUnit을 이용하는 방식의 테스트 장점은 역시 Tomcat을 구동하지 않고도 컨트롤러를 구동해 볼 수 있다는 점

 

 

(2) 기타 도구

   ▷ JUnit을 이용하는 방식 외에 Tomcat을 구동한다면 REST 방식을 테스트할 수 있는 여러 도구들이 존재

   ▷ Mac, 리눅스를 이용한다면 curl(https://curl.haxx.se/) 같은 도구 이용 가능

      ▶ Java나 각종 언어로 개발된 라이브러리 이용 가능

   ▷ Chrome 브라우저 앱스토어(chrome://apps/)로 이동해 'REST client'로 검색하면 꽤 많은 크롬 확장 프로그램 볼 수 있음

 

◎ 크롬 확장 프로그램 


◎ Yet Another REST Client 들어가는 방법


코드 작성 : {"tno" : 123, "owner" : "user00", "grade" : "AAA"}

▷ Tomcat을 실행했다면 'Restlet Client'에서는 'GET/POST/...' 등 방식으로 접근 가능
 요청 내용(body) 역시 오른쪽 화면처럼 원하는 내용 전달 가능

 

 

5. 다양한 전송방식

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

 

◎ HTTP의 전송방식

NO 작업 전송방식
1 Create POST
2 Read GET
3 Update PUT
4 Delete DELETE

 

◎ REST 방식은 URI와 같이 결합하므로 회원(member)이라는 자원을 대상으로 전송방식을 결합

NO 작업 전송방식 URI
1 등록 POST /members/new
2 조회 GET /members/{id}
3 수정 PUT /members/{id} + body (json 데이터 등)
4 삭제 DELETE /member/{id}

   ▷ POST 방식도 그렇지만 PUT, DELETE 방식은 브라우저에서 테스트하기가 쉽지 않기 때문에 개발 시

        JUnit이나 'Restlet Client' 등과 같은 도구를 이용해서 테스트하고 개발해야만 합니다.

 

 

@RestController의 어노테이션을 이용해보았고 테스트를 실시하면서 코드가 제대로 되었는지 확인할 수 있습니다.

 

테스트를 통해 원하는 결과를 콘솔창에 볼 수 있습니다.

 

다음 글에서는 Ajax를 통한 댓글 처리 방법에 대해서 배워볼게요!!

 

많은 분들의 피드백은 언제나 환영합니다!  많은 댓글 부탁드려요~~

 

728x90
반응형