SpringBoot3.x,基于SpringMVC注解@initbinder解决类型转换问题,主要为时间转换。
场景
前端form表单发送大量yyyy-MM-dd HH:mm:ss
的时间参数,而数据库中需要存储对应的秒时间戳。
希望,在封装接收参数的XxxParam对象时,就自动转换为Long类型的属性。
原理
@InitBinder表示的方法,可以对WebDataBinder对象进行初始化。
WebDataBinder是DataBinder的子类,用于完成由表单到JavaBean属性的绑定。
实现方案
Controller层
@Controller
@RequestMapping("/xxx")
public class XxxController {
private static final Logger logger = LoggerFactory.getLogger(XxxController.class);
@Autowired
private XxxService xxxService;
public static class DateString2LongEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.isBlank(text)) {
setValue(null);
return;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = simpleDateFormat.parse(text);
setValue(DateUtil.toSecond(date));
} catch (ParseException e) {
logger.warn("data string is not format 'yyyy-MM-dd HH:mm:ss'", e);
throw new ServiceException("data string is not format 'yyyy-MM-dd HH:mm:ss'", e);
}
}
}
@InitBinder
public void initBinder(WebDataBinder wbd) {
wbd.registerCustomEditor(Long.class, new DateString2LongEditor());
}
@RequestMapping(value = "/dataGrid", method = RequestMethod.POST)
@ResponseBody
public PageVo<BanLinkageLogVo> findPage(XxxParam search) {
return xxxService.findPage(search);
}
@RequestMapping(value = "/manager", method = RequestMethod.GET)
public String manager() {
return "/xxx/list";
}
}
Vo层
@Data
public class XxxParam extends BaseSearchParam{
...
private Long createTimeBegin;
private Long createTimeEnd;
}
XxxParam中对应的属性类型应为转换后的属性类型。
在return xxxService.findPage(search);
打断点,可以发现search中原先传进来的Data被转成了Long类型的时间戳。
扩展
上面的方法可以简写为以下这种形式,但没有处理异常,不推荐。
@InitBinder
public void initBinder(WebDataBinder wbd) {
wbd.registerCustomEditor(Long.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
}