по умолчанию
По умолчанию, если конфигурация для получения данных типа Date не добавлена, внешний интерфейс передает данные типа Date во внутренний интерфейс, и на консоли возникает следующее исключение:
Failed to convert from type [java.lang.String] to type [java.util.Date] for value
'2333333333'; nested exception is java.lang.IllegalArgumentException]]
То есть вSpringBoot
, необходимо добавить некоторую конфигурацию, чтобы внешний интерфейс мог правильно передавать данные типа времени на серверную часть. Ниже приведены решения для различных ситуаций.
Локальная конфигурация - использовать@DateTimeFormat
В первом случае необходимо преобразовать только поле типа даты класса Bean, затем необходимо добавить только атрибут класса Bean.@DateTimeFormat()
Примечания в скобкахpattern
Формат даты, переданный для внешнего интерфейса. Например:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
Date createTime;
Особенности - Дефекты:
В соответствии с приведенной выше конфигурацией может быть обработана только форма:2018-11-2 2:22:2
Такие данные фиксированного формата не могут обрабатывать метки времени и2018-11-2
форматировать данные. Если вы хотите иметь дело с2018-11-2
В такое время необходимоpattern
изменить наyyyy-MM-dd
.
Разным атрибутам можно присвоить разныеpattern
, но добавлять аннотации к каждому типу Date громоздко, и он не может справиться с ситуацией, когда одному атрибуту могут соответствовать значения в разных форматах.
Более общий и эффективный способ — определить класс преобразования времени и применить его ко всем интерфейсам.
Глобальная конфигурация — пользовательский преобразователь времени
Делится на два этапа:
- Напишите класс преобразования времени для преобразования возможных форматов в тип даты.
- Каким-то образом преобразование времени применяется ко всем интерфейсам Spring.
класс преобразования времени
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 日期转换类
* 将标准日期、标准日期时间、时间戳转换成Date类型
*/
public class DateConverter implements Converter<String, Date> {
private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
private static final String shortDateFormat = "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(":")) {
formatter = new SimpleDateFormat(dateFormat);
} else {
formatter = new SimpleDateFormat(shortDateFormat);
}
return formatter.parse(value);
} else if (value.matches(timeStampFormat)) {
Long lDate = new Long(value);
return new Date(lDate);
}
} 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;
/**
* @author zfh
* @version 1.0
* @date 2018/12/30 10:16
*/
@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
Чтобы понять значение этих двух аннотаций, пожалуйста, обратитесь к моему блогу:Spring расширенный @ControllerAdvice и унифицированная обработка исключений
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.*;
/**
* @author zfh
* @version 1.0
* @since 2019/1/4 15:23
*/
@ControllerAdvice
public class ControllerHandler {
@InitBinder
public void initBinder(WebDataBinder binder) {
GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
if (genericConversionService != null) {
genericConversionService.addConverter(new DateConverter());
}
}
}
Хорошо, здесь представлены соответствующие решения проблемы обработки SpringBoot передачи даты во внешнем интерфейсе.