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 메서드에 어노테이션을 달기 위해 @RestControllerAPI 클래스 에 어노테이션을 달 것 입니다.

4. RestTemplate 사용

이제 Person REST API를 테스트하기 위해 몇 가지 단위 테스트를 작성할 수 있습니다 . 여기에, 우리는에 POST 요청을 보내려고합니다  사람 에 의해 제공되는 POST 방법을 사용하여 API를 RestTemplate : postForObject , postForEntitypostForLocation을 .

단위 테스트 구현을 시작하기 전에 모든 단위 테스트 메서드에서 사용할 개체를 초기화하는 설정 메서드를 정의 해 보겠습니다.

@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 게시

RestTemplatepostForObject 메소드는 주어진 URI 템플릿에 객체를 게시하여 새 리소스를 생성합니다. responseType 매개 변수에 지정된 유형으로 자동 변환 된 결과를 리턴합니다 .

Person API에 POST 요청을 하여 새로운 Person 객체 를 생성하고 새로 생성 된 객체를 응답에 반환 하려고한다고 가정 해 보겠습니다 .

먼저 personJsonObjectContent-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 게시

받는 유사 postForObjectpostForEntity 방법, 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 에서 찾을 수 있습니다 .