SpringBoot中Formatter和Converter用法和区别

文章详细比较了Spring中Formatter和Converter两种类型转换工具的使用场景和区别。Formatter主要用于String到其他Java类型的转换,常在web层处理输入输出,而Converter可以进行任意类型的转换,不仅限于web层。在有冲突的情况下,Spring优先使用Formatter。文章提供了Formatter和Converter的使用示例,并指出在JSON格式数据交互时,Formatter对某些类型的转换(如Date)仍能正常工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能区别:

两者的作用一样,都是类型转换。

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。

<think>我们正在讨论Spring Boot中的注解。用户询问是否存在@Binding注解。 在Spring Boot中,并没有一个名为@Binding的标准注解。但是,Spring框架中有一些与数据绑定相关的注解,比如@ModelAttribute、@RequestParam、@RequestBody等,它们用于将请求参数绑定到方法参数上。 另外,Spring Boot中有一个@ConfigurationProperties注解用于将配置文件中的属性绑定到Java对象上,这也可以看作是一种绑定。 但是,如果用户指的是在数据验证方面的绑定,可能会使用到@Valid或@Validated注解。 因此,我们需要澄清:没有直接叫做@Binding的注解,但可能有其他注解完成了类似的功能。 然而,值得注意的是,在Spring Cloud Stream中有一个@EnableBinding注解(在较新版本中已被弃用),它用于绑定消息通道。但用户问的是@Binding,而不是@EnableBinding。 所以,回答应该是:Spring Boot中没有直接名为@Binding的注解。但是,根据上下文,可能有其他注解用于数据绑定。 然后,按照要求,我们需要在最后提出3-5个相关问题。</think>在 Spring Boot 中,**不存在名为 `@Binding` 的标准注解**。这个名称可能与 Spring 框架中的其他绑定相关概念混淆,以下是关键澄清: ### 常见绑定相关注解 1. **数据绑定**: - `@ModelAttribute`:将请求参数绑定到方法参数或模型对象 - `@RequestParam`:绑定单个请求参数 - `@RequestBody`:绑定 HTTP 请求体到 Java 对象(用于 JSON/XML) - `@RequestHeader`:绑定请求头值 2. **配置属性绑定**: - `@ConfigurationProperties`:将配置文件属性绑定到 Java Bean ```java @ConfigurationProperties(prefix = "app") public class AppConfig { private String name; private int version; // getters/setters } ``` 3. **表单验证**: - `@Valid` 或 `@Validated`:触发 JSR-303 验证(如 `@NotNull`, `@Size`) ```java @PostMapping("/submit") public String submitForm(@Valid @ModelAttribute FormData form) { // ... } ``` 4. **Spring Cloud Stream(消息绑定)**: - `@Input` `@Output`:定义消息通道(注意:`@EnableBinding` 在 Spring Cloud Stream 3.1+ 已弃用) ```java // 旧版写法(已弃用) public interface MyChannels { @Input("inputChannel") SubscribableChannel input(); } ``` ### 可能混淆的概念 - **Thymeleaf 模板**:在 HTML 中使用 `th:field="*{name}"` 进行表单绑定 - **Spring Data JPA**:通过方法名自动推导查询(如 `findByName(String name)`) - **Spring Integration**:`@ServiceActivator` 等注解处理消息绑定 ### 替代方案建议 如果需要自定义绑定逻辑,可考虑: 1. 实现 `Converter` 或 `Formatter` 接口 2. 使用 `@InitBinder` 自定义数据绑定规则 3. 对于复杂场景,采用 `HandlerMethodArgumentResolver`
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大先锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值