这里给出详细讲解“Springcloud feign传日期类型参数报错的解决方案”的完整攻略。
问题描述
在使用SpringCloud Feign进行服务调用时,当接口中含有日期类型参数时,调用服务时会报错,如下:
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.time.LocalDate: parameterless constructor not available.
at [Source: (PushbackInputStream); line: 1, column: 380] (through reference chain: com.xxx.XXXVO["date"])
原因分析
出现这个问题的原因是因为Feign默认使用的是Spring MVC的HttpMessageConverters进行数据转换,Spring MVC的默认数据转换器无法对日期类型参数进行正确的反序列化。
解决方案
第一种解决方案
在Feign的配置文件中配置使用Jackson序列化和反序列化器,如下:
feign:
client:
config:
default:
encoder: feign.jackson.JacksonEncoder
decoder: feign.jackson.JacksonDecoder
将Feign默认的httpMessageConverters替换成Jackson序列化和反序列化器,这样就能够对日期类型的参数进行正确的序列化和反序列化了。通过此方式解决后接口调用的参数可以使用LocalDateTime、LocalDate或者ZonedDateTime。
第二种解决方案
在DTO类上使用@JsonFormat注解指定日期格式,如下:
public class XXXDTO {
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
// ...
}
在我们定义接口DTO的日期类型参数时,使用@JsonFormat注解来指定日期格式,这样就可以完成对日期类型的参数的序列化和反序列化了。通过此方式解决后接口调用的参数只能使用字符串类型。
示例说明
接下来通过两个示例来展示如何使用上述方法解决问题:
第一个示例:
我们定义一个接口,其中包含一个日期类型的参数,如下:
public interface XxxxService {
@GetMapping("/test")
public String test(@RequestParam LocalDate date);
}
使用Feign进行服务调用,测试接口是否可用:
@RestController
public class TestController {
@Autowired
private XxxxService xxxxService;
@GetMapping("/test")
public String test() {
String res = xxxxService.test(LocalDate.now());
return "res: " + res;
}
}
此时调用接口会抛出异常:com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.time.LocalDate
。
采用第一种解决方案,增加配置文件:
feign:
client:
config:
default:
encoder: feign.jackson.JacksonEncoder
decoder: feign.jackson.JacksonDecoder
重新启动服务,再次调用接口,可以正常返回。
第二个示例:
我们定义一个DTO,其中包含一个日期类型的参数,如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class XxxxDTO {
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
}
我们使用DTO来作为接口的参数,如下:
public interface XxxxService {
@PostMapping("/test")
public String test(@RequestBody XxxxDTO dto);
}
使用Feign进行服务调用,测试接口是否可用:
@RestController
public class TestController {
@Autowired
private XxxxService xxxxService;
@GetMapping("/test")
public String test() {
XxxxDTO dto = new XxxxDTO(LocalDate.now());
String res = xxxxService.test(dto);
return "res: " + res;
}
}
此时调用接口仍然会抛出异常:com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.time.LocalDate
。
采用第二种解决方案,为DTO类中的date属性添加@JsonFormat注解:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class XxxxDTO {
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
}
重新启动服务,再次调用接口,可以正常返回。
以上就是Springcloud feign传日期类型参数报错的解决方案的完整攻略,包含了两个示例说明。