SpringBoot中Formatter和Converter用法和区别
功能区别:
两者的作用一样,都是类型转换。
org.springframework.format.Formatter只能做String类型到其他类型的转换。
org.springframework.core.convert.converter.Converter可以做任意类型的转换。
Converter是一般工具,可以将一种类型转换成另一种类型。例如,将String转换成Date,或者将Long转换成Date。Converter既可以用在web层,也可以用在其它层中。Formatter只能将String转成成另一种java类型。例如,将String转换成Date,但它不能将Long转换成Date。
Formatter
Formatter使用示例:
1.定义Formatter类:
需要实现Formatter接口, 并在pase方法中进行转换的逻辑。通过@Component自动将其添加到SpringBoot容器,这样就会自动生效。
@Component
public class StudentFormatter implements Formatter<Student> {
/**
* 校验不太严密,仅作演示
*/
@Override
public Student parse(String text, Locale locale) {
if (NumberUtils.isParsable(text)) {
Student s = new Student();
s.setAge(Integer.parseInt(text));
return s;
}
return null;
}
@Override
public String print(Student money, Locale locale) {
if (money == null) {
return null;
}
return money.getAge()+"";
}
}
2.Controller中的代码:
@PostMapping(path = "/stu")
@ResponseBody
public String sst(NewRequest newCoffee) {
return newCoffee.getStudent().getAge()+"";
}
数据实体:
@Getter
@Setter
@ToString
public class NewRequest {
private String name;
private Student student;
}
3.访问:http://localhost:8080/stu
采用application/x-www-form-urlencoded 参数类型传递参数。
这样服务端收到参数,就会自动将字符串转换成一个Student对象。
注意点:这里采用了application/x-www-form-urlencoded提交参数,所以在Controller中不能加@RequestBody,并且参数名称要和数据对象的属性保持一致。如果采用json格式数据交互,测试发现解析报错。
{
"timestamp": "2019-09-05T07:42:00.809+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Current token (VALUE_STRING) not numeric, can not use numeric value accessors; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Current token (VALUE_STRING) not numeric, can not use numeric value accessors\n at [Source: (PushbackInputStream); line: 1, column: 29] (through reference chain: geektime.spring.springbucks.waiter.controller.request.NewCoffeeRequest[\"price\"])",
"path": "/coffee/addJson"
}
说明在转换成自定义的对象时,必须通过form格式进行传参。
但奇怪的是Date类型的转换,通过json格式传递参数,可以正常转换。 如下:
@Component
public class DateFormatter implements Formatter<Date> {
@Override
public Date parse(String text, Locale locale) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
System.out.println("parse input text: " + text);
System.out.println("parse date: " + dateFormat.parse(text));
return dateFormat.parse(text);
}
@Override
public String print(Date object, Locale locale) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
System.out.println("print method." + object);
return dateFormat.format(object);
}
}
Controller中:
@ResponseBody
@PostMapping(path = "/date")
public String formatterStringToDate(@RequestBody ZXRequest date) {
System.out.println("action method: " + date.getDate().getTime());
return date.getDate().getTime()+"";
}
数据类:
@Getter
@Setter
@ToString
public class ZXRequest {
private Date date;
}
访问:
可以正常返回。说明转换正确。关于原因,目前尚不清楚,有知道的,希望留言。
Converter使用示例:
1.创建转换类:其他步骤和Formatter完全一样。
@Component
public class StudentConvert implements Converter<String ,Student> {
@Override
public Student convert(String text) {
if (NumberUtils.isParsable(text)) {
Student s = new Student();
s.setAge(Integer.parseInt(text));
return s;
}
return new Student();
}
}
如果同时定义了Converter和Formatter,并且转换同一个类型,会采用哪个进行转换?
测试证明,同时定义Student的转换类,会采用Formatter。
相关文章
- SpringBoot框架_skynet框架详解
- SpringBoot面试题大汇总附答案,SpringBoot面试题-持续更新中「建议收藏」
- SpringBoot——ResponseBody
- springboot事物oracle,SpringBoot 事务管理
- 最简单的SpringBoot整合MyBatis教程
- SpringBoot框架:第二章:SpringBoot中static和templates二个目录下的页面和静态资源访问的三个常见问题
- SpringBoot整合Redis[哨兵版]
- SpringBoot优雅整合RocketMQ
- Springboot集成swagger_springboot nginx
- springboot多环境配置文件_Springboot教程
- springboot到底是什么_Springboot注解
- springboot jdbc template_Springboot教程
- springBoot整合Mybatis-Plus需要的依赖_springboot中文手册
- SpringBoot 三层开发复习
- 【开发日记】SpringBoot做参数校验
- [线程池]Springboot如何使用线程池
- springboot整合使用云服务器上的Redis方法
- springmvc和springboot的区别详解编程语言
- SpringBoot之静态资源(F)详解编程语言
- springboot-配置多个数据源详解编程语言