当前位置: 移动技术网 > IT编程>开发语言>Java > springboot 自定义转换器(converter)

springboot 自定义转换器(converter)

2020年07月12日  | 移动技术网IT编程  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网