📜  initbinder 中的 spring 转换器 - Java (1)

📅  最后修改于: 2023-12-03 15:15:50.282000             🧑  作者: Mango

Spring中的转换器和InitBinder

在Spring开发中,经常需要将前端传来数据进行数据类型转换和格式化,使其适合存储和处理。Spring中提供了转换器和InitBinder机制来帮助我们实现这些操作。

转换器

Spring的转换器是一个用于数据类型转换和格式化的通用机制。在Spring中,转换器主要用于将字符串转换为常见的基本数据类型以及自定义类型。

实现Converter接口

Spring中的转换器都是实现Converter接口的类。转换器需要实现两个方法:convertmatch。其中convert方法用于执行真正的转换操作,match方法则用于判断是否支持该类型的转换。

例如,需要将字符串转为Date类型,可以实现如下转换器:

public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return dateFormat.parse(source);
        } catch (ParseException e) {
            throw new IllegalArgumentException("无法转换为日期格式");
        }
    }
    
    @Override
    public boolean match(Class<?> sourceType, Class<?> targetType) {
        return String.class.equals(sourceType) && Date.class.equals(targetType);
    }
}
注册转换器

在Spring中,我们需要将自定义的转换器注册到Spring容器中。可以通过以下两种方式实现:

  1. 编写配置类WebMvcConfigurer,覆盖addFormatters方法,在该方法中添加转换器。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToDateConverter());
    }
}
  1. 使用注解方式,在转换器类上添加注解@Component@Converter
@Component
public class StringToDateConverter implements Converter<String, Date> {
    // ...
}
InitBinder

InitBinder是Spring MVC中的一个用于参数绑定的注解,可以用于在Controller处理请求时,对参数值进行预处理或格式化的操作。

用于处理HTTP请求参数

在处理HTTP请求时,Spring MVC默认使用ServletRequestDataBinder将HTTP请求参数绑定到控制器方法的入参上。InitBinder可以对入参进行预处理,在使用ServletRequestDataBinder进行绑定前,对入参进行格式化或修改操作。

例如,需要对日期类型入参进行格式化,可以在Controller方法上添加InitBinder,实现如下:

@Controller
@RequestMapping("/user")
public class UserController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        df.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(df, false));
    }

    @RequestMapping("/addUser")
    public String addUser(@ModelAttribute User user) {
        // ...
    }
}

在上述例子中,InitBinder将入参Date类型转为字符串并进行格式化,然后交由Spring MVC的默认Binder进行类型转换和绑定。

用于处理属性编辑器

除了用于处理HTTP请求参数外,InitBinder也可以用于处理属性编辑器。属性编辑器和转换器的作用相似,可以用于将值从一种类型转为另一种类型。

例如,需要对User实体中的Birthday属性进行日期格式化,可以实现如下属性编辑器:

public class DateEditor extends PropertyEditorSupport {
    private SimpleDateFormat dateFormat;

    public DateEditor(SimpleDateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            Date date = dateFormat.parse(text);
            setValue(date);
        } catch (ParseException e) {
            throw new IllegalArgumentException("无法转换为日期格式");
        }
    }

    @Override
    public String getAsText() {
        return dateFormat.format((Date) getValue());
    }
}

并在Controller中添加InitBinder,实现如下:

@Controller
@RequestMapping("/user")
public class UserController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        df.setLenient(false);
        binder.registerCustomEditor(Date.class, new DateEditor(df));
    }

    @RequestMapping("/addUser")
    public String addUser(@ModelAttribute User user) {
        // ...
    }
}
总结

通过转换器和InitBinder机制,Spring提供了基本的类型转换和格式化功能,同时也帮助我们解决了在应用中常见的一些问题。在实际开发中,我们需要根据具体要求自定义代码实现转换器和属性编辑器,以此来满足我们的开发需求。