Do not attempt to add Jaxb customization if Jaxb is not present

See gh-16268
This commit is contained in:
Stephane Nicoll 2019-03-25 15:29:44 +01:00
parent c2f9e7dd43
commit e57c0c0657
2 changed files with 54 additions and 13 deletions

View File

@ -25,6 +25,7 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.ws.rs.ext.ContextResolver;
import javax.xml.bind.annotation.XmlElement;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -39,6 +40,7 @@ import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.servlet.ServletProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
@ -201,17 +203,14 @@ public class JerseyAutoConfiguration implements ServletContextAware {
}
@Configuration
@ConditionalOnClass(JacksonFeature.class)
@ConditionalOnSingleCandidate(ObjectMapper.class)
@Configuration
static class JacksonResourceConfigCustomizer {
private static final String JAXB_ANNOTATION_INTROSPECTOR_CLASS_NAME = "com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector";
@Bean
public ResourceConfigCustomizer resourceConfigCustomizer(
final ObjectMapper objectMapper) {
addJaxbAnnotationIntrospectorIfPresent(objectMapper);
return (ResourceConfig config) -> {
config.register(JacksonFeature.class);
config.register(new ObjectMapperContextResolver(objectMapper),
@ -219,16 +218,12 @@ public class JerseyAutoConfiguration implements ServletContextAware {
};
}
private void addJaxbAnnotationIntrospectorIfPresent(ObjectMapper objectMapper) {
if (ClassUtils.isPresent(JAXB_ANNOTATION_INTROSPECTOR_CLASS_NAME,
getClass().getClassLoader())) {
new ObjectMapperCustomizer().addJaxbAnnotationIntrospector(objectMapper);
}
}
@Configuration
@ConditionalOnClass({ JaxbAnnotationIntrospector.class, XmlElement.class })
static class JaxbObjectMapperCustomizer {
private static final class ObjectMapperCustomizer {
private void addJaxbAnnotationIntrospector(ObjectMapper objectMapper) {
@Autowired
public void addJaxbAnnotationIntrospector(ObjectMapper objectMapper) {
JaxbAnnotationIntrospector jaxbAnnotationIntrospector = new JaxbAnnotationIntrospector(
objectMapper.getTypeFactory());
objectMapper.setAnnotationIntrospectors(

View File

@ -16,12 +16,16 @@
package org.springframework.boot.autoconfigure.jersey;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@ -72,6 +76,48 @@ public class JerseyAutoConfigurationTests {
});
}
@Test
public void whenJaxbIsAvailableTheObjectMapperIsCustomizedWithAnAnnotationIntrospector() {
this.contextRunner
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
.run((context) -> {
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
assertThat(objectMapper.getSerializationConfig()
.getAnnotationIntrospector().allIntrospectors().stream()
.filter(JaxbAnnotationIntrospector.class::isInstance))
.hasSize(1);
});
}
@Test
public void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() {
this.contextRunner
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
.withClassLoader(new FilteredClassLoader("javax.xml.bind.annotation"))
.run((context) -> {
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
assertThat(objectMapper.getSerializationConfig()
.getAnnotationIntrospector().allIntrospectors().stream()
.filter(JaxbAnnotationIntrospector.class::isInstance))
.isEmpty();
});
}
@Test
public void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() {
this.contextRunner
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
.withClassLoader(
new FilteredClassLoader(JaxbAnnotationIntrospector.class))
.run((context) -> {
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
assertThat(objectMapper.getSerializationConfig()
.getAnnotationIntrospector().allIntrospectors().stream()
.filter(JaxbAnnotationIntrospector.class::isInstance))
.isEmpty();
});
}
@Configuration
static class ResourceConfigConfiguration {