基于springboot处理date参数过程解析

这篇文章主要介绍了基于springboot处理date参数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

最近在后台开发中遇到了时间参数的坑,就单独把这个问题提出来找时间整理了一下;

正文

测试方法

bean代码:

public class DateModelNoAnnotation {
  private Integer id;
  private Date receiveDate;
}

controller代码:

@RestController
@RequestMapping("/date")
public class DateVerifyController {
  //  方式一
  @PostMapping("/no")
  public String dateUnNoAnnotation(DateModelNoAnnotation dateModelNoAnnotation){
    System.out.println(dateModelNoAnnotation.toString());
    return "SUCCESS";
  }

//  方式二
  @PostMapping("/has")
  public String dateHasAnnotation(@RequestBody DateModelNoAnnotation dateModelNoAnnotation){
    System.out.println(dateModelNoAnnotation.toString());
    return "SUCCESS";
  }
//  方式三
  @GetMapping("/param")
  public String dateParams(@RequestParam("id")Integer id, @RequestParam("receiveDate")Date receiveDate){
    System.out.println("id====="+id);
    System.out.println("receiveDate====="+receiveDate);
    System.out.println("receiveDate====="+receiveDate.getTime());
    return "SUCCESS";
  }
//  方式四
  @GetMapping("/no/param")
  public String dateNoParams(Integer id,Date receiveDate){
    System.out.println("id====="+id);
    System.out.println("receiveDate====="+receiveDate);
    System.out.println("receiveDate====="+receiveDate.getTime());
    return "SUCCESS";
  }
}

接收参数的几种方式(实验)

  • 通过bean来接收数据(表单方式)

    • 这种方式只支持"yyyy/MM/dd HH:mm:ss"这种格式的time参数
  • 通过bean来接收数据(json格式)
    • 这种方式只支持"yyyy-MM-dd HH:mm:ss"这种格式的time参数
  • 通过RequestParam注解
    • 这种方式只支持"yyyy/MM/dd HH:mm:ss"这种格式的time参数
  • 不通过RequestParam注解
    • 这种方式只支持"yyyy/MM/dd HH:mm:ss"这种格式的time参数

以上几种接收参数的方式接收的参数格式并不统一,而且有时候web前端传入的时间参数为时间戳,还得写修改接口或者让其自己修改格式;

后端给前端统一返回json格式的数据,且时间格式为"yyyy-MM-dd HH:mm:ss"

解决方案

开发之前统一时间接口接收的时间格式

一 yyyy/MM/dd HH:mm:ss 格式

后端所有接口统一接收"yyyy/MM/dd HH:mm:ss"或"yyyy/MM/dd"格式时间参数

第一种: 舍弃上边的方式二的接口

第二种:不舍弃方拾二,在bean的时间属性上添加JsonFormat注解,例如:

  com.fasterxml.jackson.annotation.JsonFormat;
   @JsonFormat(timezone = "GMT+8",pattern = "yyyy/MM/dd HH:mm:ss")
  private Date receiveDate;

优势: 不舍弃方式二接口,且统一了时间格式

使用该注解的弊端: 当pattern="yyyy/MM/dd" 时, 只支持处理“2019/09/03"格式时间参数,不支持“2019/09/03 00:00:00”,且会报错,当pattern="yyyy/MM/dd HH:mm:ss"时,只支持处理“2019/09/03 00:00:00"格式时间参数,其余格式均会报错;

二 接收所有时间格式

  • yyyy-MM-dd HH:mm:ss 格式
  • yyyy-MM-dd 格式
  • 时间戳
  • yyyy/MM/dd HH:mm:ss 格式
  • yyyy/MM/dd 格式

注意

该方式不对json或xml的数据处理,比如使用@RequestBody注解的bean(也就是方式二)

工具类:

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @author gyc
 * @title: DateConverter
 * @projectName app
 * @date 2019/8/1914:36
 * @description: 时间转换类
 */
public class CourseDateConverter implements Converter<String, Date> {
  private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
  private static final String dateFormata = "yyyy-MM-dd HH:mm:ss";
  private static final String shortDateFormat = "yyyy-MM-dd";
  private static final String shortDateFormata = "yyyy/MM/dd";
  private static final String timeStampFormat = "^\\d+$";
  @Override
  public Date convert(String value) {
    if(StringUtils.isEmpty(value)) {
      return null;
    }
    value = value.trim();
    try {
      if (value.contains("-")) {
        SimpleDateFormat formatter;
        if (value.contains(":")) {
          //yyyy-MM-dd HH:mm:ss 格式
          formatter = new SimpleDateFormat(dateFormat);
        } else {
          //yyyy-MM-dd 格式
          formatter = new SimpleDateFormat(shortDateFormat);
        }
        return formatter.parse(value);
      } else if (value.matches(timeStampFormat)) {
        //时间戳
        Long lDate = new Long(value);
        return new Date(lDate);
      }else if (value.contains("/")){
        SimpleDateFormat formatter;
        if (value.contains(":")) {
//          yyyy/MM/dd HH:mm:ss 格式
          formatter = new SimpleDateFormat(dateFormata);
        } else {
//          yyyy/MM/dd 格式
          formatter = new SimpleDateFormat(shortDateFormata);
        }
        return formatter.parse(value);
      }
    } catch (Exception e) {
      throw new RuntimeException(String.format("parser %s to Date fail", value));
    }
    throw new RuntimeException(String.format("parser %s to Date fail", value));
  }
}

将时间转换类应用到接口上

介绍两种方式:使用@Component + @PostConstruct或@ControllerAdvice + @InitBinder

第一种方式:

@Component + @PostConstruct

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import javax.annotation.PostConstruct;

@Component
public class WebConfigBeans {
 @Autowired
 private RequestMappingHandlerAdapter handlerAdapter;
 @PostConstruct
 public void initEditableAvlidation() {
  ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)handlerAdapter.getWebBindingInitializer();
  if(initializer.getConversionService()!=null) {
   GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();

   genericConversionService.addConverter(new DateConverterConfig());

  }
 }
}

第二种方式:

@ControllerAdvice + @InitBinder

import com.aegis.config.converter.DateConverter;
import com.aegis.model.bean.common.JsonResult;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class CourseControllerHandler {
  @InitBinder
  public void initBinder(WebDataBinder binder) {
    GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
    if (genericConversionService != null) {
      genericConversionService.addConverter(new CourseDateConverter());
    }
  }
}

最后

我使用的最后的一种方法的第二种方式

总结

时间参数这个坑还是有点大的,之前都是针对性的处理,只要一变化就没法了;现在这个还是可以应付基本上会出现的错误了;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring 参数验证@Validated和@Valid的区别

    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303 规范,是标准 JSR-303 的一个变种),javax提供了@Valid(标准JSR-303规范),配合 BindingResult 可以直接提供参数验证结果.其中对于字段的特定验证注解比如 @NotNull 等网上到处都有,这里不详述 在检验 Controller 的入参是否符合规范时,使用 @Validated 或者 @Valid 在基本验证功能上没有太多区别.但是在分组.

  • Spring Boot LocalDateTime格式化处理的示例详解

    JDK8的新特性中Time API,其包括Clock.Duration.Instant.LocalDate.LocalTime.LocalDateTime.ZonedDateTime,在这里就不一一介绍了,相信很多人都会使用其代替Date及Calendar来处理日期时间,下面介绍Spring Boot处理LocalDateTime格式. Controller接收LocalDateTime参数 在Spring中,接收LocalDateTime日期时间数据时,只需要使用@DateTimeFormat

  • 使用SpringMVC的@Validated注解验证的实现

    1.SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 edit.username.null=用户名不能为空 edit.password.size=密码最少{min}位,最长{max}位 ...... 可以将edit.username.null与edit.password.size看为参数,在message中传递,具体请看第二步. 第二步:Bean实体类中加注解

  • 解决Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题

    LocalDate . LocalTime . LocalDateTime 是Java 8开始提供的时间日期API,主要用来优化Java 8以前对于时间日期的处理操作.然而,我们在使用Spring Boot或使用Spring Cloud Feign的时候,往往会发现使用请求参数或返回结果中有 LocalDate . LocalTime . LocalDateTime 的时候会发生各种问题.本文我们就来说说这种情况下出现的问题,以及如何解决. 问题现象 先来看看症状.比如下面的例子: @Sprin

  • springboot mybatis里localdatetime序列化问题的解决

    问题起因 主要是使用mybatis作为ORM之后,返回的对象为Map,然后对于数据库的datetime,datestamp类型返回为时间戳而不是标准的时间,这个问题解决方案有两种,大叔分析一下: 1.在mapper的select里,使用mysql这些数据库的函数,dateformat进行转化,缺点,单元测试里使用h2数据库时会找不到这些函数 2.在ObjectMapper反序列化时统一进行处理,这种方式更好,与具体数据库解耦了 实现 >引用依赖包 'org.mybatis:mybatis-typ

  • Spring shiro + bootstrap + jquery.validate 实现登录、注册功能

    之前的文章中我们已经搭建好框架,并且设计好了,数据库. 现在我们开始实现登录功能,这个可以说是Web应用最最最普遍的功能了. 先来说说我们登录的逻辑: 输入用户名.密码(validate进行前端验证)--ajax调用后台action方法--根据用户名调用业务层到数据层查询数据库信息--查询的密码跟用户输入的密码比对--shiro登录身份验证--将用户信息存入session--响应前端--前端跳转 这个是我要告诉大家的姿势,还有很多很多的姿势.下面我们来看具体的代码. 首先前端验证,这里使用了jq

  • spring boot @ResponseBody转换JSON 时 Date 类型处理方法【两种方法】

    spring boot @ResponseBody转换JSON 时 Date 类型处理方法[两种方法],Jackson和FastJson两种方式. spring boot @ResponseBody转换JSON 时 Date 类型处理方法 ,这里一共有两种不同解析方式(Jackson和FastJson两种方式) 第一种方式:默认的json处理是 jackson 也就是对configureMessageConverters 没做配置时 mybatis数据查询返回的时间,是一串数字,如何转化成时间.

  • Spring注入Date类型的三种方法总结

    Spring注入Date类型的三种方法总结 测试Bean: public class DateBean { private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } 方式1:利用SimpleDateFormat的构造方法注入 <?xml version="1.0&quo

  • 基于springboot处理date参数过程解析

    这篇文章主要介绍了基于springboot处理date参数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言 最近在后台开发中遇到了时间参数的坑,就单独把这个问题提出来找时间整理了一下: 正文 测试方法 bean代码: public class DateModelNoAnnotation { private Integer id; private Date receiveDate; } controller代码: @RestContr

  • 基于SPRINGBOOT配置文件占位符过程解析

    这篇文章主要介绍了基于SPRINGBOOT配置文件占位符过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.配置文件占位符 1.application.properties server.port=8088 debug=false product.id=ID:${random.uuid} product.name=da mao mao product.weight=${random.int} product.fristLinePrice

  • 如何基于SpringBoot部署外部Tomcat过程解析

    这篇文章主要介绍了SpringBoot以war包形式部署到外部Tomcat过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 SpringBoot 项目打包时能打成 .jar 与 .war包文件,.jar使用 java -jar xx.jar 就可以启动,而 .war 可以部署到tomcat的 webapps 中,随tomcat的启动而启动. SpringBoot 本身是内置tomcat的,如果想部署到外部tomcat, 就要做一些改变.

  • 基于SpringBoot实现定时发送邮件过程解析

    前提: 1.Springboot项目 2.引入maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 以下代码中涉及到的maven依赖有日志依赖,但是springboot都有集成,不用重新引入依赖 Application(程序入口)

  • 基于springboot设置Https请求过程解析

    1.首先去阿里云购买个证书,也有免费的,但是免费的只能使用一年,证书需要绑定域名 2.将证书放进项目 3.配置YML server: ssl: key-store: 55555.pfx key-store-password: 55555 keyStoreType: PKCS12 connectionTimeout: 20000 port: 8888 重点来了,配置请求转发 @Configuration public class WebMvcconfig implements WebMvcConf

  • Springboot整合GuavaCache缓存过程解析

    这篇文章主要介绍了springboot整合GuavaCache缓存过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Guava Cache是一种本地缓存机制,之所以叫本地缓存,是因为它不会把缓存数据放到外部文件或者其他服务器上,而是存放到了应用内存中. Guava Cache的优点是:简单.强大.轻量级. GuavaCache适用场景: 1.某些接口或者键值会被查询多次以上: 2.愿意使用或牺牲一些内存空间来提升访问或者计算速度: 3.缓

  • Springboot 集成 lombok.jar过程解析

    这篇文章主要介绍了Springboot 集成 lombok.jar过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 介绍 Spring Boot是非常高效的开发框架,lombok是一套代码模板解决方案,将极大提升开发的效率,这里介绍给大家使用. Lombok想要解决了的是在我们实体Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不会用到,但是某些时候仍然需要复写,以期方便使用的方法:在使用Lo

  • SpringBoot Shiro授权实现过程解析

    这篇文章主要介绍了SpringBoot Shiro授权实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用Shiro过滤器实现授权 设置好授权拦截跳转的请求地址 /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") Defaul

  • 基于python调用psutil模块过程解析

    这篇文章主要介绍了基于python调用psutils模块过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 用Python来编写脚本简化日常的运维工作是Python的一个重要用途.在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等.要获取这些系统信息,Python可以通过subprocess模块调用并获取结果.但这样做显得很麻烦,尤其是要写很多解析代码. 在Python中获取系统信息的另一个好办法是

  • SpringBoot整合Dubbo zookeeper过程解析

    这篇文章主要介绍了SpringBoot整合Dubbo zookeeper过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 docker pull zookeeper docker run --name zk01 -p 2181:2181 --restart always -d 2e30cac00aca 表明zookeeper已成功启动 Zookeeper和Dubbo• ZooKeeperZooKeeper 是一个分布式的,开放源码的分布式

随机推荐