@DateTimeFormat失效原因

文章讨论了在Spring框架中,@RequestParam注解配合@DateTimeFormat注解进行日期转换时可能出现的问题,包括参数在JSON对象中导致的失效,以及@InitBinder个性化转换器对@DateTimeFormat的影响。解决方案包括使用@JsonFormat注解或者调整转换逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注解作用

        将前端传递 字符串参数 转换为指定格式的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注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值