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

时间:2017-11-30 16:56:35

标签: java spring code-cleanup

为了编写一个干净而智能的代码,我想知道如何改进我的实际代码:

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。 有没有办法用标准库做到这一点?

由于

2 个答案:

答案 0 :(得分:1)

首先,我宁愿使用DTO对象来保存响应数据并操纵它们,而不是使用有效负载的String表示。所以你可以这样改变它。杰克逊负责处理数据的所有序列化和反序列化。

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对象中设置错误消息并正确设置状态代码。

答案 1 :(得分:1)

首先,我会删除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实际上会返回JSONObject,而不是Customer
  2. templateURL对基本网址以及客户网址进行了硬编码。
  3. 该方法做了很多工作(承担了太多的责任) - 参数验证,URL构造,发出请求。尝试在相应的方法之间分配这些责任。