【问题标题】:@RequestParam is still giving null even when is not required@RequestParam 即使不需要也仍然给出 null
【发布时间】:2018-07-05 10:13:20
【问题描述】:

我有一个带有一个参数的控制器:

@GetMapping("/people")
    public Page<People> list(
            @RequestParam(name="name", required = false) String name
            Pageable pageable
            ){

        Page<People> peoples=PeopleService.findByName(pageable,name);
        return peoples;

    }

当我转到localhost:8080/people?name=John 时,它给了我正确的数据,但是当我转到localhost:8080/people 时,它没有给我任何数据,但我希望它给我所有人。

发现是Spring引起的,还在搜索where name=null

如何解决这个问题,因为我有更多的参数,比如年龄、日期等?

【问题讨论】:

  • 为什么不使用不同的 URL 呢?例如/people/all 所有人
  • 因为你还在调用findByName方法。如果参数是null,并且您想返回所有内容,请使用findAll。为此,您将需要控制器中的一些逻辑。
  • 是JPA服务吗?
  • 您可能还想在“name”参数后添加一个逗号,并将“peoples”变量重命名为“people”。

标签: spring spring-data spring-rest


【解决方案1】:

您正在使用不需要的 name 参数调用方法 findByName。检查名称变量是否为空,具体取决于调用findByNamefindAll 方法。

@GetMapping("/people")
    public Page<People> list(
            @RequestParam(name="name", required = false) String name
            Pageable pageable
            ){
        if(name != null){

        Page<People> peoples=PeopleService.findByName(pageable,name);
        return peoples;

        }else{

        Page<People> peoples=PeopleService.findAll(pageable);
        return peoples;

        }

    }

【讨论】:

  • name 为空时,此代码将以NullPointerException 中断。
  • @M.Deinum 然后检查 null 而不是比较空字符串应该可以吗?
  • 您可以利用 Apache Commons StringUtils.isEmpty(str) 来检查空字符串并优雅地处理 null
【解决方案2】:

您可以在Spring Data 中使用Specifications

只需让您的 PeopleService 接口(如果它是您的 Spring 数据存储库接口)扩展 JpaSpecificationExecutor&lt; People &gt; 并创建一个像 PeopleSpecification 这样实现 Specification&lt; People &gt; 的类,如下所示:

public class PeopleSpecification implements Specification<People> {

    private String firstName;

    //getters and setters

    public Predicate toPredicate(Root<People> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        if (firstName != null)
            return cb.equal(root.get("firstName"), firstName);
        return cb.and();
    }
}

然后更改您的控制器方法以获取PeopleSpecification 的实例作为参数:

public Page<People> list(@ModelAttribute PeopleSpecification specification, Pagable pageable)

最后在控制器的PeopleService 中使用从JpaSpecificationExecutor 继承的新方法:

Page<People> findAll(Specification<People> specification, Pageable pageable);

很明显,您可以更改 PeopleSpefication 类的实现,使其具有任意数量的属性,并更改 toPredicate 方法逻辑以返回正确的 Predicate 对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-02
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多