欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot 自定义转换器(converter)

程序员文章站 2024-01-17 14:24:28
springboot自定义转换器(converter)应用:实现一对一转换,如将字符串转换为pojo、枚举等***********************相关类与接口Converter@FunctionalInterfacepublic interface Converter {@NullableT convert(S source); //将类型S的对象转换为类型T的对象}......

springboot 自定义转换器(converter)

 

应用:实现一对一转换,如将字符串转换为pojo、枚举等

 

 

***********************

相关类与接口

 

Converter

@FunctionalInterface
public interface Converter<S, T> {

	@Nullable
	T convert(S source);  //将类型S的对象转换为类型T的对象

}

 

ConverterFactory

public interface ConverterFactory<S, R> {

	<T extends R> Converter<S, T> getConverter(Class<T> targetType);

}

 

 

********************

部分内置converter、converterFactory

 

EnumToStringConverter:将枚举字面量转换为字符串

final class EnumToStringConverter extends AbstractConditionalEnumConverter implements Converter<Enum<?>, String> {

	public EnumToStringConverter(ConversionService conversionService) {
		super(conversionService);
	}

	@Override
	public String convert(Enum<?> source) {
		return source.name();
	}

}

 

StringToNumerConverterFactory:字符串转换为数字

final class StringToNumberConverterFactory implements ConverterFactory<String, Number> {

	@Override
	public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {
		return new StringToNumber<>(targetType);
	}


	private static final class StringToNumber<T extends Number> implements Converter<String, T> {

		private final Class<T> targetType;

		public StringToNumber(Class<T> targetType) {
			this.targetType = targetType;
		}

		@Override
		public T convert(String source) {
			if (source.isEmpty()) {
				return null;
			}
			return NumberUtils.parseNumber(source, this.targetType);
		}
	}

}

 

StringToEnumConverterFactory:根据枚举字面量将字符串转换为枚举对象

final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {

	@Override
	public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
		return new StringToEnum(ConversionUtils.getEnumType(targetType));
	}


	private static class StringToEnum<T extends Enum> implements Converter<String, T> {

		private final Class<T> enumType;

		public StringToEnum(Class<T> enumType) {
			this.enumType = enumType;
		}

		@Override
		public T convert(String source) {  //根据枚举的字面量进行转换
			if (source.isEmpty()) {
				// It's an empty enum identifier: reset the enum value to null.
				return null;
			}
			return (T) Enum.valueOf(this.enumType, source.trim());
		}
	}

}

 

 

***********************

示例:自定义枚举转换器,根据枚举属性进行转换

 

********************

myenum 层

 

Sex

public enum Sex {

    Male(1,"男"),Female(2,"女");

    private Integer id;
    private String name;

    Sex(Integer id,String name){
        this.id=id;
        this.name=name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Sex{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

 

********************

pojo 层

 

Person

@Data
public class Person {

    private String name;
    private Integer age;
    private Sex sex;
}

 

********************

config 层

 

StringToEnumConverter:根据属性name将字符串转换为枚举对象

@Component
public class StringToEnumConverter implements Converter<String, Sex> {

    @Override
    public Sex convert(String source) {
        Sex sex=Sex.Male;
        if ("女".equals(source)){
            sex=Sex.Female;
        }

        return sex;
    }
}

说明:将转换器注册为容器bean后,可自动注册,不需要使用WebMvcConfigurer

 

WebConfig:注册converter

@Component
public class WebConfig implements WebMvcConfigurer {

    @Resource
    private StringToEnumConverter stringToEnumConverter;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(stringToEnumConverter);
    }
}

 

********************

controller 层

 

HelloController

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(Sex sex){
        System.out.println(sex);

        return "success";

    }

    @RequestMapping("/hello2")
    public String hello2(Person person){
        System.out.println(person);

        return "success";
    }
}

 

 

***********************

默认枚举转换器测试

 

localhost:8080/hello?sex=Male

2020-07-11 10:09:53.896  INFO 6652 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-07-11 10:09:53.908  INFO 6652 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 12 ms
Sex{id=1, name='男'}

 

localhost:8080/hello?sex=男

2020-07-11 10:08:33.021  INFO 14848 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
2020-07-11 10:08:33.056  WARN 14848 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'com.example.demo.myenum.Sex'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [com.example.demo.myenum.Sex] for value '男'; nested exception is java.lang.IllegalArgumentException: No enum constant com.example.demo.myenum.Sex.男]

 说明:默认的枚举转换器根据字面量进行转换,使用属性转换会报错

 

 

***********************

自定义枚举转换器测试

 

localhost:8080/hello?sex=女

2020-07-11 10:00:03.110  INFO 13032 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-07-11 10:00:03.119  INFO 13032 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
Sex{id=2, name='女'}

 

localhost:8080/hello2?name=瓜田李下&age=20&sex=女

Person(name=瓜田李下, age=20, sex=Sex{id=2, name='女'})

说明:自定义枚举转换器生效,可根据枚举属性进行转换

 

 

本文地址:https://blog.csdn.net/weixin_43931625/article/details/107279831