问题描述
java中的date类型 在接收前台传入的参数时报400错误。时间格式为“yyyy-MM-dd HH:mm:ss"。
问题分析
由于前端传入的参数默认为String,然后与后台接收的参数不匹配,所以浏览器报400错误。
解决方案
- 通过String 变量来接收字符串,然后通过时间转换类DateFormatter进行转换后,得到Date对象。
@Controller
public class TestController(){
public void test(String dateString){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(dateString); //转换为date
}
}
- 在controller中绑定一个时间转换方法
@Controller
public class TestController{
@InitBinder
public void intDate(WebDataBinder dataBinder){
dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
public void test(Date date){
……
}
}
这样在整个controller中的所有方法在接收date类型的字符串时,都会自动转换为Date对象。为了方便使用,可以写一个基础的controller作为父类,将绑定的方法写父controller中,如:
public class BaseController{
@InitBinder
public void intDate(WebDataBinder dataBinder){
dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
}
@Controller
public class TestController extends BaseController{
public void test(Date date){
……
}
}
Date返回
- 将Date对象返回前台时,需要先转化为json字符串,然后提供给前台。否则会报undefined的错误。
- 解决方案
在将对象转化为json对象的时候,提供时间转化的格式配置。
// 使用方式
Class Test (){
private static JsonConfig jsonConfig = new JsonConfig();
static {
jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
}
}
public String test(){
return JSONObject.fromObject(new Date(), jsonConfig).toString();
}
}
// 工具类
public class JsonDateValueProcessor implements JsonValueProcessor {
private String format = "yyyy-MM-dd hh:mm:ss";
public JsonDateValueProcessor() {
super();
}
public JsonDateValueProcessor(String format) {
super();
this.format = format;
}
@Override
public Object processArrayValue(Object paramObject,JsonConfig paramJsonConfig) {
return process(paramObject);
}
@Override
public Object processObjectValue(String paramString, Object paramObject,JsonConfig paramJsonConfig) {
return process(paramObject);
}
private Object process(Object value) {
if (value instanceof Date) {
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
return sdf.format(value);
}
return value == null ? "" : value.toString();
}
}
Springboot(2019-04-04)
相比之前冗余的解决方案,springboot中对时间的处理显得十分简单。通过在实体类上配置注解即可完成对时间的特殊处理。
public class PubHoliday extends BaseEntity{
private Integer id;
private String holidayName;
@JsonFormat(timezone = "GMT+8", pattern = "YYYY-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date holidayDate;
private Integer dayType;
// 0:自动导入,1手工添加
private Integer state;
}
@JsonFormat(timezone = “GMT+8”, pattern = “YYYY-MM-dd”) :即返回结果时,时间对象安装此格式转换。
@DateTimeFormat(pattern=“yyyy-MM-dd”) :即接收参数时以此格式接收。
问题
由于需要访问static目录的静态文件配置了拦截器。
@Configuration
@EnableWebMvc
@ComponentScan
public class InterceptorConfiger implements WebMvcConfigurer {
private ApplicationContext applicationContext;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/static/");
registry.addResourceHandler("/templates/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/templates/");
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
.modulesToInstall(new ParameterNamesModule()); //JDK8 新特性,可选择多个模块
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
/**
* 自动转换时间格式
*
* @param registry date
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
}
增加此配置后,实体类上的注解将会失效。所以时间格式以这里配置的为准。