下面列出了怎么用com.fasterxml.jackson.databind.JavaType的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Determine whether to log the given exception coming from a {@link ObjectMapper#canDeserialize} /
* {@link ObjectMapper#canSerialize} check.
* @param type the class that Jackson tested for (de-)serializability
* @param cause the Jackson-thrown exception to evaluate (typically a {@link JsonMappingException})
* @since 4.3
*/
private void logWarningIfNecessary(Type type, @Nullable Throwable cause) {
if (cause == null) {
return;
}
// Do not log warning for serializer not found (note: different message wording on Jackson 2.9)
boolean debugLevel = cause instanceof JsonMappingException && cause.getMessage().startsWith("Cannot find");
if (debugLevel ? logger.isDebugEnabled() : logger.isWarnEnabled()) {
String msg = StrUtil.concat("Failed to evaluate Jackson ", type instanceof JavaType ? "de" : "", "serialization for type [", type
.toString(), "]");
if (debugLevel) {
logger.debug(msg, cause);
} else if (logger.isDebugEnabled()) {
logger.warn(msg, cause);
} else {
logger.warn(msg + ": " + cause);
}
}
}
private <R> JsonRpcResponse<R> responseFromStream(InputStream inputStream, JavaType responseType) throws IOException {
JsonRpcResponse<R> responseJson;
try {
if (log.isDebugEnabled()) {
// If logging enabled, copy InputStream to string and log
String responseBody = convertStreamToString(inputStream);
log.debug("Response Body: {}", responseBody);
responseJson = mapper.readValue(responseBody, responseType);
} else {
// Otherwise convert directly to responseType
responseJson = mapper.readValue(inputStream, responseType);
}
} catch (JsonProcessingException e) {
log.error("JsonProcessingException: {}", e);
// TODO: Map to some kind of JsonRPC exception similar to JsonRPCStatusException
throw e;
}
return responseJson;
}
/**
* Method called to see if type is one of core JDK types
* that we have cached for efficiency.
*/
protected BasicBeanDescription _findStdTypeDesc(JavaType type)
{
Class<?> cls = type.getRawClass();
if (cls.isPrimitive()) {
if (cls == Boolean.TYPE) {
return BOOLEAN_DESC;
}
if (cls == Integer.TYPE) {
return INT_DESC;
}
if (cls == Long.TYPE) {
return LONG_DESC;
}
} else {
if (cls == String.class) {
return STRING_DESC;
}
}
return null;
}
@Override
public Model resolve(JavaType type, ModelConverterContext context, Iterator<ModelConverter> next) {
// property is not a model
if (propertyCreatorMap.containsKey(type.getRawClass())) {
return null;
}
Model model = super.resolve(type, context, next);
if (model == null) {
return null;
}
checkType(type);
// 只有声明model的地方才需要标注类型
if (model instanceof ModelImpl && !StringUtils.isEmpty(((ModelImpl) model).getName())) {
setType(type, model.getVendorExtensions());
}
return model;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
JavaType returnType = mListener.getReturnType();
T returnData = null;
if (returnType != null) {
try {
if (response.data != null) {
returnData = OBJECT_MAPPER.readValue(response.data, returnType);
} else if (response instanceof JacksonNetworkResponse) {
returnData = OBJECT_MAPPER.readValue(((JacksonNetworkResponse)response).inputStream, returnType);
}
} catch (Exception e) {
VolleyLog.e(e, "An error occurred while parsing network response:");
return Response.error(new ParseError(response));
}
}
return mListener.onParseResponseComplete(Response.success(returnData, HttpHeaderParser.parseCacheHeaders(response)));
}
protected JavaType parseType(MyTokenizer tokens)
throws IllegalArgumentException
{
if (!tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected end-of-string");
}
Class<?> base = findClass(tokens.nextToken(), tokens);
// either end (ok, non generic type), or generics
if (tokens.hasMoreTokens()) {
String token = tokens.nextToken();
if ("<".equals(token)) {
List<JavaType> parameterTypes = parseTypes(tokens);
TypeBindings b = TypeBindings.create(base, parameterTypes);
return _factory._fromClass(null, base, b);
}
// can be comma that separates types, or closing '>'
tokens.pushBack(token);
}
return _factory._fromClass(null, base, TypeBindings.emptyBindings());
}
/**
* Returns true if the given type is an array or {@link Collection} of {@code SIMPLE_TYPES} or
* enums, or if the given type is a {@link ValueProvider ValueProvider<T>} and {@code T} is
* an array or {@link Collection} of {@code SIMPLE_TYPES} or enums.
*/
private static boolean isCollectionOrArrayOfAllowedTypes(Class<?> type, JavaType genericType) {
JavaType containerType =
type.equals(ValueProvider.class) ? genericType.containedType(0) : genericType;
// Check if it is an array of simple types or enum.
if (containerType.getRawClass().isArray()
&& (SIMPLE_TYPES.contains(containerType.getRawClass().getComponentType())
|| containerType.getRawClass().getComponentType().isEnum())) {
return true;
}
// Check if it is Collection of simple types or enum.
if (Collection.class.isAssignableFrom(containerType.getRawClass())) {
JavaType innerType = containerType.containedType(0);
// Note that raw types are allowed, hence the null check.
if (innerType == null
|| SIMPLE_TYPES.contains(innerType.getRawClass())
|| innerType.getRawClass().isEnum()) {
return true;
}
}
return false;
}
@Test
public void serderDocs1() throws IOException {
final JavaType type = JSONTestHelper.getMapper().getTypeFactory().constructType(AuthConfig.class);
final AuthConfig authConfig = testRoundTrip(RemoteApiVersion.VERSION_1_22,
"/other/AuthConfig/docs1.json",
type
);
assertThat(authConfig, notNullValue());
assertThat(authConfig.getUsername(), is("jdoe"));
assertThat(authConfig.getPassword(), is("secret"));
assertThat(authConfig.getEmail(), is("[email protected]"));
final AuthConfig authConfig1 = new AuthConfig().withUsername("jdoe")
.withPassword("secret")
.withEmail("[email protected]");
assertThat(authConfig1, equalTo(authConfig));
}
<T> Map<String, T> loadProps(Class<?> clazz, Function<KvProperty, T> func) {
ImmutableMap.Builder<String, T> b = ImmutableMap.builder();
TypeFactory tf = TypeFactory.defaultInstance();
while(clazz != null && !Object.class.equals(clazz)) {
for(Field field: clazz.getDeclaredFields()) {
KvMapping mapping = field.getAnnotation(KvMapping.class);
if(mapping == null) {
continue;
}
JavaType javaType;
String typeStr = mapping.type();
if(!typeStr.isEmpty()) {
javaType = tf.constructFromCanonical(typeStr);
} else {
javaType = tf.constructType(field.getGenericType());
}
KvProperty property = new KvProperty(this, field.getName(), field, javaType);
b.put(property.getKey(), func.apply(property));
}
clazz = clazz.getSuperclass();
}
return b.build();
}
@Test
public void testBackwardCompatibility() throws Exception
{
JsonInstanceSerializer<TestJsonInstanceSerializer.Payload> serializer = new JsonInstanceSerializer<TestJsonInstanceSerializer.Payload>(TestJsonInstanceSerializer.Payload.class, true, true);
ServiceInstance<TestJsonInstanceSerializer.Payload> instance = new ServiceInstance<TestJsonInstanceSerializer.Payload>("name", "id", "address", 10, 20, new TestJsonInstanceSerializer.Payload("test"), 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"), false);
byte[] bytes = serializer.serialize(instance);
instance = serializer.deserialize(bytes);
Assert.assertTrue(instance.isEnabled()); // passed false for enabled in the ctor but that is lost with compatibleSerializationMode
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory().constructType(OldServiceInstance.class);
OldServiceInstance rawServiceInstance = mapper.readValue(bytes, type);
TestJsonInstanceSerializer.Payload.class.cast(rawServiceInstance.getPayload()); // just to verify that it's the correct type
//noinspection unchecked
OldServiceInstance<TestJsonInstanceSerializer.Payload> check = (OldServiceInstance<TestJsonInstanceSerializer.Payload>)rawServiceInstance;
Assert.assertEquals(check.getName(), instance.getName());
Assert.assertEquals(check.getId(), instance.getId());
Assert.assertEquals(check.getAddress(), instance.getAddress());
Assert.assertEquals(check.getPort(), instance.getPort());
Assert.assertEquals(check.getSslPort(), instance.getSslPort());
Assert.assertEquals(check.getPayload(), instance.getPayload());
Assert.assertEquals(check.getRegistrationTimeUTC(), instance.getRegistrationTimeUTC());
Assert.assertEquals(check.getServiceType(), instance.getServiceType());
Assert.assertEquals(check.getUriSpec(), instance.getUriSpec());
}
@SuppressWarnings("unchecked")
protected <T> List<T> readList(String key, Class<T> clazz,
String content) {
ObjectMapper mapper = this.client.mapper();
try {
JsonNode root = mapper.readTree(content);
JsonNode element = root.get(key);
if(element == null) {
throw new SerializeException(
"Can't find value of the key: %s in json.", key);
} else {
JavaType t = mapper.getTypeFactory()
.constructParametricType(List.class, clazz);
return (List<T>) mapper.readValue(element.toString(), t);
}
} catch (IOException e) {
throw new SerializeException(
"Failed to deserialize %s", e, content);
}
}
/**
* Method for constructing a {@link CollectionType}.
*<p>
* NOTE: type modifiers are NOT called on Collection type itself; but are called
* for contained types.
*/
public CollectionType constructCollectionType(Class<? extends Collection> collectionClass,
JavaType elementType)
{
TypeBindings bindings = TypeBindings.createIfNeeded(collectionClass, elementType);
CollectionType result = (CollectionType) _fromClass(null, collectionClass, bindings);
// 17-May-2017, tatu: As per [databind#1415], we better verify bound values if (but only if)
// type being resolved was non-generic (i.e.element type was ignored)
if (bindings.isEmpty() && (elementType != null)) {
JavaType t = result.findSuperType(Collection.class);
JavaType realET = t.getContentType();
if (!realET.equals(elementType)) {
throw new IllegalArgumentException(String.format(
"Non-generic Collection class %s did not resolve to something with element type %s but %s ",
ClassUtil.nameOf(collectionClass), elementType, realET));
}
}
return result;
}
@Test
public void testSerDer1() throws Exception {
final JavaType type = JSONTestHelper.getMapper().getTypeFactory().constructType(Version.class);
final Version version = testRoundTrip(RemoteApiVersion.VERSION_1_22,
"/version/1.json",
type
);
assertThat(version, notNullValue());
assertThat(version.getVersion(), is("1.10.1"));
assertThat(version.getApiVersion(), is("1.22"));
assertThat(version.getGitCommit(), is("9e83765"));
assertThat(version.getGoVersion(), is("go1.5.3"));
assertThat(version.getOperatingSystem(), is("linux"));
assertThat(version.getArch(), is("amd64"));
assertThat(version.getKernelVersion(), is("4.1.17-boot2docker"));
assertThat(version.getBuildTime(), is("2016-02-11T20:39:58.688092588+00:00"));
}
/**
* 反序列化复杂Collection如List<Bean>, 先使用createCollectionType()或contructMapType()构造类型, 然后调用本函数.
*
* @see #createCollectionType(Class, Class...)
*/
public <T> T fromJson(String jsonString, JavaType javaType) {
if (StringUtils.isEmpty(jsonString)) {
return null;
}
try {
return (T) mapper.readValue(jsonString, javaType);
} catch (IOException e) {
logger.warn("parse json string error:" + jsonString, e);
return null;
}
}
private ConvertingDeserializer(AnnotatedType detectedType, JavaType substituteType, InputConverter inputConverter, GlobalEnvironment environment, ObjectMapper objectMapper) {
this.detectedType = detectedType;
this.substituteType = substituteType;
this.inputConverter = inputConverter;
this.environment = environment;
this.valueMapper = new JacksonValueMapper(objectMapper);
this.objectMapper = objectMapper;
}
@Override
public Either<?,?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonDeserializer ser = ctxt.findRootValueDeserializer(ctxt.getTypeFactory().constructSimpleType(EitherBean.class, new JavaType[0]));
EitherBean x = (EitherBean)ser.deserialize(p, ctxt);
if(x.left!=null){
return Either.left(x.left);
}
return Either.right(x.right);
}
@Override
@SuppressWarnings("deprecation")
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, Object conversionHint) {
JavaType javaType = this.objectMapper.constructType(targetClass);
Object payload = message.getPayload();
Class<?> view = getSerializationView(conversionHint);
// Note: in the view case, calling withType instead of forType for compatibility with Jackson <2.5
try {
if (payload instanceof byte[]) {
if (view != null) {
return this.objectMapper.readerWithView(view).withType(javaType).readValue((byte[]) payload);
}
else {
return this.objectMapper.readValue((byte[]) payload, javaType);
}
}
else {
if (view != null) {
return this.objectMapper.readerWithView(view).withType(javaType).readValue(payload.toString());
}
else {
return this.objectMapper.readValue(payload.toString(), javaType);
}
}
}
catch (IOException ex) {
throw new MessageConversionException(message, "Could not read JSON: " + ex.getMessage(), ex);
}
}
private ServerInstance convert(ServiceInstance instance) {
try {
ServerInstance si = new ServerInstance(instance.getServiceName());
si.setHost(instance.getHost());
si.setPort(instance.getPort());
si.setProtocol(instance.getProtocol());
si.setVersion(instance.getVersion());
si.setRoom(instance.getRoom());
si.setStartTimestamp(instance.getStartTime().getTime());
si.setInstanceId(instance.getInstanceId());
si.setWarmupSeconds(instance.getWarmupSeconds());
si.setWeight(instance.getWeight());
si.setGroup(instance.getGroup());
si.setIsAlive(instance.getStatus() == 1);
if (StringUtils.isNotEmpty(instance.getProps())) {
Map<String, String> propMap = new HashMap<>();
JavaType listType = JsonTools.NON_NULL.buildCollectionType(List.class, Map.class);
List<Map<String, String>> propMapList = JsonTools.NON_NULL.fromJson(instance.getProps(), listType);
for (Map<String, String> map : propMapList) {
propMap.put(map.get("key"), map.get("value"));
}
si.setProps(propMap);
}
si.ready();
return si;
} catch (Exception ex) {
log.error("转换服务实例数据失败:{},instance:{}", ex.getMessage(), instance, ex);
return null;
}
}
@Test
public void testAfterReceiveResponseNormal(@Mocked Invocation invocation,
@Mocked HttpServletResponseEx responseEx,
@Mocked Buffer bodyBuffer,
@Mocked OperationMeta operationMeta,
@Mocked RestOperationMeta swaggerRestOperation,
@Mocked ProduceProcessor produceProcessor) throws Exception {
MultiMap responseHeader = new CaseInsensitiveHeaders();
responseHeader.add("b", "bValue");
Object decodedResult = new Object();
new Expectations() {
{
responseEx.getHeader(HttpHeaders.CONTENT_TYPE);
result = "json";
responseEx.getHeaderNames();
result = Arrays.asList("a", "b");
responseEx.getHeaders("b");
result = responseHeader.getAll("b");
swaggerRestOperation.findProduceProcessor("json");
result = produceProcessor;
produceProcessor.decodeResponse(bodyBuffer, (JavaType) any);
result = decodedResult;
invocation.getOperationMeta();
result = operationMeta;
operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
result = swaggerRestOperation;
responseEx.getStatusType();
result = Status.OK;
}
};
Response response = filter.afterReceiveResponse(invocation, responseEx);
Assert.assertSame(decodedResult, response.getResult());
Assert.assertEquals(1, response.getHeaders().getHeaderMap().size());
Assert.assertEquals(response.getHeaders().getHeader("b"), Arrays.asList("bValue"));
}
@Override
public Object[] deepCloneMethodArgs(Method method, Object[] args) throws Exception {
if (null == args || args.length == 0) {
return args;
}
Type[] genericParameterTypes = method.getGenericParameterTypes();
if (args.length != genericParameterTypes.length) {
throw new Exception("the length of " + method.getDeclaringClass().getName() + "." + method.getName()
+ " must " + genericParameterTypes.length);
}
Class<?> clazz = args.getClass();
Object[] res = ((Object) clazz == (Object) Object[].class) ? (Object[]) new Object[args.length]
: (Object[]) Array.newInstance(clazz.getComponentType(), args.length);
int len = genericParameterTypes.length;
for (int i = 0; i < len; i++) {
Type genericParameterType = genericParameterTypes[i];
Object obj = args[i];
if (genericParameterType instanceof ParameterizedType) {
byte[] tmp = MAPPER.writeValueAsBytes(obj);
JavaType javaType = MAPPER.getTypeFactory().constructType(genericParameterType);
res[i] = MAPPER.readValue(tmp, javaType);
} else {
res[i] = deepClone(obj, null);
}
}
return res;
}
private byte[] buildAbstractBase(JavaType javaType, String className) {
DynamicType.Builder<?> builder =
new ByteBuddy()
//needed because className will contain the 'abstract' Java keyword
.with(TypeValidation.DISABLED)
.subclass(createTypeDefinitionFromJavaType(javaType))
.name(className)
.modifiers(Visibility.PUBLIC, TypeManifestation.ABSTRACT);
if (javaType.isInterface()) {
builder = ByteBuddyBuilderUtil.createEqualsAndHashCode(builder);
}
return builder.make().getBytes();
}
public static <T> T fromJson(Reader reader, JavaType type) {
try {
return sMapper.readValue(reader, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private <T> T handleSuccess(JavaType javaType, HttpURLConnection conn, int responseCode) throws IOException {
if (shouldSkipResponseEntity(javaType, conn, responseCode)) {
return null;
} else {
return readEntity(conn, responseCode, javaType);
}
}
@Override
public BasicBeanDescription forDirectClassAnnotations(MapperConfig<?> config,
JavaType type, MixInResolver r)
{
BasicBeanDescription desc = _findStdTypeDesc(type);
if (desc == null) {
desc = BasicBeanDescription.forOtherUse(config, type,
_resolveAnnotatedWithoutSuperTypes(config, type, r));
}
return desc;
}
protected JavaType _resolveSuperClass(ClassStack context, Class<?> rawType, TypeBindings parentBindings)
{
Type parent = ClassUtil.getGenericSuperclass(rawType);
if (parent == null) {
return null;
}
return _fromAny(context, parent, parentBindings);
}
@Override
public JavaType getSuperClass() {
if (_referencedType != null) {
return _referencedType.getSuperClass();
}
return super.getSuperClass();
}
private Object readObject(JavaType type, JsonNode value, String key)
{
try {
return mapper.readValue(value.traverse(), type);
}
catch (Exception ex) {
throw propagateConvertException(ex, typeNameOf(type), value, key);
}
}
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
JavaType javaType = getJavaType(clazz, null);
return readJavaType(javaType, inputMessage);
}
/**
* Prepare and throw JsonRPCStatusException with all relevant info
* @param responseCode Non-success response code
* @param connection the current connection
* @throws IOException IO Error
* @throws JsonRpcStatusException An exception containing the HTTP status code and a message
*/
private void handleBadResponseCode(int responseCode, HttpURLConnection connection) throws IOException, JsonRpcStatusException
{
String responseMessage = connection.getResponseMessage();
String exceptionMessage = responseMessage;
int jsonRpcCode = 0;
JsonRpcResponse bodyJson = null; // Body as JSON if available
String bodyString = null; // Body as String if not JSON
InputStream errorStream = connection.getErrorStream();
if (errorStream != null) {
if (connection.getContentType().equals("application/json")) {
JavaType genericResponseType = mapper.getTypeFactory().
constructParametricType(JsonRpcResponse.class, JsonNode.class);
// We got a JSON error response -- try to parse it as a JsonRpcResponse
bodyJson = responseFromStream(errorStream, genericResponseType);
JsonRpcError error = bodyJson.getError();
if (error != null) {
// If there's a more specific message in the JSON use it instead.
exceptionMessage = error.getMessage();
jsonRpcCode = error.getCode();
// Since this is an error at the JSON level, let's log it with `info` level and
// let the higher-level software decide whether to log it as `error` or not.
// i.e. The higher-level software can set error level on this module to `warn` and then
// decide whether to log this "error" not based upon the JsonRpcStatusException thrown.
// An example occurs in Bitcoin when a client is waiting for a server to initialize
// and returns 'Still scanning.. at block 530006 of 548850'
log.info("json error code: {}, message: {}", jsonRpcCode, exceptionMessage);
}
} else {
// No JSON, read response body as string
bodyString = convertStreamToString(errorStream);
log.error("error string: {}", bodyString);
errorStream.close();
}
}
throw new JsonRpcStatusException(exceptionMessage, responseCode, responseMessage, jsonRpcCode, bodyString, bodyJson);
}
public static <T> T constructEnumArrayClass(JavaType javaType) {
if (javaType.isArrayType()) {
return ReflectUtils.constructArrayType(javaType.getContentType().getRawClass());
}
return ReflectUtils.constructArrayType(Object.class);
}