java - 为什么 dto 被转换为 Map?
问题描述
我一直在试图理解为什么将 searchDto 转换为 Map。调用以下函数来获取与来自 Angular 表单的给定搜索词匹配的客户。
public Page<Customer> getCustomerFromCustomerLoan(Object searchDto, Pageable pageable) {
List<Customer> customerList = new ArrayList<>();
final ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> s = objectMapper.convertValue(searchDto, Map.class);
s.put("distinctByCustomer", "true");
s.values().removeIf(Objects::isNull);
logger.info("search param for customer in customerLoan {}", s);
final CustomerLoanSpecBuilder customerLoanSpecBuilder = new CustomerLoanSpecBuilder(s);
final Specification<CustomerLoan> specification = customerLoanSpecBuilder.build();
Page<CustomerLoan> customerLoanPage = customerLoanRepository
.findAll(specification, pageable);
customerLoanPage.getContent().forEach(customerLoan -> {
if (!customerList.contains(customerLoan)) {
customerList.add(customerLoan.getCustomerInfo());
}
});
List<Customer> finalList = customerList.stream().filter(distinctByKey(Customer::getId))
.collect(
Collectors.toList());
Page<Customer> pages = new PageImpl<Customer>(finalList, pageable,
customerLoanPage.getTotalElements());
return pages;
}
解决方案
好吧,当问到为什么有人以特定方式做某事时,我们所能做的就是做出有根据的猜测——除非有一些文档说明这背后的原因。在这种情况下,我的猜测是,因为searchDto
它的类型Object
实际上可能是几种类型之一,例如普通的 json 字符串、已经解析的 pojo 等 - 将其转换为地图可以使该 dto 中的信息在相当通用方式。
想想那些实际使用共享某些属性的不同 pojo 的 api,CustomerLoan
假设这些可能是 customerNumber
,loanAmount
等customerName
。
现在可以使用只有customerNumber
andloanAmount
而另一个具有customerNumber
and的 DTO customerName
。如果您将这些 DTO 转换为映射,您将获得一个可以传递给该类的通用结构,CustomerLoanSpecBuilder
然后该类可以检查这些属性是否存在值。
当然,您可能可以同时使用接口,instanceof
但这也可能很乏味。
我将尝试用一个例子来澄清:
使用地图可能如下所示:
Map<String, String> props = ...;
if( props.get("customerNumber") != null ) {
//add predicate for customer number
}
if( props.get("customerName") != null ) {
//add predicate for customer name
}
if( props.get("loanAmount") != null ) {
//add predicate for loan amount
}
如果您想使用接口提供一个干净的 api,则需要 3 个单独的接口,例如, ICustomerNumber
(我实际上并不喜欢这些名称,但它们应该使它们的含义有些清晰):ICustomerName
ILoanAmount
class DTO1 implements ICustomerNumber, ILoanAmount { ... }
class DTO1 implements ICustomerNumber, ICustomerName { ... }
现在使用这些可能如下所示:
Object inputDto = ...;
if( inputDto instanceof ICustomerNumber ) {
//cast to ICustomerNumber, get the value and add predicate for customer number
}
if( inputDto instanceof ICustomerName ) {
//cast to ICustomerName , get the value and add predicate for customer name
}
if( inputDto instanceof ILoanAmount ) {
//cast to ILoanAmount , get the value and add predicate for loan amount
}
另一种选择是使用反射来检查是否有一个方法被调用getCustomerNumber()
,如果是调用它,但你不想走那条路。
推荐阅读
- python - 如何使用 pyenv 更新 python 版本(将 python 3.6.2 更新到 3.6.5)
- java - 如何摆脱输入字符串
- python - 带有 !pip 的 Python SSL 错误 748
- php - Laravel Queue 是否防止并发请求插入重复记录?
- ruby-on-rails - Rails AWS 配置文件错误
- javascript - 当我使用功能单击 chrome 控制台时,我得到未定义
- ios - 我从 Appdelegate 设置的背景图像没有出现
- javascript - 如何使用 WebRTC 和 Node.js 向所有房间用户发送消息?
- spring-boot - 我该如何解决考虑在你的配置中定义一个“java.lang.String”类型的bean?
- vba - 合并两个工作表执行错误