SpringMVC在controller里如何接收字符串类型的日期

谁践踏了优雅 2022-01-13 12:39 250阅读 0赞

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

先说一下对象

  1. public class Book {
  2. private int id;
  3. private String bookname;
  4. private Date birthday;
  5. private BigDecimal money;
  6. .....get set....
  7. }

前端提交过来的日期格式是:2018-09-03 15:23:55,后边在controller如何用Date直接接收这个日期数据

  1. 以form-data的格式提交
    也就是在controller里是直接接收对象。像这样

    @PostMapping(“/books”)
    public int addBook(Book book) {

    1. return feign.addBook(book);

    }

处理方法:
方法一:
在controller里添加@InitBinder, 然后添加日期格式化方式。亲测,这种可以。
这种方式只对这个controller有效

  1. @InitBinder
  2. public void initDateFormate(WebDataBinder dataBinder) {
  3. dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
  4. }

还可以指定要格式化的具体字段。这样如果这个controller接收好几个date类型,其中有的是yyyy-MM-dd HH:mm:ss,有的是yyyy-MM-dd,就可以分别设置
可以看下WebDataBinder这个类,功能还是很强大

  1. @InitBinder
  2. public void initDateFormate(WebDataBinder dataBinder) {
  3. dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"), "birthday");
  4. }

方法二:
给字段添加注解@DateTimeFormat

  1. public class Book {
  2. private int id;
  3. private String bookname;
  4. @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  5. private Date birthday;
  6. private BigDecimal money;
  7. ......
  8. }

方法三:
使用Spring MVC的扩展接口HandlerMethodArgumentResolver。它的使用是把HttpRequest里面的参数解析成Controller里面标注了@RequestMapping方法的方法参数。

这种等于是自己定义了一个注解处理日期格式转换,然后把这个注解加入到springMVC的HandlerMethodArgumentResolver里边

1) Date.java – 指定该方法参数需要特殊处理

  1. @Target(ElementType.PARAMETER)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Date {
  5. String[] params () default "";
  6. String pattern() default "yyyy-MM-dd HH:mm:ss";
  7. }
  8. 2) DateHandlerMethodArgumentResolver 处理标注了@Date注解的方法参数
  9. public class DateHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
  10. private String[] params;
  11. private String pattern;
  12. @Override
  13. public boolean supportsParameter(MethodParameter parameter) {
  14. boolean hasParameterAnnotation = parameter.hasParameterAnnotation(Date.class);
  15. if(!hasParameterAnnotation){
  16. return false;
  17. }
  18. Date parameterAnnotations = parameter.getParameterAnnotation(Date.class);
  19. String[] parameters = parameterAnnotations.params();
  20. if(StringUtils.isNoneBlank(parameters)){
  21. params = parameters;
  22. pattern = parameterAnnotations.pattern();
  23. return true;
  24. }
  25. return false;
  26. }
  27. @Override
  28. public Object resolveArgument(MethodParameter methodParam, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
  29. Object object = BeanUtils.instantiateClass(methodParam.getParameterType());
  30. BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
  31. HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
  32. for (String param : params) {
  33. String value = request.getParameter(param);
  34. if(StringUtils.isNoneBlank(value)){
  35. SimpleDateFormat sdf = new SimpleDateFormat(this.pattern);
  36. java.util.Date date = sdf.parse(value);
  37. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
  38. for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
  39. if(propertyDescriptor.getName().equals(param)){
  40. Method writeMethod = propertyDescriptor.getWriteMethod();
  41. if(!Modifier.isPublic(writeMethod.getModifiers())){
  42. writeMethod.setAccessible(true);
  43. }
  44. writeMethod.invoke(object, date);
  45. }
  46. }
  47. }
  48. }
  49. return object;
  50. }
  51. }

3) MyMVCConfig – 配置Spring MVC扩展

  1. @Configuration
  2. @EnableWebMvc
  3. public class MyMVCConfig extends WebMvcConfigurerAdapter{
  4. ......
  5. @Override
  6. public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
  7. argumentResolvers.add(new DateHandlerMethodArgumentResolver());
  8. }
  9. }

4) 测试

  1. @PostMapping("/books")
  2. public int addBook(@Date(params = "birthday") Book book) {
  3. return feign.addBook(book);
  4. }
  1. json格式的日期
    也就是在controller里以下边这种方式接收对象,加上@RequestBody

    @PostMapping(“/books”)
    public int addBook(@RequestBody Book book) {

    1. return feign.addBook(book);

    }

第一种方法:
使用jackson提供的注解@JsonFormat

  1. public class Book {
  2. private int id;
  3. private String bookname;
  4. @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
  5. private Date birthday;
  6. private BigDecimal money;
  7. }

第二种方法:
自定义序列化和反序列工具。这里以反序列化工具为例
先定义一个反序列化工具类

  1. public class DateSerialzer extends JsonDeserializer<Date> {
  2. @Override
  3. public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
  4. JsonNode node = jsonParser.getCodec().readTree(jsonParser);
  5. String now = node.asText();
  6. Date date = null;
  7. SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  8. try {
  9. date = format.parse(now);
  10. System.out.println(date);
  11. } catch (ParseException e) {
  12. e.printStackTrace();
  13. }
  14. return date;
  15. }
  16. }

然后在从属性上注明使用哪个反序列化工具@JsonDeserialize(using = DateSerialzer.class),如下:

  1. public class Book {
  2. private int id;
  3. private String bookname;
  4. @JsonDeserialize(using = DateSerialzer.class)
  5. private Date birthday;
  6. private BigDecimal money;
  7. }

转载于:https://my.oschina.net/u/3734228/blog/3029698

发表评论

表情:
评论列表 (有 0 条评论,250人围观)

还没有评论,来说两句吧...

相关阅读