在 Spring 个 RestController 中使用 Field Formatter
Use Field Formatter in Spring RestControllers
我尝试让 RestController 使用我的自定义格式化程序 java.time.Duration,但我不知道为什么没有成功。我有一个简单的 Order 实体、一个 OrderController 和一个 DurationFormatter,它们应该应用于 Order 的 Duration 类型字段与字符串的转换。 Formatter 在 Configuration class 中注册到 FormattingConversionServiceFactoryBean。这是代码:
public class Order {
@Getter
@Setter
private String id;
@Getter
@Setter
@NotNull
private String customerId;
@Getter
@Setter
private ZonedDateTime validFrom;
@Getter
@Setter
private ZonedDateTime validTo;
@Getter
@Setter
private Duration maxDuration;
@Getter
@Setter
private Duration actDuration;
}
@RestController
@RequestMapping("order")
public class OrderController {
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createOrder(@RequestBody @Valid Order order) {
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest().path("/" + order.getId()).build().toUri());
return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.GET)
public Order getExample() {
Order order = new Order();
order.setMaxDuration(Duration.ofHours(10));
return order;
}
}
public class DurationFormatter implements Formatter<Duration>{
@Override
public String print(Duration duration, Locale locale) {
return new Long(duration.toHours()).toString();
}
@Override
public Duration parse(String text, Locale locale) throws ParseException {
return Duration.ofHours(Long.parseLong(text));
}
}
@Configuration
public class AppConfig {
@Bean
public FormattingConversionServiceFactoryBean getFormattingConversionServiceFactory() {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set<Formatter<?>> formatters = new HashSet<>();
formatters.add(new DurationFormatter());
factory.setFormatters(formatters);
return factory;
}
}
当我尝试 post 一个订单时,这是我得到的错误:
at [Source: java.io.PushbackInputStream@595e3818; line: 4, column:
30] (through reference chain:
com.sap.sptutorial.rest.Order["maxDuration"]); nested exception is
com.fasterxml.jackson.databind.JsonMappingException: Can not
instantiate value of type [simple type, class java.time.Duration] from
String value ('67'); no single-String constructor/factory method
任何人都可以建议我应用格式化程序的正确方法吗?
格式化程序与 JSON 反序列化无关。在您的案例中,这就是 Jackson
的任务。将以下依赖项添加到您的 pom.xml
以获得对新的 Java 8 种类型的支持就足够了。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.1</version>
</dependency>
我尝试让 RestController 使用我的自定义格式化程序 java.time.Duration,但我不知道为什么没有成功。我有一个简单的 Order 实体、一个 OrderController 和一个 DurationFormatter,它们应该应用于 Order 的 Duration 类型字段与字符串的转换。 Formatter 在 Configuration class 中注册到 FormattingConversionServiceFactoryBean。这是代码:
public class Order {
@Getter
@Setter
private String id;
@Getter
@Setter
@NotNull
private String customerId;
@Getter
@Setter
private ZonedDateTime validFrom;
@Getter
@Setter
private ZonedDateTime validTo;
@Getter
@Setter
private Duration maxDuration;
@Getter
@Setter
private Duration actDuration;
}
@RestController
@RequestMapping("order")
public class OrderController {
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createOrder(@RequestBody @Valid Order order) {
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest().path("/" + order.getId()).build().toUri());
return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.GET)
public Order getExample() {
Order order = new Order();
order.setMaxDuration(Duration.ofHours(10));
return order;
}
}
public class DurationFormatter implements Formatter<Duration>{
@Override
public String print(Duration duration, Locale locale) {
return new Long(duration.toHours()).toString();
}
@Override
public Duration parse(String text, Locale locale) throws ParseException {
return Duration.ofHours(Long.parseLong(text));
}
}
@Configuration
public class AppConfig {
@Bean
public FormattingConversionServiceFactoryBean getFormattingConversionServiceFactory() {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set<Formatter<?>> formatters = new HashSet<>();
formatters.add(new DurationFormatter());
factory.setFormatters(formatters);
return factory;
}
}
当我尝试 post 一个订单时,这是我得到的错误:
at [Source: java.io.PushbackInputStream@595e3818; line: 4, column: 30] (through reference chain: com.sap.sptutorial.rest.Order["maxDuration"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.Duration] from String value ('67'); no single-String constructor/factory method
任何人都可以建议我应用格式化程序的正确方法吗?
格式化程序与 JSON 反序列化无关。在您的案例中,这就是 Jackson
的任务。将以下依赖项添加到您的 pom.xml
以获得对新的 Java 8 种类型的支持就足够了。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.1</version>
</dependency>