相信技术的力量

SpringMVC 入参出参数据类型转换

入参Spring类型转换为Date类型

如果前端传递的是日期字符串,比如"2017-10-23 19:46:45",而我们在Controller中直接用Date类型接收,会报出如下异常:

Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'

解决方案:自定义数据类型转换器

1.自定义DateConverter

import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        String pattern = source.length()==10 ? "yyyy-MM-dd" : "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            return format.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

2.在Spring MVC配置文件中配置自定义的Converter

<!-- 注解驱动-->
<mvc:annotation-driven conversion-service="conversionService"/>

<!-- 自定义参数绑定-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!-- 转换器 -->
    <property name="converters">
        <set>
            <!-- 日期类型转换 -->
            <bean class="com.longke.watercleanner.converter.CustomDateConverter"/>
        </set>
    </property>
</bean>

这样前端传递的日期型字符串如"2017-10-23 19:46:45",就可以转换为Date类型,在Controller中接收参数时可以使用Date类型接收,会自动转换.

出参Long类型转换为String类型

由于在项目中使用了SnowFlake生成long类型ID作为表的主键,这样虽然有利于后台数据库的优化,但是在和前端交互时会出现一些问题.

Java中的long类型字段在JavaScript的number类型接收时,会存在四舍五入的失真情况,比如:

  • 后台id为372121275172126720,前端接收到的id为372121275172126700
  • 后台id为372121602671771648,前端接收到的id为372121602671771650

这会导致根据id查询某个表时,id不存在导致的查询失败.

解决方案:@ResponseBody返回json数据时,将long类型的id转换为String类型,供前端使用.

1.自定义LongToStringMapper,继承ObjectMapper

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

/**
 * 自定义Json转换器,把ResponseBody中Long类型的数据转换为String类型
 */
public class LongToStringMapper extends ObjectMapper {

    private static final long serialVersionUID = 3223645203459453114L;

    public LongToStringMapper() {
        super();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        registerModule(simpleModule);
    }
}

2.在Spring MVC配置文件中配置自定义的Mapper

 <mvc:annotation-driven>

        <!--返回JavaBean时解析成Json-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.longke.watercleanner.converter.LongToStringMapper"/>
                </property>
            </bean>

        </mvc:message-converters>

    </mvc:annotation-driven>

出参long类型时间戳转换为格式化日期字符串

正常数据库存储的是时间戳,比如时间为long类型数据1508759205000,如果想返回给前端"2017-10-23 19:46:45"类型的字符串,可以利用Spring框架本身提供给我们的注解工具@DateTimeFormat,在pojo的属性上进行配置

@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
private Date appointmentDate;

不过这个还是得看需求,传递时间戳还是比较方便的,比如前端可能有时候需要的只是"2017-10-23",而不想要后面的时分秒,而有时候又是需要的,所以还是直接传递时间戳,前端按需转换比较好.

以上只是匆匆记录,后期会再完善,优化写法,并尝试了解源码.
(完)

参考链接:

https://xtuer.github.io/spring-mvc-to-date/

⬆️