SpringBoot第八天 - Web类型转换器

SpringBoot - Web类型转换器1. 类型转换器概述类型转换器就是将一个类型转换为另一个类型,Spring提供的类型转换器多达上百种,比如可以将String类型转换为数字类型。同时Spring也提供的类型转换器的接口Converter:// org.springframework.core.convert.converter.Converter@FunctionalInterfacepublic interface Converter<S, T> { /** *
摘要由CSDN通过智能技术生成

SpringBoot - Web类型转换器

1. 类型转换器概述

类型转换器就是将一个类型转换为另一个类型,Spring提供的类型转换器多达上百种,
比如可以将String类型转换为数字类型。

同时Spring也提供的类型转换器的接口Converter

// org.springframework.core.convert.converter.Converter

@FunctionalInterface
public interface Converter<S, T> {
   

	/**
	 * Convert the source object of type {@code S} to target type {@code T}.
	 * @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
	 * @return the converted object, which must be an instance of {@code T} (potentially {@code null})
	 * @throws IllegalArgumentException if the source cannot be converted to the desired target type
	 */
	@Nullable
	T convert(S source);

	/**
	 * Construct a composed {@link Converter} that first applies this {@link Converter}
	 * to its input, and then applies the {@code after} {@link Converter} to the
	 * result.
	 * @param after the {@link Converter} to apply after this {@link Converter}
	 * is applied
	 * @param <U> the type of output of both the {@code after} {@link Converter}
	 * and the composed {@link Converter}
	 * @return a composed {@link Converter} that first applies this {@link Converter}
	 * and then applies the {@code after} {@link Converter}
	 * @since 5.3
	 */
	default <U> Converter<S, U> andThen(Converter<? super T, ? extends U> after) {
   
		Assert.notNull(after, "After Converter must not be null");
		return (S s) -> {
   
			T initialResult = convert(s);
			return (initialResult != null ? after.convert(initialResult) : null);
		};
	}

}

我们可以通过实现convert方法来根据需求编写自定义类型转换器。

2. SpringBoot定制化类型转换器

自定义类型转换器毫无疑问要通过SpringBoot定制化实现,通过上节的学习,
我们知道可以通过自定义WebMvcConfigurer的方法实现SpringMVC的定制化。

我们可以重写WebMvcConfigureraddFormatters方法来添加自定义类型转换器:

// org.springframework.web.servlet.config.annotation.WebMvcConfigurer.addFormatters
// WebMvcConfigurer.java Line:86~87

/**
 * Add {@link Converter Converters} and {@link Formatter Formatters} in addition to the ones
 * registered by default.
 * 
 * 添加类型转换器(Converter)和格式化器(Formatter)
 * 使用registry的addConverter方法添加类型转换器
 * 使用registry的addFormatter方法添加格式化器
 */
default void addFormatters(FormatterRegistry registry) {
   
}

3. 编写自定义类型转换器

我们可以通过编写自定义转换器类和使用lambda表达式的方式来编写自定义类型转换器。

3.1 编写自定义类型转换器类

  1. 自定义转换器类(实现Converter接口并重写convert方法):
public class StringToUserConverter implements Converter<String, User> {
   
    @Override
    public User convert(String source) {
   
        // TODO 在此处编写转换逻辑
    }
}
  1. 在配置类中创建自定义WebMvcConfigurer并重写addFormatters方法导入我们编写的类型转换器类:
@Configuration
public class SpringConfig {
   
    @Bean
    public WebMvcConfigurer webMvcConfig() {
   
        return new WebMvcConfigurer() {
   
            @Override
            public void addFormatters(FormatterRegistry registry) {
   
                registry.addConverter(new StringToUserConverter());
            }
        };
    }
}

3.2 使用匿名内部类或lambda表达式

匿名内部类:

@Configuration
public class SpringConfig {
   
    @Bean
    public WebMvcConfigurer webMvcConfig() {
   
        return new WebMvcConfigurer() {
   
            @Override
            public void addFormatters(FormatterRegistry registry) {
   
                registry.addConverter(new Converter<String, User>() {
   
                    @Override
                    public User convert(String source) {
   
                        // TODO 此处编写转换逻辑
                    }
                });
            }
        };
    }
}

lambda表达式:

@Configuration
public class SpringConfig {
   
    @Bean
    public WebMvcConfigurer webMvcConfig() {
   
        return new WebMvcConfigurer() {
   
            @Override
            public void addFormatters(FormatterRegistry registry) {
   
                registry.addConverter((Converter<String, User>) source -> {
   
                    // TODO 在此编写转换逻辑
                });
            }
        };
    }
}

4. 类型转换器原理&自定义POJO类型数据绑定原理

4.1 数据绑定原理(调试过程)

继续上节的学习,跟踪调试ModelAttributeMethodProcessor的resolveArgument方法:

// org.springframework.web.method.annotation.ModelAttributeMethodProcessor
// ModelAttributeMethodProcessor.java Line:119~186

@Override
@Nullable
public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
   

    Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
    Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");

    // 获取参数的名称(如果有@ModelAttribute注解的话使用注解内的名称,如果没有的话再去调用其他方法获取参数名)
    String name = ModelFactory.getNameForParameter(parameter);
    ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
    // 如果当前参数使用了@ModelAttribute注解,则直接绑定隐含模型中的对应数据
    if (ann != null) {
   
        mavContainer.setBinding(name, ann.binding())
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值