乐趣区

Spring-Boot实战之定制type-Formatters

本文首发于个人网站:Spring Boot 实战之定制 type Formatters

前面我们有篇文章介绍了 PropertyEditors,是用来将文本类型转换成指定的 Java 类型,不过,考虑到 PropertyEditor 的无状态和非线程安全特性,Spring 3 增加了一个 Formatter 接口来替代它。Formatters 提供和 PropertyEditor 类似的功能,但是提供线程安全特性,也可以实现字符串和对象类型的互相转换。

假设在我们的程序中,需要根据一本书的 ISBN 字符串得到对应的 book 对象。通过这个类型格式化工具,我们可以在控制器的方法签名中定义 Book 参数,而 URL 参数只需要包含 ISBN 号和数据库 ID。

实战

  • 首先在项目根目录下创建 formatters
  • 然后创建 BookFormatter,它实现了 Formatter 接口,实现两个函数:parse 用于将字符串 ISBN 转换成 book 对象;print 用于将 book 对象转换成该 book 对应的 ISBN 字符串。
package com.test.bookpub.formatters;

import com.test.bookpub.domain.Book;
import com.test.bookpub.repository.BookRepository;
import org.springframework.format.Formatter;
import java.text.ParseException;
import java.util.Locale;

public class BookFormatter implements Formatter<Book> {
    private BookRepository repository;

    public BookFormatter(BookRepository repository) {this.repository = repository;}
  
    @Override
    public Book parse(String bookIdentifier, Locale locale) throws ParseException {Book book = repository.findBookByIsbn(bookIdentifier);
        return book != null ? book : repository.findOne(Long.valueOf(bookIdentifier));
    }
  
    @Override
    public String print(Book book, Locale locale) {return book.getIsbn();
    }
}
  • 在 WebConfiguration 中添加我们定义的 formatter,重写(@Override 修饰)addFormatter(FormatterRegistry registry)函数。
@Autowired
private BookRepository bookRepository;

@Override
public void addFormatters(FormatterRegistry registry) {registry.addFormatter(new BookFormatter(bookRepository));
}
  • 最后,需要在 BookController 中新加一个函数 getReviewers,根据一本书的 ISBN 号获取该书的审阅人。
@RequestMapping(value = "/{isbn}/reviewers", method = RequestMethod.GET)
public List<Reviewer> getReviewers(@PathVariable("isbn") Book book) {return book.getReviewers();
}
  • 通过 mvn spring-boot:run 运行程序
  • 通过 httpie 访问 URL——http://localhost:8080/books/9781-1234-1111/reviewers,得到的结果如下:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Date: Tue, 08 Dec 2015 08:15:31 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked

[]

分析

Formatter工具的目标是提供跟 PropertyEditor 类似的功能。通过 FormatterRegistry 将我们自己的 formtter 注册到系统中,然后 Spring 会自动完成文本表示的 book 和 book 实体对象之间的互相转换。由于 Formatter 是无状态的,因此不需要为每个请求都执行注册 formatter 的动作。

使用建议:如果需要通用类型的转换——例如 String 或 Boolean,最好使用 PropertyEditor 完成,因为这种需求可能不是全局需要的,只是某个 Controller 的定制功能需求。

我们在 WebConfiguration 中引入(@Autowired)了BookRepository(需要用它创建 BookFormatter 实例),Spring 给配置文件提供了使用其他 bean 对象的能力。Spring 本身会确保 BookRepository 先创建,然后在 WebConfiguration 类的创建过程中引入。

Spring Boot 1.x 系列

  1. Spring Boot 的自动配置、Command-line-Runner
  2. 了解 Spring Boot 的自动配置
  3. Spring Boot 的 @PropertySource 注解在整合 Redis 中的使用
  4. Spring Boot 项目中如何定制 HTTP 消息转换器
  5. Spring Boot 整合 Mongodb 提供 Restful 接口
  6. Spring 中 bean 的 scope
  7. Spring Boot 项目中使用事件派发器模式
  8. Spring Boot 提供 RESTful 接口时的错误处理实践
  9. Spring Boot 实战之定制自己的 starter
  10. Spring Boot 项目如何同时支持 HTTP 和 HTTPS 协议
  11. 自定义的 Spring Boot starter 如何设置自动配置注解
  12. Spring Boot 项目中使用 Mockito
  13. 在 Spring Boot 项目中使用 Spock 测试框架
  14. Spring Boot 项目中如何定制拦截器
  15. Spring Boot 项目中如何定制 PropertyEditors
  16. Spring Boot 构建的 Web 项目如何在服务端校验表单输入
  17. Spring Boot 应用的健康监控
  18. Spring Boot 项目中如何定制 servlet-filters
  19. Spring Boot 实战之定制 URL 匹配规则

本号专注于后端技术、JVM 问题排查和优化、Java 面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

退出移动版