框架相关 - Bug
SpringMVC日期参数绑定
- 我们再项目中多多少少都使用过SprigMVC的参数绑定,只要参数名一致就可以避免从request中获取数据。
- 项目中,我们更习惯使用DTO来接收数据,当对象中存在如
java.util.Date
类型的时候。SpringMvc 的请求中的参数(字符串)默认是不能自动地转换为日期的。 - 需要使用 Converter, InitBinder 或者 Formatter 来把请求中的参数转换为日期。
使用 Converter
Converter 是全局的,可以在所有 Controller 中使用。
定义字符串转换为日期的类 DateConverter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package top.fulsun.converter;
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> {
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;
}
}SpringMvc 的配置文件中注册 Converter
1
2
3
4
5
6
7
8
9
10<mvc:annotation-driven conversion-service="customConversionService">
</mvc:annotation-driven>
<bean id="customConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="top.fulsun.converter.DateConverter"/>
</set>
</property>
</bean>处理请求
1
2
3
4
5
6
public Date toDate(Date date) {
System.out.println("=========>" + date);
return date;
}
使用 InitBinder
注意:
@InitBinder(“date”) 中 date 必须和 请求方法toDate(Date date) 中的 date 名字一样,当然,请求的参数中也必须有名为 date 的参数。
@InitBinder 只能在当前 Controller 中使用,当有多个地方都需要把参数转换为日期对象,则使用 Converter 更适合。
Controller 中定义 InitBinder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @InitBinder用于在控制器(Controller)中标注于方法上,表示为当前控制器注册一个属性编辑器,只对当前的Controller有效。
* 第二个参数true表示允许传入的时间为空 如: url?startTime=&name=张
*/
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
// 不适用严格解析模式,数据类型不对抛出异常
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}catch (Exception e){
throw new ApplicationException("时间格式错误", e);
}
}处理请求
1
2
3
4
5
6
public Date toDate(Date date) {
System.out.println("=========>" + date);
return date;
}
入/出参格式化
- @DateTimeFormat转换前端string类型到后端date类型,此字段一般加到属性上面, 前台给后台传值时用
- @JsonFormat转换后端date类型到前端string类型,如果只用到此注解,加到属性上或者方法上都可以;后台传值给前台时
- @JsonFormat不仅可以完成后台到前台参数传递的类型转换,还可以实现前台到后台类型转换。
- 当content-type为application/json时,优先使用@JsonFormat的pattern进行类型转换。而不会使用@DateTimeFormat进行类型转换。
- @JsonFormat注解的作用就是完成json字符串到java对象的转换工作,与参数传递的方向无关。
使用 Spring 的 @DateTimeFormat 注解格式化参数,pattern 属性值指定的日期时间格式
1
2
private Date date;如果放回的参数的结果中包含时间,如
"date": "2018-08-01T14:25:31.296+0000"
。这个格式并不是我们想要的,我们可以将其进行格式化,就需要用到 jackson 的 @JsonFormat 注解。在 spring-boot-start-web 下已经包含了 jackson 相关依赖。1
2
3
4
5
6
7注解所依赖的jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.7</version>
</dependency>
- jackson在序列化时间时是按照国际标准时间GMT进行格式化的。
- 而在国内默认时区使用的是CST时区,两者相差8小时。可以指定timezone属性解决
属性值上配置
1
2
private Date date;配置文件中配置
1
2
3# 时间戳统一转换
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
使用String处理
接收的时候使用String ,返回的使用Date对象,可以避免上述方法传参为空报错的问题。
字段描述
1
2
3
4
5
6// top.fulsun.app.dto.AppUserQuery
private String startTime;
private String endTime;
// top.fulsun.app.dto.AppUserDto
private Date createTime = null;sql处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<select id="find" resultType="AppUserDto" parameterType="com.philips.education.app.dto.AppUserQuery" >
select * from user
<trim prefix="WHERE" prefixOverrides="AND|OR" >
<if test="startTime != null and startTime != ''" >
<![CDATA[
AND DATE_FORMAT(t_app_user.create_time, '%Y-%m-%d') >= #{startTime, jdbcType=VARCHAR}
]]>
</if>
<if test="endTime != null and endTime != ''" >
<![CDATA[
AND DATE_FORMAT(t_app_user.create_time, '%Y-%m-%d') <= #{endTime, jdbcType=VARCHAR}
]]>
</if>
</trim>
</select>
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 凉月の博客!
评论