当前位置 主页 > 服务器问题 > Linux/apache问题 >

    详解SpringBoot时间参数处理完整解决方案(2)

    栏目:Linux/apache问题 时间:2019-12-03 10:46

    注:这个DateConverter类在下面都会用到。

    import com.aegis.yqmanagecenter.config.date.DateConverter;
    import com.aegis.yqmanagecenter.model.bean.common.JsonResult;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.propertyeditors.CustomDateEditor;
    import org.springframework.core.convert.support.GenericConversionService;
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.*;
    
    import java.beans.PropertyEditorSupport;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @ControllerAdvice
    public class ControllerHandler {
    
     private Logger logger = LoggerFactory.getLogger(ControllerHandler.class);
    
     @InitBinder
     public void initBinder(WebDataBinder binder) {
      // 方法1,注册converter
      GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
      if (genericConversionService != null) {
       genericConversionService.addConverter(new DateConverter());
      }
    
      // 方法2,定义单格式的日期转换,可以通过替换格式,定义多个dateEditor,代码不够简洁
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      CustomDateEditor dateEditor = new CustomDateEditor(df, true);
      binder.registerCustomEditor(Date.class, dateEditor);
    
    
      // 方法3,同样注册converter
      binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
       @Override
       public void setAsText(String text) throws IllegalArgumentException {
        setValue(new DateConverter().convert(text));
       }
      });
    
     }
    }
    
    

    注:上面的三个方法都是利用@ControllerAdvice+@InitBinder来设置时间参数处理的,其中1和3都可以设置DateConverter,而方法2只能一个一个手动设置格式。

    这里需要注意,上述配置方法都无法解决Json格式数据中的时间参数接收问题。下面我们直接看完整的解决方案——将DateConverter注册为组件,并使用ObjectMapper来配置时间参数的序列化(接口返回值)和反序列化形式(接口接收参数)。

    2.2 配置ObjectMapper以及完整解决方案

    完整的解决方案:

    /**
     * 日期转换配置
     * 解决@RequestAttribute、@RequestParam和@RequestBody三种类型的时间类型参数接收与转换问题
     */
    @Configuration
    public class DateConfig {
    
     /**
      * 默认日期时间格式
      */
     public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
     /**
      * Date转换器,用于转换RequestParam和PathVariable参数
      */
     @Bean
     public Converter<String, Date> dateConverter() {
      return new DateConverter();
     }
    
     /**
      * Json序列化和反序列化转换器,用于转换Post请求体中的json以及将我们的对象序列化为返回响应的json
      * 使用@RequestBody注解的对象中的Date类型将从这里被转换
      */
     @Bean
     public ObjectMapper objectMapper(){
      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
      objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
    
      JavaTimeModule javaTimeModule = new JavaTimeModule();
    
      //Date序列化和反序列化
      javaTimeModule.addSerializer(Date.class, new JsonSerializer<Date>() {
       @Override
       public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
        String formattedDate = formatter.format(date);
        jsonGenerator.writeString(formattedDate);
       }
      });
      javaTimeModule.addDeserializer(Date.class, new JsonDeserializer<Date>() {
       @Override
       public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        return new DateConverter().convert(jsonParser.getText());
       }
      });
    
      objectMapper.registerModule(javaTimeModule);
      return objectMapper;
     }
    
    }