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

See gh-16268
pull/16472/head
Stephane Nicoll 6 years ago
parent c2f9e7dd43
commit e57c0c0657

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

@ -16,12 +16,16 @@
package org.springframework.boot.autoconfigure.jersey; 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.glassfish.jersey.server.ResourceConfig;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
import org.springframework.boot.logging.LogLevel; 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.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; 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 @Configuration
static class ResourceConfigConfiguration { static class ResourceConfigConfiguration {

Loading…
Cancel
Save