表单类型参数
有时候需要将前台传来一些特定格式的数据对象转化成特定的Java对象,这个时候类型转换器就派上用场了。这里简单介绍使用比较简单的Converter接口。Converter是Spring 3.0后的一个函数式接口,只有一个方法,将source转化成target。
首先需要定义自己的转换器,需要实现Converter<S,T>接口,convert就是具体的转换方法。
一般推荐使用ConditionalGenericConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import java.util.Set; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.stereotype.Component;
public class CustomConditionalConverter implements ConditionalGenericConverter {
@Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return targetType.hasAnnotation(Key.class); }
@Override public Set<ConvertiblePair> getConvertibleTypes() { // getConvertibleTypes方法返回可转换的源类型和目标类型的配对, // 如果只关心,字符串类型的转换。 // return Collections.singleton(new ConvertiblePair(String.class, String.class));
// 如果全部都关注 return null; }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Key annotation = targetType.getAnnotation(Key.class); try { return annotation.using().newInstance().convert(source); } catch (Exception e) { throw new RuntimeException(e); } } }
|
然后需要将自定义的转换器进行注册:
1 2 3 4 5 6 7 8
| @Configuration public class CustomWebMvcConfig extends WebMvcConfigurerAdapter{ @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new CustomConditionalConverter()); } }
|
1 2 3 4 5 6 7 8 9 10
| import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Key { Class<? extends Convert> using(); }
|
1 2 3
| public abstract class Convert<T, P> { abstract P convert(T t); }
|
JSON类型参数
1 2 3 4 5 6 7 8 9 10 11
| import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.Data;
@Data public class TestReq {
@JsonDeserialize(using = DateDeserializer.class) private Integer createTime;
private String value; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Locale;
public class DateDeserializer extends JsonDeserializer<Integer> {
@Override public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException { String dateStr = parser.getValueAsString(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA); LocalDateTime parse = LocalDateTime.parse(dateStr, formatter); long epochSecond = parse.toEpochSecond(ZoneOffset.ofHours(8)); return (int)epochSecond; } }
|
- 表单类型:通过继承
Converter配置自定义参数转换器。
- JSON类型:配置自定义的Jackson反序列化器。