Permintaan Pos RestTemplate dengan JSON

REST Teratas

Saya baru sahaja mengumumkan kursus Learn Spring yang baru , yang berfokus pada asas-asas Spring 5 dan Spring Boot 2:

>> SEMAK KURSUS

1. Pengenalan

Dalam tutorial ringkas ini, kami menggambarkan cara menggunakan Spring's RestTemplate untuk membuat permintaan POST menghantar kandungan JSON.

2. Menetapkan Contoh

Mari kita mulakan dengan menambahkan kelas model Orang sederhana untuk mewakili data yang akan dihantar:

public class Person { private Integer id; private String name; // standard constructor, getters, setters }

Untuk bekerja dengan objek Person , kami akan menambahkan antara muka dan pelaksanaan PersonService dengan dua kaedah:

public interface PersonService { public Person saveUpdatePerson(Person person); public Person findPersonById(Integer id); }

Pelaksanaan kaedah ini hanya akan mengembalikan objek. Kami menggunakan implementasi lapisan ini di sini supaya kami dapat memfokus pada lapisan web.

3. Penyediaan API REST

Mari tentukan REST API ringkas untuk kelas Person kami :

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

Ingat, kami ingin menghantar data dalam format JSON. Untuk itu, kami menambah consumes atribut dalam @PostMapping anotasi dengan nilai "application / json" untuk kedua-dua kaedah.

Begitu juga, kami menetapkan atribut menghasilkan ke "application / json" untuk memberitahu Spring bahawa kami mahukan badan respons dalam format JSON.

Kami memberi penjelasan parameter orang dengan anotasi @RequestBody untuk kedua-dua kaedah tersebut. Ini akan memberitahu Spring bahawa objek orang akan terikat pada badan permintaan HTTP .

Terakhir, kedua-dua kaedah mengembalikan objek Orang yang akan terikat pada badan tindak balas. Perhatikan bahawa kami akan memberi anotasi kelas API kami dengan @RestController untuk memberi anotasi semua kaedah API dengan anotasi @ResponseBody yang tersembunyi .

4. Menggunakan RestTemplate

Sekarang kita boleh menulis beberapa ujian unit untuk menguji API REST Person kita . Di sini, kami akan cuba menghantar permintaan POST ke Person API dengan menggunakan kaedah POST yang disediakan oleh RestTemplate : postForObject , postForEntity , dan postForLocation .

Sebelum kita mula melaksanakan ujian unit kami, mari tentukan kaedah penyediaan untuk menginisialisasi objek yang akan kami gunakan dalam semua kaedah ujian unit kami:

@BeforeClass public static void runBeforeAllTestMethods() { createPersonUrl = "//localhost:8082/spring-rest/createPerson"; updatePersonUrl = "//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"); }

Selain kaedah penyediaan ini, perhatikan bahawa kami akan merujuk kepada mapper berikut untuk menukar JSON String menjadi objek JSONNode dalam ujian unit kami:

private final ObjectMapper objectMapper = new ObjectMapper();

Seperti yang telah disebutkan sebelumnya, kami ingin menghantar data dalam format JSON. Untuk mencapainya, kami akan menambahkan tajuk Jenis Kandungan pada permintaan kami dengan jenis media APPLICATION_JSON .

Kelas HttpHeaders Spring menyediakan kaedah yang berbeza untuk mengakses tajuk. Di sini, kami menetapkan tajuk Content-Type ke application / json dengan memanggil kaedah setContentType . Kami akan melampirkan objek tajuk ke permintaan kami.

4.1. Mengeposkan JSON Dengan postForObject

RestTemplate 's postForObject kaedah mencipta sumber baru dengan menyiarkan objek untuk template URI yang diberikan. Ia mengembalikan hasilnya sebagai secara automatik ditukar kepada jenis yang dinyatakan dalam responseType parameter.

Katakanlah bahawa kami ingin membuat permintaan POST ke Person API kami untuk membuat objek Orang baru dan mengembalikan objek yang baru dibuat ini sebagai tindak balas.

Pertama, kita akan membina objek permintaan jenis HttpEntity berdasarkan personJsonObject dan tajuk yang mengandungi Content-Type . Ini membolehkan kaedah postForObject menghantar badan permintaan JSON:

@Test public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull() throws IOException { HttpEntity request = new HttpEntity(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()); }

Kaedah postForObject () mengembalikan badan tindak balas sebagai jenis String .

Kita juga boleh kembali sambutan sebagai Orang objek dengan menetapkan responseType parameter:

Person person = restTemplate.postForObject(createPersonUrl, request, Person.class); assertNotNull(person); assertNotNull(person.getName());

Sebenarnya, kaedah pengendali permintaan kami yang sepadan dengan URI createPersonUrl menghasilkan badan respons dalam format JSON.

Tetapi ini tidak adalah had untuk kita - postForObject mampu untuk secara automatik menukar isi sambutan ke Java jenis yang diminta (contohnya String , Orang ) yang dinyatakan dalam responseType parameter.

4.2. Mengeposkan JSON Dengan postForEntity

Berbanding dengan postForObject () , postForEntity () mengembalikan tindak balas sebagai objek ResponseEntity . Selain daripada itu, kedua-dua kaedah melakukan pekerjaan yang sama.

Katakan bahawa kami ingin membuat permintaan POST ke Person API kami untuk membuat objek Orang baru dan mengembalikan respons sebagai ResponseEntity .

Kita boleh menggunakan kaedah postForEntity untuk melaksanakan ini:

@Test public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull() throws IOException { HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); ResponseEntity responseEntityStr = restTemplate. postForEntity(createPersonUrl, request, String.class); JsonNode root = objectMapper.readTree(responseEntityStr.getBody()); assertNotNull(responseEntityStr.getBody()); assertNotNull(root.path("name").asText()); }

Sama dengan postForObject , postForEntity mempunyai responseType parameter untuk menukar isi sambutan dengan jenis Java yang diminta.

Di sini, kami dapat mengembalikan badan tindak balas sebagai ResponseEntity .

We can also return the response as a ResponseEntity object by setting the responseType parameter to Person.class:

ResponseEntity responseEntityPerson = restTemplate. postForEntity(createPersonUrl, request, Person.class); assertNotNull(responseEntityPerson.getBody()); assertNotNull(responseEntityPerson.getBody().getName());

4.3. Posting JSON With postForLocation

Similar to the postForObject and postForEntity methods, postForLocation also creates a new resource by posting the given object to the given URI. The only difference is that it returns the value of the Location header.

Remember, we already saw how to set the Location header of a response in our updatePerson REST API method above:

response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath() .path("/findPerson/" + person.getId()).toUriString());

Sekarang mari kita bayangkan bahawa kita mahu mengembalikan Lokasi pengepala sambutan selepas mengemas kini orang objek kita mencatatkan.

Kami dapat melaksanakannya dengan menggunakan kaedah postForLocation :

@Test public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader() throws JsonProcessingException { HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request); assertNotNull(locationHeader); }

5. Kesimpulan

Dalam artikel ini, kami meneroka cara menggunakan RestTemplate untuk membuat permintaan POST dengan JSON.

Seperti biasa, semua contoh dan coretan kod boleh didapati di GitHub.

REST bawah

Saya baru sahaja mengumumkan kursus Learn Spring yang baru , yang berfokus pada asas-asas Spring 5 dan Spring Boot 2:

>> SEMAK KURSUS