gpt4 book ai didi

java - Spring Data JPA 无效的 page.sort 参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:22:26 26 4
gpt4 key购买 nike

在将 Spring Data JPA 与 Hibernate 结合使用的 Web 应用程序中,我们利用 web pagination在各种实体列表中提供分页和排序功能的功能。

@Controller
public class MyEntityController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView list(Pageable pageable) { ... }
}

@Configuration
public class MyWebMvcConfig extends WebMvcConfigurationSupport {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new PageableArgumentResolver());
}
}

public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, String> {
Page<MyEntity> findByPropertyX(String propertyX, Pageable pagable);
}

这允许在呈现的 html 中将实体属性定义为特殊类型 request parameters ,其中 page.sort 值实际上与要排序的实体中的属性匹配。

<table>
<thead>
<tr>
<th><a href="?page.sort=propertyX&amp;page.sort.dir=asc">Property X</a></th>
<th><a href="?page.sort=propertyY&amp;page.sort.dir=asc">Property Y</a></th>
</tr>
</thead>
<tbody>...</tbody>
</table>

这会生成一个结果 URL,例如:

http://host/context-root/entities/?page.sort=propertyX&page.sort.dir=asc

问题是用户可能会修改 URL 以使用无效的 page.sort 属性,这些属性引用不存在的列/属性名称,或者更糟的是,使用无效的 JPA 查询字符导致无效语法。

例如,如果将 URL 修改为按“noSuchProperty”排序:

http://host/context-root/entities/?page.sort=noSuchProperty&page.sort.dir=asc

但是这个属性不存在,会抛出如下异常:

java.lang.IllegalArgumentException: No property noSuchProperty found for type class com.my.company.MyEntity
at org.springframework.data.repository.query.parser.Property.<init>(Property.java:76)
. . .
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:86)
. . .
at $Proxy68.findByPropertyX(Unknown Source)
at com.my.company.MyEntityRepository.findByPropertyX(MyEntityRepository.java:17

同样,如果 URL 被修改为无效的查询语法字符,例如“””:

http://host/context-root/entities/?page.sort=%22&page.sort.dir=asc

会出现如下错误:

java.lang.StackOverflowError
java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
. . .
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)

(当在 Repository 方法上显式定义 @Query 时,还有第三种异常会导致 org.hibernate.QueryException。)

Spring Data JPA 抽象出排序、分页和处理这些参数的细节;但是,它似乎无法妥善处理这些情况(即指定了无效的排序参数)。

我们可以添加一些额外的自定义逻辑来验证排序属性是否确实存在于实体上;但是,我想知道是否有一种更清洁、更集中的方法来执行此操作,这样我们就不会失去 Spring Data JPA 抽象的好处和简单性。我们在整个应用程序中对许多不同的实体使用这种排序功能,因此理想情况下,我们需要更多的通用方法,而不必为请求的每个实体页面显式定义或检查排序属性。

具体来说,我们实际上扩展了 PageableArgumentResolver 以接受我们的 Controller 中提供的带注释的排序默认值(为简单起见,代码示例中未说明),因此我们只想回退到此默认排序顺序,或只是实体的默认排序顺序,而不是抛出异常。

一些想法和尝试..我可以使用QueryCreationListener来拦截查询创建并获取排序参数;但是,此时我实际上无法修改查询。或者,我可以扩展并使用自定义 PageableArgumentResolver(我们已经在这样做)来获取排序参数;但是,此时我无权访问该实体,也无法确定该实体是否确实具有该名称的属性。我们可以明确声明支持的属性;然而,这又一次打败了集中自动处理这种情况而不需要实体的特定或公开知识的想法。

是否有任何其他类型的拦截器或类似构造可用于集中验证可分页排序参数并在调用查询之前根据需要进行修改?或者是否有任何类型的配置或方法可以让 Spring 自动处理这种情况,以便更优雅地处理无效的排序参数?

最佳答案

我正在查看代码,我认为更多的堆栈跟踪会有所帮助。但据我所知,如果您有心情重写一些 Spring 代码,我认为您可能需要解决两个问题。

这里有两种情况,在第一种情况下,您要传递对象/表中不存在的排序字段。你真正想要的是一直默默地忽略那个错误的参数,而不仅仅是在传入 1PageableArgumentResolver] 1 时。 .我认为它应该是 AbstractQueryCreator 上的一个选项(因此, JpaQueryCreator )忽略排序中的错误参数。

应该解决的第二部分可能是 PageableArgumentResolver .如果您传递空字符串或像 %20 这样没有意义的东西,那么它应该忽略该参数并且不会将它发送到 PageRequest

祝你黑客愉快,祝你好运。阅读您的帖子让我意识到我的网站也存在同样的问题,我真的没有好的解决方案。

关于java - Spring Data JPA 无效的 page.sort 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11232056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com