搭建完一个spring-boot的接口服务后,可以在前段通过ajax异步请求后台接口数据,一般ajax通过传递json对象给后台接口,后台接收数据转化为Bean对象,处理逻辑完成后,将返回的数据转为json回送给前台调用者;
1.前台ajax参数格式为:
var param1={
id:1234,
name:'名称',
path:'路径',
createdDate:'2017-01-05 12:45:32'
}
2.ajax 调用
$.get("http://***********/ajaxApi/getOfBean",param, function(result){
console.info("result:"+JSON.stringify(result));
});
3.后台接收参数的Bean实体类
public class Ajax implements Serializable{
private Long id;
private String name;
private String path;
private Date createdDate;
}
4.后台spring-boot提供的接口:
@RestController
@RequestMapping(value="ajaxApi")
@Api(value = "/ajaxApi", description = "异步接口测试API",tags={"/ajaxApi"})
public class AjaxController {
private static final Logger logger = LoggerFactory.getLogger(AjaxController.class);
/***
* 异步参数接收
* @return
*/
@RequestMapping(value = "/getOfBean")
@ApiOperation("Bean实体参数")
public Ajax getOfBean(Ajax ajax) throws Exception{
logger.info("异步参数接收:{}",ajax.toString());//打印接收的对象
return ajax;
}
}
接口接收参数为AjaxBean实体类,结束后返回该实体类给前台;启动项目,触发ajax请求,报错:
【org.springframework.validation.BindException】
Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'createdDate';
nested exception is org.springframework.core.convert.ConversionFailedException:
Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2017-01-05 12:45:32';
nested exception is java.lang.IllegalArgumentException
【
报错原因】:
ajax使用json字符串将日期字符串发送到后台接口,后台无法将字符串转为日期类型,缺少转换器;
【解决方法】:
增加日期类型转换器,方式有四种:
第一种:在Bean实体字段或参数上增加@DateTimeFormat注解
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate;
第二种:在接收参数的的Controller中增加
@InitBinder转化方法
@InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
【*】此种方式只对当前controller起作用
第三种:配置全局的日期转换器
/**
* 转换解析器
* @author wangqingguo 2017/9/25
*/
@Configuration
public class MappingConverterAdapter {
/***
* 日期参数接收转换器,将json字符串转为日期类型
* @return
*/
@Bean
public Converter DateConvert() {
return new Converter() {
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = sdf.parse((String) source);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
};
}
}
【*】此处定义的dateConvert用来转换Date类型,如果是LocalDate、LocalDateTime类型,则将Date
类型换成相应的类型即可,注意java8的日期类型需要用Formatter格式化:
/**
* 转换解析器
* @author wangqingguo 2017/9/25
*/
@Configuration
public class MappingConverterAdapter {
/***
* 日期参数接收转换器,将json字符串转为日期类型
* @return
*/
@Bean
public Converter LocalDateTimeConvert() {
return new Converter() {
@Override
public LocalDateTime convert(String source) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date = null;
try {
date = LocalDateTime.parse((String) source,df);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
};
}
}
/**
* 日期转换器
* @author LiMeng 2017/11/7
*/
@Configuration
public class DateConfig {
/***
* Date日期类型转换器
* @return
*/
@Bean
public Formatter dateFormatter() {
return new Formatter() {
@Override
public Date parse(String text, Locale locale) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = sdf.parse(text);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
@Override
public String print(Date object, Locale locale) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(object);
}
};
}
}
/**
* 日期转换器
* @author LiMeng 2017/11/7
*/
@Configuration
public class DateConfig {
/***
* Date日期类型转换器
* @return
*/
@Bean
public Formatter dateFormatter() {
return new Formatter() {
@Override
public Date parse(String text, Locale locale) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = sdf.parse(text);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
@Override
public String print(Date object, Locale locale) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(object);
}
};
}
@Bean
public Formatter localDateFormatter() {
return new Formatter() {
@Override
public LocalDate parse(String text, Locale locale) throws ParseException {
return LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
}
@Override
public String print(LocalDate object, Locale locale) {
return DateTimeFormatter.ISO_LOCAL_DATE.format(object);
}
};
}
@Bean
public Formatter localDateTimeFormatter() {
return new Formatter() {
@Override
public String print(LocalDateTime localDateTime, Locale locale) {
DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return formatter.format(localDateTime);
}
@Override
public LocalDateTime parse(String text, Locale locale) throws ParseException {
DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
};
}
}
解决方式有以下几种
第一种:在Bean实体属性增加 @JsonFormat注解
@JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date createdDate;
@JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
另外LocalDateTime只加此注解,还是无法解析,需要增加jackson-datatype-jsr310jar包才管用
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.3'
第二种:增加MappingJackson2HttpMessageConverterAdapter 转换器,对日期类型进行格式化转换:
/**
* JSON解析器
* @author wangqingguo 2017/9/25
*/
@Configuration
public class MappingJackson2HttpMessageConverterAdapter {
/***
* 配置JSON解析器内容
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter a= new MappingJackson2HttpMessageConverter();
/***
* 头格式
*/
List supportedMediaTypes=new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
supportedMediaTypes.add(MediaType.TEXT_HTML);
supportedMediaTypes.add(MediaType.TEXT_PLAIN);
a.setSupportedMediaTypes(supportedMediaTypes);
/***
* 日期格式化,解决返回的日期类型格式化
*/
ObjectMapper objectMapper = a.getObjectMapper();
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
objectMapper.setDateFormat(dateFormat);
a.setObjectMapper(objectMapper);
return a;
}
}
【*】注:此种方式只对Date类型起作用,Java8的LocalDateTime类型不起作用,LocalDateTime类型还是需要用@JsonFormat注解的形式;