用RestTemplate使用REST端点

摘要

  • 客户端可以使用RestTemplate对REST API发出HTTP请求。
  • Traverson使客户能够使用嵌入在响应中的超链接来导航API。

要使用RestTemplate,您需要在需要的时候创建一个实例

RestTemplate rest = new RestTemplate();

或者你可以将它声明为bean并将其注入你需要的地方:

@Bean
public RestTemplate restTemplate() {
  return new RestTemplate();
}

Get resources

 @GetMapping("/my/{ingredientId}")
    public Ingredient getMyIngredientById(@PathVariable String ingredientId){
        return rest.getForObject("http://localhost:8080/ingredients/{id}",Ingredient.class,ingredientId);
    }
@GetMapping("/my/{ingredientId}")
    public ResponseEntity<Ingredient> getMyIngredientById(@PathVariable String ingredientId){
        return rest.getForEntity("http://localhost:8080/ingredients/{id}",Ingredient.class,ingredientId);
    }

使用Map来指定URL变量:

@GetMapping("/my/{ingredientId}")
    public Ingredient getMyIngredientById(@PathVariable String ingredientId) {
        Map<String, String> urlVariables = new HashMap<>();
        urlVariables.put("id", ingredientId);
        return rest.getForObject("http://localhost:8080/ingredients/{id}", Ingredient.class, urlVariables);
    }

使用URI参数来指定URL变量:

 @GetMapping("/my/{ingredientId}")
    public Ingredient getMyIngredientById(@PathVariable String ingredientId) {
        Map<String, String> urlVariables = new HashMap<>();
        urlVariables.put("id", ingredientId);
        URI url = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/ingredients/{id}").build(urlVariables);
        return rest.getForObject(url, Ingredient.class);
    }

getForEntity()

检查响应中的Date标头

 @GetMapping("/my/{ingredientId}")
    public Ingredient getMyIngredientById(@PathVariable String ingredientId) {
        ResponseEntity<Ingredient> responseEntity = rest.getForEntity("http://localhost:8080/ingredients/{id}", Ingredient.class, ingredientId);
        log.info("Fetcded time: " + responseEntity.getHeaders().getDate());
        return responseEntity.getBody();
    }

Put resources

 //客户端Put
    @PutMapping(path = "/my",consumes = "application/json")
    public void updateIngredient2(@RequestBody Ingredient ingredient){
        rest.put("http://localhost:8080/ingredients/{id}",ingredient,ingredient.getId());
    }

    //服务端
    @PutMapping("/{id}")
    public void updateIngredient(@RequestBody Ingredient ingredient) {
        ingredientRepo.save(ingredient);
    }

    @PatchMapping(path = "/{id}",consumes = "application/json")
    public  void patchIngredient(@PathVariable String id,@RequestBody Ingredient patch) {
        Ingredient ingredient = ingredientRepo.findById(id).get();
        if (patch.getType() != null) {
            ingredient.setType(patch.getType());
        }
        if (patch.getName() != null) {
            ingredient.setName(patch.getName());
        }
        ingredientRepo.save(ingredient);
    }

 Delete resources

public void deleteIngredient(Ingredient ingredient) {
  rest.delete("http://localhost:8080/ingredients/{id}",
              ingredient.getId());
}

Post resource data

在POST请求后收到新创建的资源,您可以这样使用postForObject():

public Ingredient createIngredient(Ingredient ingredient) {
  return rest.postForObject("http://localhost:8080/ingredients",
                            ingredient,
                            Ingredient.class);
}

需要新创建的资源的位置,那么您可以调用postForLocation():

public URI createIngredient(Ingredient ingredient) {
  return rest.postForLocation("http://localhost:8080/ingredients",
                              ingredient);
}

需要位置和响应实例,则可以调用postForEntity():

public Ingredient createIngredient(Ingredient ingredient) {
  ResponseEntity<Ingredient> responseEntity =
         rest.postForEntity("http://localhost:8080/ingredients",
                            ingredient,
                            Ingredient.class);

  log.info("New resource created at " +
           responseEntity.getHeaders().getLocation());

  return responseEntity.getBody();
}

使用Traverson导航REST API

Traverson附带Spring Data HATEOAS作为在Spring应用程序中使用超媒体API的开箱即用解决方案。

Traverson的名称听起来像“遍历”,这是描述它如何使用的好方法。在本节中,您将通过遍历关系名称的API来使用API​​。

使用Traverson开始使用TraversonAPI的基URI 实例化对象:

Traverson traverson = new Traverson(
    URI.create("http://localhost:8080/api"), MediaTypes.HAL_JSON);

我将Traverson指向了Taco Cloud的基本URL(在本地运行)。这是您需要向Traverson提供的唯一网址。

有了一个Traverson对象,您可以通过以下链接开始使用API​​。

ParameterizedTypeReference<Resources<Ingredient>> ingredientType =
    new ParameterizedTypeReference<Resources<Ingredient>>() {};

Resources<Ingredient> ingredientRes =
    traverson
      .follow("ingredients")
      .toObject(ingredientType);

Collection<Ingredient> ingredients = ingredientRes.getContent();

该toObject()方法要求您告诉它将数据读入哪种对象。考虑到您需要将其作为Resources<Ingredient>对象读取,这可能会有点棘手,而Java类型擦除使得难以为泛型类型提供类型信息。但是要创造一个ParameterizedTypeReference帮助。

现在让我们考虑一个稍微有趣的用例。假设你想要获取最近创建的玉米饼。从主资源开始,您可以导航到最近的tacos资源,如下所示:

ParameterizedTypeReference<Resources<Taco>> tacoType =
    new ParameterizedTypeReference<Resources<Taco>>() {};

Resources<Taco> tacoRes =
    traverson
      .follow("tacos")
      .follow("recents")
      .toObject(tacoType);

Collection<Taco> tacos = tacoRes.getContent();

.follow()通过列出要遵循的关系名称的跟踪,可以简化该方法:

Resources<Taco> tacoRes =
    traverson
      .follow("tacos", "recents")
      .toObject(tacoType);

Traverson可以轻松地导航启用HATEOAS的API并消耗其资源。但它没有做的一件事是提供任何写入或删除这些API的方法。相比之下,RestTemplate可以编写和删除资源,但不能轻松导航API。

当您需要导航API并更新或删除资源时,您需要同时使用RestTemplate和Traverson。Traverson仍可用于导航到将创建新资源的链接。然后,RestTemplate可以给该链接做了POST,PUT,DELETE,或者任何其他HTTP请求你所需要的。

例如,假设您要向IngredientTaco Cloud菜单添加新内容。以下addIngredient()方法组合Traverson并向API RestTemplate发布新内容Ingredient:

private Ingredient addIngredient(Ingredient ingredient) {
  String ingredientsUrl = traverson
      .follow("ingredients")
      .asLink()
      .getHref();

  return rest.postForObject(ingredientsUrl,
                            ingredient,
                            Ingredient.class);
}

按照“成分”链接后,您可以通过致电询问链接本身asLink()。从该链接,您可以通过调用来请求链接的URL getHref()。随着在手的URL,你有你需要的一切调用postForObject()的RestTemplate实例,并保存新的成分。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值