SpringBoot中Formatter和Converter用法和區(qū)別小結
功能區(qū)別:
兩者的作用一樣,都是類型轉換。
- 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格式數據交互,測試發(fā)現解析報錯。
{
"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.創(chuàng)建轉換類:其他步驟和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中Formatter和Converter用法和區(qū)別小結的文章就介紹到這了,更多相關SpringBoot Formatter Converter 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

