将参数传递给 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;
}
然后,如果 customerId
是 null
或一些空格或不存在,我希望结果是 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 = ...;
一些注意事项:
getCustomer
实际上 returns 一个 JSONObject
,而不是一个 Customer
。
templateURL
将基础 URL 和 URL 硬编码给客户。
- 该方法做了很多工作(承担了太多责任)- 参数验证、URL 构造、发出请求。尝试在相应的方法之间拆分这些职责。
为了编写干净智能的代码,我想知道我可以做些什么来改进我的实际代码:
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;
}
然后,如果 customerId
是 null
或一些空格或不存在,我希望结果是 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 = ...;
一些注意事项:
getCustomer
实际上 returns 一个JSONObject
,而不是一个Customer
。templateURL
将基础 URL 和 URL 硬编码给客户。- 该方法做了很多工作(承担了太多责任)- 参数验证、URL 构造、发出请求。尝试在相应的方法之间拆分这些职责。