Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.support.json;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.integration.message.AdviceMessage;
import org.springframework.integration.support.MutableMessage;
import org.springframework.messaging.support.ErrorMessage;
import org.springframework.messaging.support.GenericMessage;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* Utility methods for Jackson.
*
* @author Artem Bilan
* @author Gary Russell
*
* @since 3.0
*
*/
public final class JacksonJsonUtils {
private JacksonJsonUtils() {
super();
}
/**
* Return an {@link ObjectMapper} if available,
* supplied with Message specific serializers and deserializers.
* Also configured to store typo info in the {@code @class} property.
* @param trustedPackages the trusted Java packages for deserialization.
* @return the mapper.
* @throws IllegalStateException if an implementation is not available.
* @since 4.3.10
*/
public static ObjectMapper messagingAwareMapper(String... trustedPackages) {
if (JacksonPresent.isJackson2Present()) {
ObjectMapper mapper = new Jackson2JsonObjectMapper().getObjectMapper();
mapper.setDefaultTyping(new WhitelistTypeResolverBuilder(trustedPackages));
GenericMessageJacksonDeserializer genericMessageDeserializer = new GenericMessageJacksonDeserializer();
genericMessageDeserializer.setMapper(mapper);
ErrorMessageJacksonDeserializer errorMessageDeserializer = new ErrorMessageJacksonDeserializer();
errorMessageDeserializer.setMapper(mapper);
AdviceMessageJacksonDeserializer adviceMessageDeserializer = new AdviceMessageJacksonDeserializer();
adviceMessageDeserializer.setMapper(mapper);
MutableMessageJacksonDeserializer mutableMessageDeserializer = new MutableMessageJacksonDeserializer();
mutableMessageDeserializer.setMapper(mapper);
SimpleModule simpleModule = new SimpleModule()
.addSerializer(new MessageHeadersJacksonSerializer())
.addDeserializer(GenericMessage.class, genericMessageDeserializer)
.addDeserializer(ErrorMessage.class, errorMessageDeserializer)
.addDeserializer(AdviceMessage.class, adviceMessageDeserializer)
.addDeserializer(MutableMessage.class, mutableMessageDeserializer);
mapper.registerModule(simpleModule);
return mapper;
}
else {
throw new IllegalStateException("No jackson-databind.jar is present in the classpath.");
}
}
/**
* An implementation of {@link ObjectMapper.DefaultTypeResolverBuilder}
* that wraps a default {@link TypeIdResolver} to the {@link WhitelistTypeIdResolver}.
*
* @author Rob Winch
* @author Artem Bilan
* @author Filip Hanik
* @author Gary Russell
*
* @since 4.3.11
*/
private static final class WhitelistTypeResolverBuilder extends ObjectMapper.DefaultTypeResolverBuilder {
private static final long serialVersionUID = 1L;
private final String[] trustedPackages;
WhitelistTypeResolverBuilder(String... trustedPackages) {
super(ObjectMapper.DefaultTyping.NON_FINAL,
//we do explicit validation in the TypeIdResolver
BasicPolymorphicTypeValidator.builder()
.allowIfSubType(Object.class)
.build());
this.trustedPackages =
trustedPackages != null ? Arrays.copyOf(trustedPackages, trustedPackages.length) : null;
init(JsonTypeInfo.Id.CLASS, null)
.inclusion(JsonTypeInfo.As.PROPERTY);
}
@Override
protected TypeIdResolver idResolver(MapperConfig config,
JavaType baseType,
PolymorphicTypeValidator subtypeValidator,
Collection subtypes, boolean forSer, boolean forDeser) {
TypeIdResolver result = super.idResolver(config, baseType, subtypeValidator, subtypes, forSer, forDeser);
return new WhitelistTypeIdResolver(result, this.trustedPackages);
}
}
/**
* A {@link TypeIdResolver} that delegates to an existing implementation
* and throws an IllegalStateException if the class being looked up is not whitelisted,
* does not provide an explicit mixin mappings.
*
* @author Rob Winch
* @author Artem Bilan
*
* @since 4.3.11
*/
private static final class WhitelistTypeIdResolver implements TypeIdResolver {
private static final List TRUSTED_PACKAGES =
Arrays.asList(
"java.util",
"java.lang",
"org.springframework.messaging.support",
"org.springframework.integration.support",
"org.springframework.integration.message",
"org.springframework.integration.store"
);
private final TypeIdResolver delegate;
private final Set trustedPackages = new LinkedHashSet<>(TRUSTED_PACKAGES);
WhitelistTypeIdResolver(TypeIdResolver delegate, String... trustedPackages) {
this.delegate = delegate;
if (trustedPackages != null) {
for (String whiteListClass : trustedPackages) {
if ("*".equals(whiteListClass)) {
this.trustedPackages.clear();
break;
}
else {
this.trustedPackages.add(whiteListClass);
}
}
}
}
@Override
public void init(JavaType baseType) {
this.delegate.init(baseType);
}
@Override
public String idFromValue(Object value) {
return this.delegate.idFromValue(value);
}
@Override
public String idFromValueAndType(Object value, Class suggestedType) {
return this.delegate.idFromValueAndType(value, suggestedType);
}
@Override
public String idFromBaseType() {
return this.delegate.idFromBaseType();
}
@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
DeserializationConfig config = (DeserializationConfig) context.getConfig();
JavaType result = this.delegate.typeFromId(context, id);
Package aPackage = result.getRawClass().getPackage();
if (aPackage == null || isTrustedPackage(aPackage.getName())) {
return result;
}
boolean isExplicitMixin = config.findMixInClassFor(result.getRawClass()) != null;
if (isExplicitMixin) {
return result;
}
throw new IllegalArgumentException("The class with " + id + " and name of " +
"" + result.getRawClass().getName() + " is not in the trusted packages: " +
"" + this.trustedPackages + ". " +
"If you believe this class is safe to deserialize, please provide its name or an explicit Mixin. " +
"If the serialization is only done by a trusted source, you can also enable default typing.");
}
private boolean isTrustedPackage(String packageName) {
if (!this.trustedPackages.isEmpty()) {
for (String trustedPackage : this.trustedPackages) {
if (packageName.equals(trustedPackage) || packageName.startsWith(trustedPackage + ".")) {
return true;
}
}
return false;
}
return true;
}
@Override
public String getDescForKnownTypeIds() {
return this.delegate.getDescForKnownTypeIds();
}
@Override
public JsonTypeInfo.Id getMechanism() {
return this.delegate.getMechanism();
}
}
}