将参数传递给 restTemplate.getForObject 的最佳方式

Best way to passing parameter to restTemplate.getForObject

为了编写干净智能的代码,我想知道我可以做些什么来改进我的实际代码:

public JSONObject getCustomer(final String customerId) {
    if (customerId == null || customerId.equals("")) {
        return null;
    } else {
        final RestTemplate restTemplate = new RestTemplate();
        final String result = restTemplate.getForObject("http://localhost:6061/customers/" + customerId,
                String.class);
        return new JSONObject(result);
    }
}

特别是,我不喜欢我编写 url 的方式,也不喜欢检查 customerId 的值。

我想要类似 JPA 的东西,我在其中询问一些传递参数的信息,只是为了清楚(在伪代码中):

public JSONObject getCustomer(final String customerId) {
    final RestTemplate restTemplate = new RestTemplate();
    final Query query = restTemplate.query("http://localhost:6061/customers/:customerId");

    query.addParameter("customerId", customerId);
    JSONObject result = query.getForObject();

    return result;
}

然后,如果 customerIdnull 或一些空格或不存在,我希望结果是 null。 有没有办法用标准库做到这一点?

谢谢

首先,我宁愿使用 DTO 对象来保存响应数据并对其进行操作,而不是使用负载的字符串表示形式。所以你可以这样改变它。 Jackson 负责数据的所有序列化和反序列化。

CustomerDTO customerDTO = restTemplate
                    .getForEntity("http://localhost:6061/customers/{customerId}", CustomerDTO.class, customerId).getBody();

您可以在控制器上使用 javax.validators(例如 @Min@NotEmpty 等)来检查空值。下面给出了示例。

@RequestMapping(value = someURL, params = {"id"})
public SomeResponse doSomething(@PathVariable(value = "id") @Size(min=1) String id)

这会抛出一个 ValidationException,其中包含一条可以由您自定义的相关错误消息。然后,您需要有一个错误处理方面,它在 ErrorDTO 对象中设置错误消息并适当地设置状态代码。

首先,我将删除 else 分支并将条件重构为:

public JSONObject getCustomer(final String customerId) {
    if (isNull(customerId) || customerId.trim().isEmpty()) {
        return null;
    }
    ...
}

其次,如果你有一堆 URI 变量,Spring guys recommend 使用 Map<String, String>:

final String templateURL = "http://localhost:6061/customers/{customerId}";
final Map<String, String> variables = new HashMap<>();

variables.put("customerId", customerId);
...

template.getForObject(templateURL, String.class, variables);

第三,该方法不应自行创建 RestTemplate 实例。我更愿意将已经调优的对象注入实例字段:

getTemplate().getForObject(templateURL, String.class, variables);

最后,我会命名 result 更有意义:

final String customerRepresentation = ...;

一些注意事项:

  1. getCustomer 实际上 returns 一个 JSONObject,而不是一个 Customer
  2. templateURL 将基础 URL 和 URL 硬编码给客户。
  3. 该方法做了很多工作(承担了太多责任)- 参数验证、URL 构造、发出请求。尝试在相应的方法之间拆分这些职责。