Spring 控制器:将查询参数绑定到自定义 POJO 字段
Spring Controller: bind query parameters to custom POJO fields
我正在尝试将某些值从请求查询参数映射到 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;
}
这是控制器:
@GetMapping(path = "/persons")
public ResponseEntity<Integer> getPersons(@Valid final Person personRequest) throws Exception {
return ResponseEntity.ok(personService.getPersonsCount(personRequest));
}
我想将请求查询参数映射到这个 pojo 的属性。这是预期的请求:
{application_url}/persons?personId=12&from=2017-03-22T00:00:00&to=2019-03-22T00:00:00&country=UK&company=xyz
我想将 personId, from, to
映射到 POJO 中的相应属性,并将其余查询参数 nationality, company
映射到过滤器映射。换句话说 personId, to, from
在请求中只是静态的,其余参数可能会有所不同,我们可以使用 salary=1000&minAage=31
而不是 country=UK&company=xyz
所以我想将其余参数映射到filters
地图。
有办法实现吗?
实现它的方法是将 @RequestParam Map<String, String> filters
与其他请求参数一起使用,或者只使用 map 作为请求参数。因为所有参数都将包含在地图中。
请求中包含所有参数的示例:
@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;
}
代码完全乱七八糟。由于 Map<String, String> filters
是 @RequestParam
,因此它包括所有请求参数,甚至包括上面定义的参数。因此,如果您不想在 filters
地图中,则需要删除 pesonId
、from
、to
。
仅包含请求映射的示例
@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;
}
但是至少我不知道在调用控制器端点之前将路径参数转换为 POJO 的好的或简单的配置,因此我建议您使用这些示例中的内容。否则使用请求正文或尝试使用此 example
我正在尝试将某些值从请求查询参数映射到 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;
}
这是控制器:
@GetMapping(path = "/persons")
public ResponseEntity<Integer> getPersons(@Valid final Person personRequest) throws Exception {
return ResponseEntity.ok(personService.getPersonsCount(personRequest));
}
我想将请求查询参数映射到这个 pojo 的属性。这是预期的请求:
{application_url}/persons?personId=12&from=2017-03-22T00:00:00&to=2019-03-22T00:00:00&country=UK&company=xyz
我想将 personId, from, to
映射到 POJO 中的相应属性,并将其余查询参数 nationality, company
映射到过滤器映射。换句话说 personId, to, from
在请求中只是静态的,其余参数可能会有所不同,我们可以使用 salary=1000&minAage=31
而不是 country=UK&company=xyz
所以我想将其余参数映射到filters
地图。
有办法实现吗?
实现它的方法是将 @RequestParam Map<String, String> filters
与其他请求参数一起使用,或者只使用 map 作为请求参数。因为所有参数都将包含在地图中。
请求中包含所有参数的示例:
@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;
}
代码完全乱七八糟。由于 Map<String, String> filters
是 @RequestParam
,因此它包括所有请求参数,甚至包括上面定义的参数。因此,如果您不想在 filters
地图中,则需要删除 pesonId
、from
、to
。
仅包含请求映射的示例
@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;
}
但是至少我不知道在调用控制器端点之前将路径参数转换为 POJO 的好的或简单的配置,因此我建议您使用这些示例中的内容。否则使用请求正文或尝试使用此 example