1. 소개
이 빠른 자습서에서는 Spring의 RestTemplate 을 사용하여 JSON 콘텐츠를 보내는 POST 요청을 만드는 방법을 설명합니다 .
2. 예제 설정
게시 할 데이터를 나타내는 간단한 Person 모델 클래스를 추가하여 시작하겠습니다 .
public class Person {
private Integer id;
private String name;
// standard constructor, getters, setters
}
Person 객체로 작업하기 위해 PersonService 인터페이스와 구현을 두 가지 방법으로 추가 합니다.
public interface PersonService {
public Person saveUpdatePerson(Person person);
public Person findPersonById(Integer id);
}
이러한 메소드의 구현은 단순히 객체를 반환합니다. 여기서는 웹 레이어에 집중할 수 있도록이 레이어의 더미 구현을 사용하고 있습니다.
3. REST API 설정
Person 클래스에 대한 간단한 REST API를 정의 해 보겠습니다 .
@PostMapping(
value = "/createPerson", consumes = "application/json", produces = "application/json")
public Person createPerson(@RequestBody Person person) {
return personService.saveUpdatePerson(person);
}
@PostMapping(
value = "/updatePerson", consumes = "application/json", produces = "application/json")
public Person updatePerson(@RequestBody Person person, HttpServletResponse response) {
response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/findPerson/" + person.getId()).toUriString());
return personService.saveUpdatePerson(person);
}
데이터를 JSON 형식으로 게시하고 싶습니다. 이를 위해 두 메서드 모두에 대해 "application / json"값을 사용하여 @PostMapping 어노테이션 에 소비 속성을 추가했습니다 .
마찬가지로, 우리 는 JSON 형식의 Response body을 원한다는 것을 Spring에 알리기 위해 생성 속성을 "application / json"으로 설정합니다.
우리는 어노테이션 사람 와 매개 변수를 @RequestBody 두 가지 방법에 대한 어노테이션. 이것은 사람 객체가 HTTP 요청 의 본문에 바인딩 될 것이라는 것을 Spring에 알려줄 것 입니다.
마지막으로 두 메서드 모두 Response body에 바인딩 될 Person 개체를 반환합니다 . 숨겨진 @ResponseBody 어노테이션으로 모든 API 메서드에 어노테이션을 달기 위해 @RestController 로 API 클래스 에 어노테이션을 달 것 입니다.
4. RestTemplate 사용
이제 Person REST API를 테스트하기 위해 몇 가지 단위 테스트를 작성할 수 있습니다 . 여기에, 우리는에 POST 요청을 보내려고합니다 사람 에 의해 제공되는 POST 방법을 사용하여 API를 RestTemplate : postForObject , postForEntity 및 postForLocation을 .
단위 테스트 구현을 시작하기 전에 모든 단위 테스트 메서드에서 사용할 개체를 초기화하는 설정 메서드를 정의 해 보겠습니다.
@BeforeClass
public static void runBeforeAllTestMethods() {
createPersonUrl = "http://localhost:8082/spring-rest/createPerson";
updatePersonUrl = "http://localhost:8082/spring-rest/updatePerson";
restTemplate = new RestTemplate();
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
personJsonObject = new JSONObject();
personJsonObject.put("id", 1);
personJsonObject.put("name", "John");
}
이 설정 방법 외에도 단위 테스트에서 JSON 문자열을 JSONNode 객체 로 변환하기 위해 다음 매퍼를 참조 할 것입니다 .
private final ObjectMapper objectMapper = new ObjectMapper();
앞서 언급했듯이 데이터를 JSON 형식으로 게시하려고합니다. 이를 위해 APPLICATION_JSON 미디어 유형을 사용하여 요청에 Content-Type 헤더를 추가합니다 .
Spring의 HttpHeaders 클래스는 헤더에 접근하기위한 다양한 방법을 제공합니다. 여기서는 setContentType 메서드 를 호출하여 Content-Type 헤더를 application / json 으로 설정합니다 . 요청에 headers 객체를 첨부 합니다.
4.1. postForObject로 JSON 게시
RestTemplate 의 postForObject 메소드는 주어진 URI 템플릿에 객체를 게시하여 새 리소스를 생성합니다. responseType 매개 변수에 지정된 유형으로 자동 변환 된 결과를 리턴합니다 .
Person API에 POST 요청을 하여 새로운 Person 객체 를 생성하고 새로 생성 된 객체를 응답에 반환 하려고한다고 가정 해 보겠습니다 .
먼저 personJsonObject 및 Content-Type을 포함하는 헤더를 기반으로 HttpEntity 유형 의 요청 객체를 빌드합니다 . 이렇게하면 postForObject 메서드가 JSON 요청 본문을 보낼 수 있습니다 .
@Test
public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull()
throws IOException {
HttpEntity<String> request =
new HttpEntity<String>(personJsonObject.toString(), headers);
String personResultAsJsonStr =
restTemplate.postForObject(createPersonUrl, request, String.class);
JsonNode root = objectMapper.readTree(personResultAsJsonStr);
assertNotNull(personResultAsJsonStr);
assertNotNull(root);
assertNotNull(root.path("name").asText());
}
postForObject () 메소드는로 Response body을 반환 문자열 유형입니다.
responseType 매개 변수 를 설정하여 응답을 Person 객체 로 반환 할 수도 있습니다 .
Person person = restTemplate.postForObject(createPersonUrl, request, Person.class);
assertNotNull(person);
assertNotNull(person.getName());
실제로 createPersonUrl URI 와 일치하는 요청 처리기 메서드 는 JSON 형식의 Response body을 생성합니다.
그러나 이것은 우리에게 제한이 아닙니다. postForObject 는 Response body을 responseType 매개 변수에 지정된 요청 된 Java 유형 (예 : String , Person ) 으로 자동 변환 할 수 있습니다.
4.2. postForEntity로 JSON 게시
비교 postForObject () , postForEntity ()는 A와 응답 반환 ResponseEntity의 개체. 그 외에는 두 방법 모두 동일한 작업을 수행합니다.
새 Person 객체 를 생성 하고 응답을 ResponseEntity 로 반환 하기 위해 Person API에 POST 요청을하고 싶다고 가정 해 보겠습니다 .
postForEntity 메소드를 사용하여 이를 구현할 수 있습니다.
@Test
public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull()
throws IOException {
HttpEntity<String> request =
new HttpEntity<String>(personJsonObject.toString(), headers);
ResponseEntity<String> responseEntityStr = restTemplate.
postForEntity(createPersonUrl, request, String.class);
JsonNode root = objectMapper.readTree(responseEntityStr.getBody());
assertNotNull(responseEntityStr.getBody());
assertNotNull(root.path("name").asText());
}
받는 유사 postForObject , postForEntity는 이 responseType의 요청 Java 유형에 Response body을 변환하는 매개 변수를.
여기에서 Response body을 ResponseEntity <String> 로 반환 할 수있었습니다 .
responseType 매개 변수를 Person.class 로 설정하여 응답을 ResponseEntity <Person> 객체 로 반환 할 수도 있습니다 .
ResponseEntity<Person> responseEntityPerson = restTemplate.
postForEntity(createPersonUrl, request, Person.class);
assertNotNull(responseEntityPerson.getBody());
assertNotNull(responseEntityPerson.getBody().getName());
4.3. postForLocation으로 JSON 게시
받는 유사 postForObject 및 postForEntity 방법, postForLocation는 또한 지정된 URI에 지정된 객체를 게시하여 새 자원을 작성합니다. 유일한 차이점은 Location 헤더 의 값을 반환한다는 것 입니다.
위 의 updatePerson REST API 메서드 에서 응답 의 Location 헤더 를 설정하는 방법을 이미 살펴 보았습니다 .
response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/findPerson/" + person.getId()).toUriString());
이제 게시 한 사람 객체를 업데이트 한 후 응답 의 Location 헤더 를 반환 한다고 가정 해 보겠습니다 .
postForLocation 메서드 를 사용하여 이를 구현할 수 있습니다 .
@Test
public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader()
throws JsonProcessingException {
HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request);
assertNotNull(locationHeader);
}
5. 결론
이 기사에서는 RestTemplate 을 사용 하여 JSON으로 POST 요청을 만드는 방법을 살펴 보았습니다 .
항상 그렇듯이 모든 예제와 코드 조각은 GitHub 에서 찾을 수 있습니다 .