简体   繁体   English

Spring Controller:将查询参数绑定到自定义 POJO 字段

[英]Spring Controller: bind query parameters to custom POJO fields

I'm trying to map certain values from request query parameters to POJO parameters as the following.我正在尝试从请求查询参数到 POJO 参数的某些值 map,如下所示。 This is the POJO:这是 POJO:

import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Map;

@Data
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    @NotNull(message = "personId cannot be null")
    @Min(value = 0)
    private Long personId;

    @NotNull(message = "from date cannot be null")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime from;

    @NotNull(message = "to date cannot be null")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime to;

    private Map<String, String> filters;
}

And this is the controller:这是 controller:

    @GetMapping(path = "/persons")
    public ResponseEntity<Integer> getPersons(@Valid final Person personRequest) throws Exception {
        return ResponseEntity.ok(personService.getPersonsCount(personRequest));
    }

I want to map request query parameters to the attributes of this pojo.我想map请求查询参数到这个pojo的属性。 This is the expected request:这是预期的请求:

{application_url}/persons?personId=12&from=2017-03-22T00:00:00&to=2019-03-22T00:00:00&country=UK&company=xyz

I want to map personId, from, to to corresponding attributes in POJO and map the rest of query parameters nationality, company to the filters map. I want to map personId, from, to to corresponding attributes in POJO and map the rest of query parameters nationality, company to the filters map. In other words personId, to, from are only static in the request and the rest of the parameters may vary, we can have salary=1000&minAage=31 instead of country=UK&company=xyz so I want to map the rest of the parameters to the filters map. In other words personId, to, from are only static in the request and the rest of the parameters may vary, we can have salary=1000&minAage=31 instead of country=UK&company=xyz so I want to map the rest of the parameters to the filters map。

Is there a way to achieve so?有没有办法做到这一点?

The way you can achieve it is to use @RequestParam Map<String, String> filters with other request parameters or just to use map for request parameters.实现它的方法是将@RequestParam Map<String, String> filters与其他请求参数一起使用,或者仅将 map 用于请求参数。 Because all parameters would be included in map.因为所有参数都将包含在 map 中。


Example with all parameters in request:请求中所有参数的示例:

@GetMapping(path = "persons")
public ResponseEntity<Integer> getPersons(@RequestParam Long personId,
                                          @RequestParam String from,
                                          @RequestParam String to,
                                          @RequestParam Map<String, String> filters) {
    Person person = Person.builder()
            .personId(personId)
            .from(getDate(from))
            .to(getDate(to))
            .filters(filterMap(filters))
            .build();
    return ResponseEntity.ok(personService.getPersonsCount(person));
}

private LocalDateTime getDate(String date) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    return LocalDateTime.parse(date, formatter);
}

private Map<String, String> filterMap(Map<String, String> request) {
    request.remove("personId");
    request.remove("from");
    request.remove("to");
    return request;
}

The code is totally messed up.代码完全搞砸了。 And since Map<String, String> filters is @RequestParam , so it includes all request parameters even what's defined above.而且由于Map<String, String> filters@RequestParam ,所以它包括所有请求参数,即使是上面定义的。 So you need to remove pesonId , from , to if you don't want to be in filters map.因此to如果您不想进入filters map,则需要from中删除pesonId

Example with request map only仅限请求 map 的示例

@GetMapping(path = "persons")
public ResponseEntity<Integer> getPerson(@RequestParam Map<String, String> requestParams) {
    Person person = Person.builder()
             .personId(Long.valueOf(requestParams.get("personId")))
             .from(getDate(requestParams.get("from")))
             .to(getDate(requestParams.get("to")))
             .filters(filterRequest(requestParams))
             .build();
    return ResponseEntity.ok(personService.getPersonsCount(person));
}

private LocalDateTime getDate(String date) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    return LocalDateTime.parse(date, formatter);
}

private Map<String, String> filterRequest(Map<String, String> request) {
    request.remove("personId");
    request.remove("from");
    request.remove("to");
    return request;
}  

However at least I don't know nice or simple configuration to convert path parameters to POJO before calling controller endpoint, so I suggest you to use something from these examples.但是,至少我不知道在调用 controller 端点之前将路径参数转换为 POJO 的良好或简单配置,所以我建议您使用这些示例中的一些内容。 Otherwise use request body or try to use this example否则使用请求正文或尝试使用此示例

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

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