简体   繁体   English

如何操作可选 Spring @RequestParam

[英]How to manipulate Optional Spring @RequestParam

I'm new to JPA.我是 JPA 的新手。 I have a class like this我有一个像这样的 class

@Table(name="student")
@Entity
public class Student{
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int studentId;
    
    @Column
    @Size(max = 20)
    private String name;
    
    @Column
    @Min(value = 2014)
    @Max(value = 2020)
    private int yearOfBirth;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "classroomId")
    Classroom classroom;

    //Getters and setters
    }

My repository:我的存储库:

        @Repository
        public interface HocSinhRepository extends JpaRepository<Student, Integer> {}

My controller:我的 controller:

public class StudentController {
        @Autowired
        StudentRepository studentRepository;
        
        @GetMapping(value = "/get")
        public Page<Student> get(@RequestParam Optional<Integer> page, @RequestParam Optional<String> sortBy) {
            return studentRepository.findAll(
                    PageRequest.of(page.orElse(0), 3, Sort.Direction.ASC, sortBy.orElse("name"))
                    );
        }
    }

By using Optional.orElse, I can assign a default value to the sortBy parameter if it's null.通过使用 Optional.orElse,如果它是 null,我可以为 sortBy 参数分配一个默认值。 How can I do the same thing if the parameter is not null, but just a non-sensible string (like "asdasd")?如果参数不是 null,而只是一个不合理的字符串(如“asdasd”),我该如何做同样的事情?

You can use the map operator of optionals.您可以使用选项的map运算符。

So it would be所以它会是

sortBy.map(o -> {
           if (o.equalsIgnoreCase("asdasd")){
               return "name";
           } else {
               return o;
           }
       }).orElse("name"));

This will make the optional return the value "name" when it is empty or when the containing value exists and is with ignore case "asdasd" .当它为空或包含值存在并且忽略大小写"asdasd"时,这将使可选返回值"name" ”。 In every other case it will return the original value it contained.在所有其他情况下,它将返回它包含的原始值。

So your code will be adapted to be所以你的代码将被改编为

return studentRepository.findAll(
                    PageRequest.of(page.orElse(0), 3, Sort.Direction.ASC, 
                                   sortBy.map(o -> {
                                              if (o.equalsIgnoreCase("asdasd")){
                                                   return "name";
                                              } else {
                                                   return o;
                                              }}).orElse("name"));
                   ));

another variation:另一种变化:

    @GetMapping(value = "/get")
    public Page<Student> get(
            @RequestParam(required = false, defaultValue = "0") Integer page,
            @RequestParam(required = false, defaultValue = "name") String sortBy) {

        String sortByOrDefault = SortConfig.STUDENTS.getSortableFields().contains(sortBy) 
                ? sortBy
                : SortConfig.STUDENTS.getDefaultSortField();
        return studentRepository.findAll(PageRequest.of(page, 3, Sort.Direction.ASC, sortByOrDefault));

    }

    public enum SortConfig {
        STUDENTS(List.of("name", "studentId")), 
        ANOTHER_ENTITY(List.of("field1", "field2"));

        private String defaultSortField;
        private List<String> sortableFields;

        private SortConfig(List<String> sortableFields) {
            this.sortableFields = sortableFields;
        }

        public String getDefaultSortField() {
            return defaultSortField;
        }

        public List<String> getSortableFields() {
            return sortableFields;
        }

    }

A common scenario would be:一个常见的情况是:

To have the "valid field names" stored in a "data structure", eg, like:将“有效字段名称”存储在“数据结构”中,例如:

public static final Set<String> VALID_SORT_FIELDS = Set.of("name", "studentId"/*, all we "consider valid"...*/);

Then we can use it in our controller like:然后我们可以在我们的 controller 中使用它,例如:

@GetMapping(value = "/get")
public Page<Student> get(@RequestParam Optional<Integer> page, @RequestParam Optional<String> sortBy) {
  final String sort = sortBy
  .map( s -> 
      s != null && VALID_SORT_FIELDS.contains(s)?
          s : "name" // or a consatant com.domain.my...DEFAULT_SORT
  )
  .get();
  return studentRepository.findAll(
     PageRequest.of(page.orElse(0), 3, Sort.Direction.ASC, sort)
  );
}

When we want to ignore the case, we would adjust to:当我们想忽略这种情况时,我们会调整为:

...&&  VALID_SORT_FIELDS.contains(s.toLowerCase(/*some (default) Locale*/))

Another/additional possible approach: validaion-api... but the wrapping Optional is a "challange"(??)...另一种/其他可能的方法:validaion-api...但包装 Optional 是“挑战”(??)...

variation on @xerx593's VALID_SORT_FIELDS and making spring's @RequestParam optional @xerx593 的VALID_SORT_FIELDS的变化并使 spring 的 @RequestParam 可选

    public static final Set<String> VALID_SORT_FIELDS = Set.of("name", "studentId");
    
    @GetMapping(value = "/get")
    public Page<Student> get(
            @RequestParam(required = false, defaultValue = "0") Integer page,
            @RequestParam(required = false, defaultValue = "name") String sortBy) {
        
        String sortByOrDefault = VALID_SORT_FIELDS.contains(sortBy) ? sortBy : "name";
        return studentRepository.findAll(PageRequest.of(page, 3, Sort.Direction.ASC, sortByOrDefault));
    
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM