客户端与 Rest 资源交互涉及很多工作,通常都是单调的模板代码。如果使用较低层级的 HTTP 库,客户端就需要创建一个客户端实例和请求对象、执行请求、解析响应、将响应映射为领域对象,并且还要处理这个过程中可能会抛出的所有异常。
Spring 提供了 RestTemplate 来避免样板代码,就像 JdbcTemplate 一样。
1、用法
RestTemplate 拥有很多操作方法,主要分为以下几种形式:
形式 | 含义 |
---|---|
...ForEntity() | 发送一个 GET 或 POST 请求,返回的 ResponseEntity 包含了由响应体所映射成的对象,有 getForEntity()、postForEntity() |
...ForObject() | 发送一个 GET、POST 或 PATCH 请求,返回的响应体将映射为一个对象,支持方法有:getForObject()、postForObject()、patchForObject() |
postForLocation() | POST 数据到一个 URL,返回一个新创建资源的 URL |
put() | PUT 资源到特定的 URL,主要用于更新数据 |
execute() | 在 URL 上执行特定的HTTP方法,返回一个从响应体映射得到的对象 |
exchange() | 在 URL 上执行特定的HTTP方法,返回一个包含了由响应体所映射成的ResponseEntity 对象 |
2、获取资源
(1)获取 POJO
// 1、使用URL占位变量,并指定 POJO 类型和传参
public Ingredient getIngredientById(String ingredientId) {
/**
* "http://localhost:8080/ingredients/{id}": 要被调用的接口
* Ingredient.class: 调用接口返回JSON要被反序列化为的对象类型
* ingredientId: 传入接口的参数
*/
try {
return rest.getForObject("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
ingredientId);
} catch (HttpClientErrorException e) {
if (e.getRawStatusCode() == 404) {
log.info("there not exists ingredient(" + ingredientId + ")");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 2、使用URL占位变量,并指定 POJO 类型和传入Map参数
public Ingredient getIngredientById2(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
return rest.getForObject("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
urlVariables);
}
// 3、使用 URI 参数
public Ingredient getIngredientById3(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
URI url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/api/ingredients/{id}")
.build(urlVariables);
return rest.getForObject(url, Ingredient.class);
}
// 4、获取ResponseEntity对象,得到响应细节,并提取POJO
public Ingredient getIngredientById4(String ingredientId) {
ResponseEntity<Ingredient> responseEntity =
rest.getForEntity("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
ingredientId);
log.info("Fetched time: " + responseEntity.getHeaders().getDate());
log.info("Response header: " + responseEntity.getHeaders());
log.info("Response status: " + responseEntity.getStatusCode());
return responseEntity.getBody();
}
// 5、使用 URI 参数并获取 ResponseEntity
public Ingredient getIngredientById5(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
URI url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/api/ingredients/{id}")
.build(urlVariables);
ResponseEntity<Ingredient> responseEntity = rest.getForEntity(url, Ingredient.class);
log.info("Fetched time: " + responseEntity.getHeaders().getDate());
log.info("Response header: " + responseEntity.getHeaders());
log.info("Response status: " + responseEntity.getStatusCode());
return responseEntity.getBody();
}
// 6、查询获取数据列表
public List<Ingredient> getAllIngredients() {
return rest.exchange("http://localhost:8080/ingredients",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Ingredient>>() {})
.getBody();
}
(2)获取 JSON
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response
= restTemplate.getForEntity("http://localhost:8080/ingredients/{id}",
String.class,
ingredientId);
String json = response.getBody();
(3)获取 Header
public void retrieveHeaders() {
HttpHeaders httpHeaders = rest.headForHeaders("http://localhost:8080/api/ingredients");
log.info("Headers : " + httpHeaders);
}
测试:
Headers : [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Link:"<http://localhost:8080/api/ingredients>;rel="self",<http://localhost:8080/api/profile/ingredients>;rel="profile"", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"SAMEORIGIN", Date:"Wed, 26 Apr 2023 08:03:22 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]
3、更新资源
RestTemplate rest = new RestTemplate();
// 1、URL 使用占位变量,传入参数
public void updateIngredient(Ingredient ingredient) {
rest.put("http://localhost:8080/api/ingredients/{id}",
ingredient,
ingredient.getId());
}
// 2、URL 使用占位变量,传入Map参数
public void updateIngredient2(Ingredient ingredient) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredient.getId());
rest.put("http://localhost:8080/api/ingredients/{id}",
ingredient,
urlVariables);
}
// 3、使用exchange(),指定请求方法为 POST
public void updateIngredient3(Ingredient ingredient) {
HttpEntity<Ingredient> entity = new HttpEntity<Ingredient>(ingredient);
rest.exchange("http://localhost:8080/api/ingredients/{id}",
HttpMethod.PUT,
entity,
Ingredient.class,
ingredient.getId());
}
4、创建资源
RestTemplate rest = new RestTemplate();
// 1、使用 postForObject()
public Ingredient createIngredient(Ingredient ingredient) {
return rest.postForObject("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
}
// 2、使用 postForLocation()
// 返回的URI是从响应的Location头信息派生出来的
public URI createIngredient2(Ingredient ingredient) {
return rest.postForLocation("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
}
// 3、使用 postForEntity()
public Ingredient createIngredient3(Ingredient ingredient) {
ResponseEntity<Ingredient> responseEntity =
rest.postForEntity("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
log.info("New resource created at " + responseEntity.getHeaders().getLocation());
return responseEntity.getBody();
}
5、删除资源
public void deleteIngredient(Ingredient ingredient) {
rest.delete("http://localhost:8080/api/ingredients/{id}",
ingredient.getId());
}
6、提交表单数据
首先,我们需要将 Content-Type 标头设置为 application/x-www-form-urlencoded。 这可确保可以将大型查询字符串发送到服务器,其中包含由 & 分隔的键值对。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// 将表单变量包装到 MultiValueMap 中
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("id", "1");
// 构建 HttpEntity 请求实例
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
// 通过在端点上调用 restTemplate.postForEntity() 来连接到 REST 服务:/foos/form
ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl+"/form",
request ,
String.class);
Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED);
7、测试
客户端代码:
package tacos.restclient;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.client.Traverson;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import lombok.extern.slf4j.Slf4j;
import tacos.Ingredient;
import tacos.Order;
import tacos.Taco;
@Service
@Slf4j
public class TacoCloudClient {
private RestTemplate rest;
private Traverson traverson;
public TacoCloudClient(RestTemplate rest, Traverson traverson) {
this.rest = rest;
this.traverson = traverson;
}
/**
* Get Example
*/
// 将参数指定为可变参数
public Ingredient getIngredientById(String ingredientId) {
/**
* "http://localhost:8080/ingredients/{id}": 要被调用的接口
* Ingredient.class: 调用接口返回JSON要被反序列化为的对象类型
* ingredientId: 传入接口的参数
*/
try {
return rest.getForObject("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
ingredientId);
} catch (HttpClientErrorException e) {
if (e.getRawStatusCode() == 404) {
log.info("there not exists ingredient(" + ingredientId + ")");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 使用Map传参
public Ingredient getIngredientById2(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
return rest.getForObject("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
urlVariables);
}
// 使用URL参数、Map传参
public Ingredient getIngredientById3(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
URI url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/api/ingredients/{id}")
.build(urlVariables);
return rest.getForObject(url, Ingredient.class);
}
// 使用getForEntity返回的是一个ResponseEntity对象,可以获取响应细节比如响应头信息
public Ingredient getIngredientById4(String ingredientId) {
ResponseEntity<Ingredient> responseEntity = rest.getForEntity("http://localhost:8080/api/ingredients/{id}",
Ingredient.class,
ingredientId);
log.info("Fetched time: " + responseEntity.getHeaders().getDate());
log.info("Response header: " + responseEntity.getHeaders());
log.info("Response status: " + responseEntity.getStatusCode());
return responseEntity.getBody();
}
public Ingredient getIngredientById5(String ingredientId) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredientId);
URI url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/api/ingredients/{id}")
.build(urlVariables);
ResponseEntity<Ingredient> responseEntity = rest.getForEntity(url, Ingredient.class);
log.info("Fetched time: " + responseEntity.getHeaders().getDate());
log.info("Response header: " + responseEntity.getHeaders());
log.info("Response status: " + responseEntity.getStatusCode());
return responseEntity.getBody();
}
public List<Ingredient> getAllIngredients() {
return rest.exchange("http://localhost:8080/ingredients",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Ingredient>>() {}).getBody();
}
public Order getOrderById(int orderId) {
return rest.getForObject("http://localhost:8080/api/orders/{id}",
Order.class,
orderId);
}
public void updateOrder(Order order) {
rest.put("http://localhost:8080/api/orders/{id}",
order,
order.getId());
}
/**
* Put Example
*/
public void updateIngredient(Ingredient ingredient) {
rest.put("http://localhost:8080/api/ingredients/{id}",
ingredient,
ingredient.getId());
}
public void updateIngredient2(Ingredient ingredient) {
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("id", ingredient.getId());
rest.put("http://localhost:8080/api/ingredients/{id}",
ingredient,
urlVariables);
}
public void updateIngredient3(Ingredient ingredient) {
HttpEntity<Ingredient> entity = new HttpEntity<Ingredient>(ingredient);
rest.exchange("http://localhost:8080/api/ingredients/{id}",
HttpMethod.PUT,
entity,
Ingredient.class,
ingredient.getId());
}
// Delete Example
public void deleteIngredient(Ingredient ingredient) {
rest.delete("http://localhost:8080/api/ingredients/{id}",
ingredient.getId());
}
// Post Example
public Ingredient createIngredient(Ingredient ingredient) {
return rest.postForObject("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
}
// 返回的URI是从响应的Location头信息派生出来的
public URI createIngredient2(Ingredient ingredient) {
return rest.postForLocation("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
}
public Ingredient createIngredient3(Ingredient ingredient) {
ResponseEntity<Ingredient> responseEntity = rest.postForEntity("http://localhost:8080/api/ingredients",
ingredient,
Ingredient.class);
log.info("New resource created at " + responseEntity.getHeaders().getLocation());
return responseEntity.getBody();
}
public void retrieveHeaders() {
HttpHeaders httpHeaders = rest.headForHeaders("http://localhost:8080/api/ingredients");
log.info("Headers : " + httpHeaders);
}
//
// Traverson with RestTemplate examples
//
public Iterable<Ingredient> getAllIngredientsWithTraverson() {
ParameterizedTypeReference<CollectionModel<Ingredient>> ingredientType = new ParameterizedTypeReference<CollectionModel<Ingredient>>() {
};
CollectionModel<Ingredient> ingredientRes = traverson.follow("ingredients").toObject(ingredientType);
//Resources<Ingredient> ingredientRes = traverson.follow("ingredients").toObject(ingredientType);
Collection<Ingredient> ingredients = ingredientRes.getContent();
return ingredients;
}
public Ingredient addIngredient(Ingredient ingredient) {
String ingredientsUrl = traverson.follow("ingredients").asLink().getHref();
return rest.postForObject(ingredientsUrl, ingredient, Ingredient.class);
}
public Iterable<Taco> getRecentTacosWithTraverson() {
ParameterizedTypeReference<CollectionModel<Taco>> tacoType = new ParameterizedTypeReference<CollectionModel<Taco>>() {
};
CollectionModel<Taco> tacoRes = traverson.follow("tacos").follow("recent").toObject(tacoType);
return tacoRes.getContent();
}
}
测试代码:
package tacos.restclient;
import java.net.URI;
import java.util.List;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.client.Traverson;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;
import tacos.Ingredient;
import tacos.Order;
import tacos.Taco;
@SpringBootConfiguration
@ComponentScan
@Slf4j
public class RestExamples {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RestExamples.class, args);
}
// 根据id获取单个配料,获取所有的配料列表
@Bean
public CommandLineRunner fetchIngredients(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- GET -------------------------");
log.info("GETTING INGREDIENT BY IDE");
log.info("Ingredient: " + tacoCloudClient.getIngredientById("CHED"));
log.info("GETTING ALL INGREDIENTS");
List<Ingredient> ingredients = tacoCloudClient.getAllIngredients();
log.info("All ingredients:");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
log.info("");
};
}
@Bean
public CommandLineRunner fetchIngredients2(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- GET(Map variables) -------------------------");
log.info("GETTING INGREDIENT BY IDE");
log.info("Ingredient: " + tacoCloudClient.getIngredientById2("CHED"));
log.info("GETTING ALL INGREDIENTS");
List<Ingredient> ingredients = tacoCloudClient.getAllIngredients();
log.info("All ingredients:");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
log.info("");
};
}
@Bean
public CommandLineRunner fetchIngredients3(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- GET(URL & Map variables) -------------------------");
log.info("GETTING INGREDIENT BY IDE");
log.info("Ingredient: " + tacoCloudClient.getIngredientById3("CHED"));
log.info("GETTING ALL INGREDIENTS");
List<Ingredient> ingredients = tacoCloudClient.getAllIngredients();
log.info("All ingredients:");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
log.info("");
};
}
@Bean
public CommandLineRunner fetchIngredientsResponseEntity(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- GET(ResponseEntity) -------------------------");
log.info("GETTING INGREDIENT BY IDE");
log.info("Ingredient: " + tacoCloudClient.getIngredientById4("CHED"));
log.info("GETTING ALL INGREDIENTS");
List<Ingredient> ingredients = tacoCloudClient.getAllIngredients();
log.info("All ingredients:");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
log.info("");
};
}
@Bean
public CommandLineRunner fetchIngredientsResponseEntity2(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- GET(ResponseEntity2) -------------------------");
log.info("GETTING INGREDIENT BY IDE");
log.info("Ingredient: " + tacoCloudClient.getIngredientById5("CHED"));
log.info("GETTING ALL INGREDIENTS");
List<Ingredient> ingredients = tacoCloudClient.getAllIngredients();
log.info("All ingredients:");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
log.info("");
};
}
// 获取并更新一条配料数据
//@Bean
public CommandLineRunner putAnIngredient(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- PUT -------------------------");
Ingredient before = tacoCloudClient.getIngredientById("LETC");
log.info("BEFORE: " + before);
tacoCloudClient.updateIngredient(new Ingredient("LETC", "Lettuce", Ingredient.Type.VEGGIES));
Ingredient after = tacoCloudClient.getIngredientById("LETC");
log.info("AFTER: " + after);
log.info("");
};
}
//@Bean
public CommandLineRunner putAnIngredient2(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- PUT -------------------------");
Ingredient before = tacoCloudClient.getIngredientById("LETC");
log.info("BEFORE: " + before);
tacoCloudClient.updateIngredient2(new Ingredient("LETC", "VEGGIES", Ingredient.Type.VEGGIES));
Ingredient after = tacoCloudClient.getIngredientById("LETC");
log.info("AFTER: " + after);
log.info("");
};
}
//@Bean
public CommandLineRunner putAnIngredient3(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- PUT(Call exchange) -------------------------");
Ingredient before = tacoCloudClient.getIngredientById("LETC");
log.info("BEFORE: " + before);
tacoCloudClient.updateIngredient3(new Ingredient("LETC", "Lettuce", Ingredient.Type.VEGGIES));
Ingredient after = tacoCloudClient.getIngredientById("LETC");
log.info("AFTER: " + after);
log.info("");
};
}
// 删除一条配料数据
//@Bean
public CommandLineRunner deleteAnIngredient(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- DELETE -------------------------");
Ingredient before = tacoCloudClient.getIngredientById("CHIX");
log.info("BEFORE DELETE: " + before);
Ingredient chix = new Ingredient("CHIX", "Shredded Chicken", Ingredient.Type.PROTEIN);
tacoCloudClient.deleteIngredient(chix);
Ingredient after = tacoCloudClient.getIngredientById("CHIX");
log.info("AFTER DELETE: " + after);
log.info("");
Ingredient before2 = tacoCloudClient.getIngredientById("CHIY");
log.info("BEFORE DELETE: " + before2);
Ingredient chix2 = new Ingredient("CHIY", "Shredded Chicken", Ingredient.Type.PROTEIN);
tacoCloudClient.deleteIngredient(chix2);
Ingredient after2 = tacoCloudClient.getIngredientById("CHIY");
log.info("AFTER DELETE: " + after2);
log.info("");
Ingredient before3 = tacoCloudClient.getIngredientById("CHIZ");
log.info("BEFORE DELETE: " + before3);
Ingredient chix3 = new Ingredient("CHIZ", "Shredded Chicken", Ingredient.Type.PROTEIN);
tacoCloudClient.deleteIngredient(chix3);
Ingredient after3 = tacoCloudClient.getIngredientById("CHIZ");
log.info("AFTER DELETE: " + after3);
log.info("");
};
}
// 添加一条配料数据
//@Bean
public CommandLineRunner addAnIngredient(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- POST -------------------------");
Ingredient chix = new Ingredient("CHIX", "Shredded Chicken", Ingredient.Type.PROTEIN);
Ingredient chixAfter = tacoCloudClient.createIngredient(chix);
log.info("AFTER=1: " + chixAfter);
log.info("");
};
}
//@Bean
public CommandLineRunner addAnIngredient2(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- POST(RETURN URI) -------------------------");
Ingredient chix = new Ingredient("CHIY", "Shredded Chicken", Ingredient.Type.PROTEIN);
URI uri = tacoCloudClient.createIngredient2(chix);
log.info("ADD URI: " + uri);
log.info("");
};
}
//@Bean
public CommandLineRunner addAnIngredient3(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- POST(RETURN ResponseEntity) -------------------------");
Ingredient chiz = new Ingredient("CHIZ", "Shredded Chicken", Ingredient.Type.PROTEIN);
Ingredient chizAdd = tacoCloudClient.createIngredient3(chiz);
log.info("AFTER=1: " + chizAdd);
log.info("");
};
}
// 删除一条配料数据
//@Bean
public CommandLineRunner deleteAnIngredient2(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- DELETE -------------------------");
// start by adding a few ingredients so that we can delete them later...
Ingredient beefFajita = new Ingredient("BFFJ", "Beef Fajita", Ingredient.Type.PROTEIN);
tacoCloudClient.createIngredient(beefFajita);
Ingredient shrimp = new Ingredient("SHMP", "Shrimp", Ingredient.Type.PROTEIN);
tacoCloudClient.createIngredient(shrimp);
Ingredient before = tacoCloudClient.getIngredientById("CHIX");
log.info("BEFORE: " + before);
before.setId("CHIX");
tacoCloudClient.deleteIngredient(before);
Ingredient after = tacoCloudClient.getIngredientById("CHIX");
log.info("AFTER: " + after);
before = tacoCloudClient.getIngredientById("BFFJ");
log.info("BEFORE: " + before);
before.setId("BFFJ");
tacoCloudClient.deleteIngredient(before);
after = tacoCloudClient.getIngredientById("BFFJ");
log.info("AFTER: " + after);
before = tacoCloudClient.getIngredientById("SHMP");
log.info("BEFORE: " + before);
before.setId("SHMP");
tacoCloudClient.deleteIngredient(before);
after = tacoCloudClient.getIngredientById("SHMP");
log.info("AFTER: " + after);
};
}
//@Bean
public CommandLineRunner putOrder(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- PUT(GET -> UPDATE -> GET) -------------------------");
// 因为hateoas返回单个数据对象时不带id,所以下面要重新set一下
Order before = tacoCloudClient.getOrderById(1);
log.info("BEFORE: " + before);
before.setDeliveryName("胡奕豪");
before.setId(1L);
tacoCloudClient.updateOrder(before);
Order after = tacoCloudClient.getOrderById(1);
log.info("AFTER: " + after);
log.info("");
};
}
//@Bean
public CommandLineRunner headers(TacoCloudClient tacoCloudClient) {
return args -> {
log.info("----------------------- Headers -------------------------");
tacoCloudClient.retrieveHeaders();
log.info("");
};
}
/**
* 参数1:指定基础URL
* 参数2:指定API生成JSON格式的响应,并且具有HAL风格的超链接
*/
@Bean
public Traverson traverson() {
Traverson traverson = new Traverson(URI.create("http://localhost:8080/api"), MediaTypes.HAL_JSON);
return traverson;
}
//@Bean
public CommandLineRunner traversonGetIngredients(TacoCloudClient tacoCloudClient) {
return args -> {
Iterable<Ingredient> ingredients = tacoCloudClient.getAllIngredientsWithTraverson();
log.info("----------------------- GET INGREDIENTS WITH TRAVERSON -------------------------");
for (Ingredient ingredient : ingredients) {
log.info(" - " + ingredient);
}
};
}
//@Bean
public CommandLineRunner traversonSaveIngredient(TacoCloudClient tacoCloudClient) {
return args -> {
Ingredient pico = tacoCloudClient
.addIngredient(new Ingredient("PICO", "Pico de Gallo", Ingredient.Type.SAUCE));
List<Ingredient> allIngredients = tacoCloudClient.getAllIngredients();
log.info("----------------------- ALL INGREDIENTS AFTER SAVING PICO -------------------------");
for (Ingredient ingredient : allIngredients) {
log.info(" - " + ingredient);
}
tacoCloudClient.deleteIngredient(pico);
log.info("");
};
}
//@Bean
public CommandLineRunner traversonRecentTacos(TacoCloudClient tacoCloudClient) {
return args -> {
Iterable<Taco> recentTacos = tacoCloudClient.getRecentTacosWithTraverson();
log.info("----------------------- GET RECENT TACOS WITH TRAVERSON -------------------------");
for (Taco taco : recentTacos) {
log.info(" - " + taco);
}
log.info("");
};
}
}