1. 将带有泛型的对象进行反序列化
借助的是com.fasterxml.jackson.core.type.TypeReference
对象,本质是使用匿名内部类来得到泛型对象。
public static void main(String[] args) {
List<Long> arrs = new ArrayList<>();
arrs.add(1L);
arrs.add(2L);
arrs.add(3L);
//获取字符串
String str = JSON.toJSONString(arrs);
List<Long> list = parseObject(str, new com.fasterxml.jackson.core.type.TypeReference<List<Long>>() {
});
System.out.println(list);
}
/**
* 带有泛型的反序列化。
*/
private static <T> T parseObject(String str, TypeReference<T> type) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(str, type);
} catch (Exception e) {
log.error("反序列化失败", e);
throw new RuntimeException(e);
}
}
2. Type转化为jackson的JavaType类型
当我们定义AspectJ或者实现HandlerMethodArgumentResolver
接口时,需要将Json串反序列化为具体的对象,如何保留对象的泛型呢?
借鉴源码:org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.getJavaType
@Slf4j
public class JsonParamAnnotationResolver implements HandlerMethodArgumentResolver {
private static ObjectMapper objectMapper = new ObjectMapper();
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonParam.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
JsonParam jsonParam = parameter.getParameterAnnotation(JsonParam.class);
//拿到参数。读取请求对象的流
Object param = CommonWebScope.getJsonParam(jsonParam.value());
// 传入type和contextClass对象,得到JavaType
//org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.getJavaType 源码。
JavaType javaType =
getJavaType(parameter.getGenericParameterType(), parameter.getContainingClass());
//Jackson+JavaType下支持泛型的返回。
return ObjectMapperUtils.value(param, javaType);
}
/**
* 将{@link java.lang.reflect.Type} 转化为Jackson需要的{com.fasterxml.jackson.databind.JavaType}
*/
public static JavaType getJavaType(Type type, Class<?> contextClass) {
//MAPPER这个可以使用ObjectMapperUtils中ObjectMapper
TypeFactory typeFactory = objectMapper.getTypeFactory();
//这种是处理public <T extends User> T testEnvV3(@JsonParam("users") List<T> user) 这种类型。
return typeFactory.constructType(GenericTypeResolver.resolveType(type, contextClass));
}
/**
* 将Object对象转换为具体的对象类型(支持泛型)
*/
public static <T> T value(Object rawValue, JavaType javaType) {
return objectMapper.convertValue(rawValue, javaType);
}
}