前后台传参类型、格式不同,解决思路
思路:
找类型转换类工具、格式转换类工具。
(1)可能需要写在控制层,那就需要使用@InitBinder注解,优先加载其中内容;(更好,更完善的方法:将这些方法写在BaseController类中(可以自己建个工具类),需要进行这类转换的控制器只需继承BaseController即可)
(2)可能需要用在get方法上面,需要使用相应注解,使参数进get之前,先进工具类进行处理。再进入get。
例子:
(1)从前台表单所获取的数据的时间格式与后台所能处理的时间格式不同,而springMVC不能自动转换,需要手动定义转换。
具体问题:在swagger页面中修改、添加数据后,若时间填写2118-8-8这种格式,则报400状态码(无法理解请求的参数)。若改成2018/8/8这种形式,则可以成功写库。
解决方法:
//将后台所能处理的日期格式从2018/8/8变成了2018-8-8 @InitBinder protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); simpleDateFormat.setLenient(false); CustomDateEditor dateEditor = new CustomDateEditor(simpleDateFormat, true); binder.registerCustomEditor(Date.class,dateEditor); } @ApiOperation(value = "更新人员") @ApiResponses(value = { @ApiResponse(code = 200, message = "updated") }) @ApiImplicitParam(name="ryid",paramType="path",dataType="string",value="人员ID",required = true) @RequestMapping(value="update/{ryid}",method=RequestMethod.PUT) public void update( @PathVariable("ryid") String ryid, @ModelAttribute Ryb ryb ){ ryb.setRyid(ryid); rybService.update(ryid,HtglRybFactory.create(ryb)); } @ApiOperation( "创建人员") @ApiResponses(value = { @ApiResponse(code = 201, message = "Created") }) @RequestMapping(value="add",method=RequestMethod.POST) public void add( @ModelAttribute Ryb ryb ){ if( rybService.add(HtglRybFactory.create(ryb)) != null ) { response.setStatus(HttpStatus.CREATED.value()); } }
说明:
1)在控制层中方法之前添加粉色处代码。即可。(会优先注册这个编辑器)
2)效果:后台能处理2118-8-8这种格式。但不能处理2018/8/8这种形式。
3)处理问题的思维历程:通过debug找到问题的具体位置,锁定具体原因。
如本例,在黄色荧光处打了断点,发现在swagger添加、修改操作时,没被断点拦截就已经报错。锁定了数据没传过来的问题。同时,若不填写时间数据,则添加、修改可以成功。锁定问题是时间格式问题。
*优化:(目标:无论输入2118-8-8这种格式,还是2018/8/8这种形式,均能成功写库)
创建工具类,如下
public class BaseController { @InitBinder protected void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Date.class, new MyDateEditor()); } private class MyDateEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); Date date = null; try { date = format.parse(text); } catch (ParseException e) { format = new SimpleDateFormat("yyyy-MM-dd"); try { date = format.parse(text); } catch (ParseException e1) { } } setValue(date); } } }
然后,让需要进行格式转换的类继承这个工具类(如下图)。即可。
public class RybRest extends BaseController{...}
(2)获取数据库数据,自定义其中的时间的格式。(使页面显示这个格式)
解决方法:
定义时间格式转换工具类,
public class DateConvertUtil extends JsonSerializer<Date>{/** * @param value 表示要转换的对象 * @param gen 表示json串生成器 * @param serializers json 串序列化提供者 (暂且不用关系) */ @Override public void serialize(Date value,JsonGenerator gen,SerializerProvider serializers) throws IOException,JsonProcessingException { //1.创建日期转换对象(如何保障如下对象每个线程有一份:了解ThreadLocal) SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd"); //2.将日期对象转换为指定格式的字符串 String dateStr=sdf.format(value); //3.将此字符串写入到json串中 gen.writeString(dateStr); } }
在实体的get方法上面通过注解调用所定义的工具类。即可。
@JsonSerialize(using=DateConvertUtil.class) public Date getWrite_time() { return write_time; }
重点:
1)遇到bug的处理思想;
2)@InitBinder注解的使用;
附:(参考)
https://www.cnblogs.com/feng9exe/p/8036657.html
状态码
https://www.cnblogs.com/huhuixin/p/6823789.html
idea Debug快捷键
https://blog.csdn.net/zhangxiaoyang0/article/details/77896171
springMVC前台传递日期类型到后台
https://www.cnblogs.com/heyonggang/p/6186633.html
SpringMVC中利用@InitBinder来对页面数据进行解析绑定