注解作用
将前端传递 字符串参数 转换为指定格式的java.util.Date参数, 并绑定到方法参数上
使用方式
@RestController
@RequestMapping("/aa") //post请求也是ok的
public class TimetableLogController extends BaseApiController {
@GetMapping("/test")
public Object test(@RequestParam(value = "startTime")
@DateTimeFormat(pattern="yyyy-MM-dd") Date startTime) {
System.out.println(startTime);
return null;
}
}
最常用使用方式: get请求, 参数使用@RequestParam注解描述
失效原因(不是转换报错哦)
网上的错误说法
1. 必须是get请求 --> 错, post也是ok的
2. 必须在url上传递参数 --> 错, 表单参数form-data也是可以的
错误原因: 使用@RequestParam注解或省略注解, 默认使用的参数解析器都是RequestParamMethodArgumentResolver, 它解析参数与请求方式无关, 也可解析表单内参数
可能的错误原因(欢迎大家留言补充, 博主会及时更新)
1. 参数写在row-json中
(不生效原因: 参数解析器为RequestResponseBodyMethodProcessor, 只会去处理@RequestBody的参数, 不处理@RequestParam注解或无注解的参数)
2. 使用了@InitBinder配置了个性化参数类型转换器PropertyEditorSupport
(不生效原因: @InitBinder影响了@DateTimeFormat使用. 参数解析时, 个性化参数解析优先级高于@DateTimeFormat的参数转换, 下图为源码举证)
// 代码所在类 org.springframework.beans.TypeConverterDelegate
@Nullable
public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue, @Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// 获取个性化参数转换器
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
ConversionFailedException conversionAttemptEx = null;
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
// 没有个性化参数转换器情况下 才走@DateTimeFormat解析流程
if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
try {
return conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
} catch (ConversionFailedException var14) {
conversionAttemptEx = var14;
}
}
}
Object convertedValue = newValue;
if (editor != null || requiredType != null && !ClassUtils.isAssignableValue(requiredType, newValue)) {
if (typeDescriptor != null && requiredType != null && Collection.class.isAssignableFrom(requiredType) && newValue instanceof String) {
TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
if (elementTypeDesc != null) {
Class<?> elementType = elementTypeDesc.getType();
if (Class.class == elementType || Enum.class.isAssignableFrom(elementType)) {
convertedValue = StringUtils.commaDelimitedListToStringArray((String)newValue);
}
}
}
if (editor == null) {
editor = this.findDefaultEditor(requiredType);
}
// 有个性化参数转换器, 直接转换执行
convertedValue = this.doConvertValue(oldValue, convertedValue, requiredType, editor);
}
boolean standardConversion = false;
.....
}
拓展
使用@JsonFormat注解来解析row-json的参数
示例:
@Data
public class test {
@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
private Date gatherTime;
}
也可使用该注解将数据库date/datetime类型参数转换为指定格式的字符串时间
需要添加的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
废话少说:
@DateTime注解失效原因:
1.参数在json上
2.使用了@InitBinder注解