1. ภาพรวม
ในบทช่วยสอนนี้เราจะแสดงให้เห็นถึงการดำเนินการที่หลากหลายซึ่งสามารถใช้ Spring REST Client - RestTemplate - ได้ดี
สำหรับด้าน API ของตัวอย่างทั้งหมดเราจะเรียกใช้บริการ RESTful จากที่นี่
2. ประกาศการเลิกใช้งาน
ในฐานะของฤดูใบไม้ผลิกรอบ 5 ข้างกอง WebFlux ฤดูใบไม้ผลิแนะนำลูกค้าใหม่ที่เรียกว่า HTTP WebClient
WebClientเป็นที่ทันสมัย, HTTP ลูกค้าทางเลือกที่จะRestTemplate ไม่เพียง แต่ให้ API แบบซิงโครนัสแบบเดิม แต่ยังสนับสนุนวิธีการแบบไม่ปิดกั้นและอะซิงโครนัสที่มีประสิทธิภาพ
ที่กล่าวว่าถ้าเรากำลังพัฒนาโปรแกรมใหม่ ๆ หรือการโยกย้ายคนเก่า, มันเป็นความคิดที่ดีที่จะใช้WebClient ก้าวไปข้างหน้าRestTemplateจะเลิกใช้ในรุ่นอนาคต
3. ใช้ GET เพื่อดึงทรัพยากร
3.1. รับ JSON ธรรมดา
มาเริ่มกันง่ายๆและพูดคุยเกี่ยวกับคำขอ GET ด้วยตัวอย่างสั้น ๆ โดยใช้getForEntity () API :
RestTemplate restTemplate = new RestTemplate(); String fooResourceUrl = "//localhost:8080/spring-rest/foos"; ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
โปรดสังเกตว่าเราสามารถเข้าถึงการตอบสนอง HTTP ได้อย่างเต็มที่ดังนั้นเราจึงสามารถทำสิ่งต่างๆเช่นตรวจสอบรหัสสถานะเพื่อให้แน่ใจว่าการดำเนินการสำเร็จหรือทำงานกับเนื้อหาจริงของการตอบสนอง:
ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(response.getBody()); JsonNode name = root.path("name"); assertThat(name.asText(), notNullValue());
เรากำลังทำงานกับเนื้อหาตอบกลับเป็นสตริงมาตรฐานที่นี่และใช้ Jackson (และโครงสร้างโหนด JSON ที่ Jackson ให้มา) เพื่อตรวจสอบรายละเอียดบางอย่าง
3.2. การดึง POJO แทน JSON
นอกจากนี้เรายังสามารถแมปการตอบสนองโดยตรงกับทรัพยากร DTO:
public class Foo implements Serializable { private long id; private String name; // standard getters and setters }
ตอนนี้เราสามารถใช้getForObject API ในเทมเพลตได้:
Foo foo = restTemplate .getForObject(fooResourceUrl + "/1", Foo.class); assertThat(foo.getName(), notNullValue()); assertThat(foo.getId(), is(1L));
4. ใช้ HEAD เพื่อดึงข้อมูลส่วนหัว
ตอนนี้เรามาดูการใช้ HEAD อย่างรวดเร็วก่อนที่จะไปสู่วิธีการทั่วไป
เราจะใช้headForHeaders () API ที่นี่:
HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl); assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));
5. ใช้ POST เพื่อสร้างทรัพยากร
ในการสร้าง Resource ใหม่ใน API เราสามารถใช้ประโยชน์จากpostForLocation () , postForObject ()หรือpostForEntity () API ได้
รายการแรกส่งคืน URI ของทรัพยากรที่สร้างขึ้นใหม่ในขณะที่รายการที่สองส่งคืนทรัพยากรเอง
5.1. postForObject () API
RestTemplate restTemplate = new RestTemplate(); HttpEntity request = new HttpEntity(new Foo("bar")); Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class); assertThat(foo, notNullValue()); assertThat(foo.getName(), is("bar"));
5.2. postForLocation () API
ในทำนองเดียวกันเรามาดูการดำเนินการที่แทนที่จะส่งคืนทรัพยากรทั้งหมดให้ส่งคืนตำแหน่งของทรัพยากรที่สร้างขึ้นใหม่:
HttpEntity request = new HttpEntity(new Foo("bar")); URI location = restTemplate .postForLocation(fooResourceUrl, request); assertThat(location, notNullValue());
5.3. API การแลกเปลี่ยน ()
มาดูวิธีการทำ POST ด้วยAPI การแลกเปลี่ยนทั่วไปเพิ่มเติม:
RestTemplate restTemplate = new RestTemplate(); HttpEntity request = new HttpEntity(new Foo("bar")); ResponseEntity response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); Foo foo = response.getBody(); assertThat(foo, notNullValue()); assertThat(foo.getName(), is("bar"));
5.4. ส่งข้อมูลแบบฟอร์ม
ต่อไปมาดูวิธีการส่งแบบฟอร์มโดยใช้วิธี POST
ขั้นแรกเราต้องตั้งค่าส่วนหัวContent-Typeเป็นapplication / x-www-form-urlencoded
สิ่งนี้ทำให้แน่ใจว่าสามารถส่งสตริงแบบสอบถามขนาดใหญ่ไปยังเซิร์ฟเวอร์ซึ่งมีคู่ชื่อ / ค่าคั่นด้วย& :
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
เราสามารถรวมตัวแปรฟอร์มลงในLinkedMultiValueMap :
MultiValueMap map= new LinkedMultiValueMap(); map.add("id", "1");
ต่อไปเราจะสร้างคำขอโดยใช้อินสแตนซ์HttpEntity :
HttpEntity
request = new HttpEntity(map, headers);
สุดท้ายเราสามารถเชื่อมต่อกับบริการ REST ได้โดยเรียกrestTemplate.postForEntity ()บน Endpoint: / foos / form
ResponseEntity response = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
6. ใช้ตัวเลือกเพื่อรับการดำเนินการที่อนุญาต
ต่อไปเราจะมาดูการใช้คำขอ OPTIONS และสำรวจการดำเนินการที่อนุญาตใน URI เฉพาะโดยใช้คำขอประเภทนี้ API คือoptionsForAllow :
Set optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl); HttpMethod[] supportedMethods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE}; assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));
7. ใช้ PUT เพื่ออัปเดตทรัพยากร
Next, we'll start looking at PUT and more specifically the exchange() API for this operation, since the template.put API is pretty straightforward.
7.1. Simple PUT With exchange()
We'll start with a simple PUT operation against the API — and keep in mind that the operation isn't returning a body back to the client:
Foo updatedInstance = new Foo("newName"); updatedInstance.setId(createResponse.getBody().getId()); String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId(); HttpEntity requestUpdate = new HttpEntity(updatedInstance, headers); template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);
7.2. PUT With exchange() and a Request Callback
Next, we're going to be using a request callback to issue a PUT.
Let's make sure we prepare the callback, where we can set all the headers we need as well as a request body:
RequestCallback requestCallback(final Foo updatedInstance) { return clientHttpRequest -> { ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); clientHttpRequest.getHeaders().add( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); clientHttpRequest.getHeaders().add( HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); }; }
Next, we create the Resource with a POST request:
ResponseEntity response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
And then we update the Resource:
Foo updatedInstance = new Foo("newName"); updatedInstance.setId(response.getBody().getId()); String resourceUrl =fooResourceUrl + '/' + response.getBody().getId(); restTemplate.execute( resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null);
8. Use DELETE to Remove a Resource
ในการลบทรัพยากรที่มีอยู่เราจะใช้API delete ()อย่างรวดเร็ว:
String entityUrl = fooResourceUrl + "/" + existingResource.getId(); restTemplate.delete(entityUrl);
9. กำหนดค่าการหมดเวลา
เราสามารถกำหนดค่าRestTemplateให้หมดเวลาได้โดยใช้ClientHttpRequestFactory :
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory; }
และเราสามารถใช้HttpClientสำหรับตัวเลือกการกำหนดค่าเพิ่มเติม:
private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; RequestConfig config = RequestConfig.custom() .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setSocketTimeout(timeout) .build(); CloseableHttpClient client = HttpClientBuilder .create() .setDefaultRequestConfig(config) .build(); return new HttpComponentsClientHttpRequestFactory(client); }
10. บทสรุป
ในบทความนี้เราได้กล่าวถึงคำกริยา HTTP หลักโดยใช้RestTemplateเพื่อจัดเตรียมคำขอโดยใช้สิ่งเหล่านี้ทั้งหมด
หากคุณต้องการเจาะลึกเกี่ยวกับวิธีการตรวจสอบสิทธิ์ด้วยเทมเพลตโปรดดูบทความของเราเกี่ยวกับการตรวจสอบสิทธิ์ขั้นพื้นฐานด้วย RestTemplate
การใช้งานตัวอย่างและข้อมูลโค้ดเหล่านี้สามารถพบได้บน GitHub