有没有办法映射 Sort 对象的属性?举个小例子:
a Dto
public class OrderDto {
private long totalAmount;
private long openAmount;
}
和一个实体
@Entity
public class Order {
private long amount;
}
和控制器
@RestController
public class OrderController {
@GetMapping("/orders")
public Page<OrderDto> findOrders(Pageable pageable) {
// Do something
}
}
我现在会打电话给
/orders?sort=totalAmount,desc
是否可以映射排序属性,在本例中,将 Dto 中的
totalAmount
映射到仅 amount
,以便以一种迷人的方式将其用于生成的 JPA 查询?
我不知道我是否正确回答了你的问题,但是...
我理解正确吗,您希望将请求参数
sort
与值 totalAmount,desc
映射,以便通过给定 Sort
对象的 Pageable
对象作为 amount
使用(顺序为 desc
)
)?
由于您在帖子中提到的名称,我希望您的类路径上有 Spring Data。
IDKFS,但也许类
SortHandlerMethodArgumentResolverCustomizer
可以帮助您自定义SortHandlerMethodArgumentResolver
的方式,您可以像您想要的那样映射请求参数。
如果没有,应该可以提供一个
SortHandlerMethodArgumentResolver
类型的 @Bean 来实现您想要的行为。
我不完全确定框架是否允许覆盖您需要自定义的特定部分,但在我看来值得一看。 :)
我面临着同样的情况,我在互联网上找到的答案都没有足够清楚地说明如何使用 Spring 完成此操作,因此为了使情况更清楚,我将发布我想出的解决方案。
。您可以摆脱 DTO 并解决这个问题,但没有人愿意失去那个抽象层。 在示例中,API 将字段
amount
转换为
totalAmount
,但是当查询 totalAmount
(客户端不必知道转换或属性的真实名称)时,API 通过服务和存储库,无法找到该属性totalAmount
。Spring 中如何处理这个问题?
第一件事是创建一个
SortArgumentResolver
,它负责修改作为排序参数传递的属性,同时保留其余排序参数(小心复杂的场景,在不同的请求上可能存在冲突的属性)。
public class OrderSortArgumentResolver implements SortArgumentResolver {
private final SortArgumentResolver delegate;
public OrderSortArgumentResolver(SortArgumentResolver delegate) {
this.delegate = delegate;
}
@Override
@NonNull
public boolean supportsParameter(MethodParameter parameter) {
return delegate.supportsParameter(parameter);
}
@Override
@NonNull
public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeRequest webRequest, WebDataBinderFactory binderFactory) {
Sort originalSort = delegate.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
Sort modifiedSort = Sort.unsorted();
if(!originalSort.isEmpty()) {
// INFO: this will retain any other sort parameter aside from the one being modified
for (Sort.Order order : originalSort) {
if (order.getProperty().equals("totalAmount")) {
modifiedSort = modifiedSort.and(Sort.by(order.getDirection(), "amount"));
} else {
modifiedSort = modifiedSort.and(Sort.by(order.getDirection(), order.getProperty()));
}
}
}
return modifiedSort;
}
}
获得参数解析器后,您需要将其添加到应用程序配置中。
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final SortArgumentResolver sortArgumentResolver;
public WebConfig(SortArgumentResolver sortArgumentResolver) {
this.sortArgumentResolver = sortArgumentResolver;
}
@Override
public void addArgumentResolver(List<HandlerMethodArgumentResolver> resolvers) {
// INFO: this will handle paged requests
PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver(new OrderSortArgumentResolver(sortArgumentResolver));
resolvers.add(pageableResolver);
//INFO: this will handle any other requests
resolvers.add(new OrderSortArgumentResolver(sortArgumentResolver));
}
}
希望这对遇到同样情况的人有帮助。