Restore support for Jersey
Closes gh-28637
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import com.fasterxml.jackson.databind.AnnotationIntrospector;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.cfg.MapperConfig;
|
||||
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRegistration;
|
||||
import jakarta.ws.rs.ext.ContextResolver;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.spring.SpringComponentProvider;
|
||||
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.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.DynamicRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.WebApplicationInitializer;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.filter.RequestContextFilter;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Jersey.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Andy Wilkinson
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@AutoConfiguration(before = DispatcherServletAutoConfiguration.class, after = JacksonAutoConfiguration.class)
|
||||
@ConditionalOnClass({ SpringComponentProvider.class, ServletRegistration.class })
|
||||
@ConditionalOnBean(type = "org.glassfish.jersey.server.ResourceConfig")
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
public class JerseyAutoConfiguration implements ServletContextAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JerseyAutoConfiguration.class);
|
||||
|
||||
private final JerseyProperties jersey;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
public JerseyAutoConfiguration(JerseyProperties jersey, ResourceConfig config,
|
||||
ObjectProvider<ResourceConfigCustomizer> customizers) {
|
||||
this.jersey = jersey;
|
||||
this.config = config;
|
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(this.config));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingFilterBean(RequestContextFilter.class)
|
||||
public FilterRegistrationBean<RequestContextFilter> requestContextFilter() {
|
||||
FilterRegistrationBean<RequestContextFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new RequestContextFilter());
|
||||
registration.setOrder(this.jersey.getFilter().getOrder() - 1);
|
||||
registration.setName("requestContextFilter");
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JerseyApplicationPath jerseyApplicationPath() {
|
||||
return new DefaultJerseyApplicationPath(this.jersey.getApplicationPath(), this.config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jerseyFilterRegistration")
|
||||
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter")
|
||||
public FilterRegistrationBean<ServletContainer> jerseyFilterRegistration(JerseyApplicationPath applicationPath) {
|
||||
FilterRegistrationBean<ServletContainer> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new ServletContainer(this.config));
|
||||
registration.setUrlPatterns(Collections.singletonList(applicationPath.getUrlMapping()));
|
||||
registration.setOrder(this.jersey.getFilter().getOrder());
|
||||
registration.addInitParameter(ServletProperties.FILTER_CONTEXT_PATH, stripPattern(applicationPath.getPath()));
|
||||
addInitParameters(registration);
|
||||
registration.setName("jerseyFilter");
|
||||
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
|
||||
return registration;
|
||||
}
|
||||
|
||||
private String stripPattern(String path) {
|
||||
if (path.endsWith("/*")) {
|
||||
path = path.substring(0, path.lastIndexOf("/*"));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jerseyServletRegistration")
|
||||
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true)
|
||||
public ServletRegistrationBean<ServletContainer> jerseyServletRegistration(JerseyApplicationPath applicationPath) {
|
||||
ServletRegistrationBean<ServletContainer> registration = new ServletRegistrationBean<>(
|
||||
new ServletContainer(this.config), applicationPath.getUrlMapping());
|
||||
addInitParameters(registration);
|
||||
registration.setName(getServletRegistrationName());
|
||||
registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup());
|
||||
return registration;
|
||||
}
|
||||
|
||||
private String getServletRegistrationName() {
|
||||
return ClassUtils.getUserClass(this.config.getClass()).getName();
|
||||
}
|
||||
|
||||
private void addInitParameters(DynamicRegistrationBean<?> registration) {
|
||||
this.jersey.getInit().forEach(registration::addInitParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
String servletRegistrationName = getServletRegistrationName();
|
||||
ServletRegistration registration = servletContext.getServletRegistration(servletRegistrationName);
|
||||
if (registration != null) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Configuring existing registration for Jersey servlet '" + servletRegistrationName + "'");
|
||||
}
|
||||
registration.setInitParameters(this.jersey.getInit());
|
||||
}
|
||||
}
|
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public static final class JerseyWebApplicationInitializer implements WebApplicationInitializer {
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
// We need to switch *off* the Jersey WebApplicationInitializer because it
|
||||
// will try and register a ContextLoaderListener which we don't need
|
||||
servletContext.setInitParameter("contextConfigLocation", "<NONE>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(JacksonFeature.class)
|
||||
@ConditionalOnSingleCandidate(ObjectMapper.class)
|
||||
static class JacksonResourceConfigCustomizer {
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer resourceConfigCustomizer(final ObjectMapper objectMapper) {
|
||||
return (ResourceConfig config) -> {
|
||||
config.register(JacksonFeature.class);
|
||||
config.register(new ObjectMapperContextResolver(objectMapper), ContextResolver.class);
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ JakartaXmlBindAnnotationIntrospector.class, XmlElement.class })
|
||||
static class JaxbObjectMapperCustomizer {
|
||||
|
||||
@Autowired
|
||||
void addJaxbAnnotationIntrospector(ObjectMapper objectMapper) {
|
||||
JakartaXmlBindAnnotationIntrospector jaxbAnnotationIntrospector = new JakartaXmlBindAnnotationIntrospector(
|
||||
objectMapper.getTypeFactory());
|
||||
objectMapper.setAnnotationIntrospectors(
|
||||
createPair(objectMapper.getSerializationConfig(), jaxbAnnotationIntrospector),
|
||||
createPair(objectMapper.getDeserializationConfig(), jaxbAnnotationIntrospector));
|
||||
}
|
||||
|
||||
private AnnotationIntrospector createPair(MapperConfig<?> config,
|
||||
JakartaXmlBindAnnotationIntrospector jaxbAnnotationIntrospector) {
|
||||
return AnnotationIntrospector.pair(config.getAnnotationIntrospector(), jaxbAnnotationIntrospector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private ObjectMapperContextResolver(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper getContext(Class<?> type) {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} for Jersey.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.jersey")
|
||||
public class JerseyProperties {
|
||||
|
||||
/**
|
||||
* Jersey integration type.
|
||||
*/
|
||||
private Type type = Type.SERVLET;
|
||||
|
||||
/**
|
||||
* Init parameters to pass to Jersey through the servlet or filter.
|
||||
*/
|
||||
private Map<String, String> init = new HashMap<>();
|
||||
|
||||
private final Filter filter = new Filter();
|
||||
|
||||
private final Servlet servlet = new Servlet();
|
||||
|
||||
/**
|
||||
* Path that serves as the base URI for the application. If specified, overrides the
|
||||
* value of "@ApplicationPath".
|
||||
*/
|
||||
private String applicationPath;
|
||||
|
||||
public Filter getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
public Servlet getServlet() {
|
||||
return this.servlet;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Map<String, String> getInit() {
|
||||
return this.init;
|
||||
}
|
||||
|
||||
public void setInit(Map<String, String> init) {
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
public String getApplicationPath() {
|
||||
return this.applicationPath;
|
||||
}
|
||||
|
||||
public void setApplicationPath(String applicationPath) {
|
||||
this.applicationPath = applicationPath;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
SERVLET, FILTER
|
||||
|
||||
}
|
||||
|
||||
public static class Filter {
|
||||
|
||||
/**
|
||||
* Jersey filter chain order.
|
||||
*/
|
||||
private int order;
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Servlet {
|
||||
|
||||
/**
|
||||
* Load on startup priority of the Jersey servlet.
|
||||
*/
|
||||
private int loadOnStartup = -1;
|
||||
|
||||
public int getLoadOnStartup() {
|
||||
return this.loadOnStartup;
|
||||
}
|
||||
|
||||
public void setLoadOnStartup(int loadOnStartup) {
|
||||
this.loadOnStartup = loadOnStartup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize Jersey's
|
||||
* {@link ResourceConfig} before it is used.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ResourceConfigCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the resource config.
|
||||
* @param config the {@link ResourceConfig} to customize
|
||||
*/
|
||||
void customize(ResourceConfig config);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Jersey.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.jersey;
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.web.servlet;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyProperties;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link JerseyApplicationPath} that derives the path from
|
||||
* {@link JerseyProperties} or the {@code @ApplicationPath} annotation.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class DefaultJerseyApplicationPath implements JerseyApplicationPath {
|
||||
|
||||
private final String applicationPath;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
public DefaultJerseyApplicationPath(String applicationPath, ResourceConfig config) {
|
||||
this.applicationPath = applicationPath;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return resolveApplicationPath();
|
||||
}
|
||||
|
||||
private String resolveApplicationPath() {
|
||||
if (StringUtils.hasLength(this.applicationPath)) {
|
||||
return this.applicationPath;
|
||||
}
|
||||
// Jersey doesn't like to be the default servlet, so map to /* as a fallback
|
||||
return MergedAnnotations.from(this.config.getApplication().getClass(), SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(ApplicationPath.class).getValue(MergedAnnotation.VALUE, String.class).orElse("/*");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.web.servlet;
|
||||
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
|
||||
/**
|
||||
* Interface that can be used by auto-configurations that need path details Jersey's
|
||||
* application path that serves as the base URI for the application.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.0.7
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface JerseyApplicationPath {
|
||||
|
||||
/**
|
||||
* Returns the configured path of the application.
|
||||
* @return the configured path
|
||||
*/
|
||||
String getPath();
|
||||
|
||||
/**
|
||||
* Return a form of the given path that's relative to the Jersey application path.
|
||||
* @param path the path to make relative
|
||||
* @return the relative path
|
||||
*/
|
||||
default String getRelativePath(String path) {
|
||||
String prefix = getPrefix();
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
return prefix + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a cleaned up version of the path that can be used as a prefix for URLs. The
|
||||
* resulting path will have path will not have a trailing slash.
|
||||
* @return the prefix
|
||||
* @see #getRelativePath(String)
|
||||
*/
|
||||
default String getPrefix() {
|
||||
String result = getPath();
|
||||
int index = result.indexOf('*');
|
||||
if (index != -1) {
|
||||
result = result.substring(0, index);
|
||||
}
|
||||
if (result.endsWith("/")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a URL mapping pattern that can be used with a
|
||||
* {@link ServletRegistrationBean} to map Jersey's servlet.
|
||||
* @return the path as a servlet URL mapping
|
||||
*/
|
||||
default String getUrlMapping() {
|
||||
String path = getPath();
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
if (path.equals("/")) {
|
||||
return "/*";
|
||||
}
|
||||
if (path.contains("*")) {
|
||||
return path;
|
||||
}
|
||||
if (path.endsWith("/")) {
|
||||
return path + "*";
|
||||
}
|
||||
return path + "/*";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1550,6 +1550,10 @@
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.jersey.type",
|
||||
"defaultValue": "servlet"
|
||||
},
|
||||
{
|
||||
"name": "spring.jpa.hibernate.use-new-id-generator-mappings",
|
||||
"type": "java.lang.Boolean",
|
||||
|
||||
@@ -72,6 +72,7 @@ org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using a custom {@link Application}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/test/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApplicationPath("/test")
|
||||
static class TestApplication extends Application {
|
||||
|
||||
}
|
||||
|
||||
@Path("/hello")
|
||||
public static class TestController {
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class JerseyConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestApplication testApplication() {
|
||||
return new TestApplication();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceConfig conf(TestApplication app) {
|
||||
ResourceConfig config = ResourceConfig.forApplication(app);
|
||||
config.register(TestController.class);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.context-path=/app",
|
||||
"server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomFilterContextPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomFilterPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom load on startup.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.jersey.servlet.load-on-startup=5")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomLoadOnStartupTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
assertThat(this.context.getBean("jerseyServletRegistration")).hasFieldOrPropertyWithValue("loadOnStartup", 5);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom ObjectMapper.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jackson.default-property-inclusion=non_null")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomObjectMapperProviderTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> response = this.restTemplate.getForEntity("/rest/message", String.class);
|
||||
assertThat(HttpStatus.OK).isEqualTo(response.getStatusCode());
|
||||
assertThat("{\"subject\":\"Jersey\"}").isEqualTo(response.getBody());
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/message")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public Message message() {
|
||||
return new Message("Jersey", null);
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Message {
|
||||
|
||||
private String subject;
|
||||
|
||||
private String body;
|
||||
|
||||
Message(String subject, String body) {
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.servlet.contextPath=/app")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomServletContextPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomServletPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationDefaultFilterPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using default servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationDefaultServletPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.xml.bind.annotation.XmlTransient;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} with an ObjectMapper.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jackson.default-property-inclusion:non-null")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationObjectMapperProviderTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void responseIsSerializedUsingAutoConfiguredObjectMapper() {
|
||||
ResponseEntity<String> response = this.restTemplate.getForEntity("/rest/message", String.class);
|
||||
assertThat(HttpStatus.OK).isEqualTo(response.getStatusCode());
|
||||
assertThat(response.getBody()).isEqualTo("{\"subject\":\"Jersey\"}");
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/message")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public Message message() {
|
||||
return new Message("Jersey", null);
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Message {
|
||||
|
||||
private String subject;
|
||||
|
||||
private String body;
|
||||
|
||||
Message() {
|
||||
}
|
||||
|
||||
Message(String subject, String body) {
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Wrapper;
|
||||
import org.apache.tomcat.util.buf.UDecoder;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfigurationServletContainerTests.Application;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests that verify the behavior when deployed to a Servlet container where Jersey may
|
||||
* have already initialized itself.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class JerseyAutoConfigurationServletContainerTests {
|
||||
|
||||
@Test
|
||||
void existingJerseyServletIsAmended(CapturedOutput output) {
|
||||
assertThat(output).contains("Configuring existing registration for Jersey servlet");
|
||||
assertThat(output).contains("Servlet " + Application.class.getName() + " was not registered");
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@Import(ContainerConfiguration.class)
|
||||
@Path("/hello")
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ContainerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcat() {
|
||||
return new TomcatServletWebServerFactory() {
|
||||
|
||||
@Override
|
||||
protected void postProcessContext(Context context) {
|
||||
Wrapper jerseyServlet = context.createWrapper();
|
||||
String servletName = Application.class.getName();
|
||||
jerseyServlet.setName(servletName);
|
||||
jerseyServlet.setServletClass(ServletContainer.class.getName());
|
||||
jerseyServlet.setServlet(new ServletContainer());
|
||||
jerseyServlet.setOverridable(false);
|
||||
context.addChild(jerseyServlet);
|
||||
String pattern = UDecoder.URLDecode("/*", StandardCharsets.UTF_8);
|
||||
context.addServletMappingDecoded(pattern, servletName);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
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;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.RequestContextFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class))
|
||||
.withUserConfiguration(ResourceConfigConfiguration.class);
|
||||
|
||||
@Test
|
||||
void requestContextFilterRegistrationIsAutoConfigured() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
|
||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
||||
assertThat(registration.getFilter()).isInstanceOf(RequestContextFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUserDefinesARequestContextFilterTheAutoConfiguredRegistrationBacksOff() {
|
||||
this.contextRunner.withUserConfiguration(RequestContextFilterConfiguration.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(FilterRegistrationBean.class);
|
||||
assertThat(context).hasSingleBean(RequestContextFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUserDefinesARequestContextFilterRegistrationTheAutoConfiguredRegistrationBacksOff() {
|
||||
this.contextRunner.withUserConfiguration(RequestContextFilterRegistrationConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
|
||||
assertThat(context).hasBean("customRequestContextFilterRegistration");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJaxbIsAvailableTheObjectMapperIsCustomizedWithAnAnnotationIntrospector() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors().stream()
|
||||
.filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader("jakarta.xml.bind.annotation")).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors()
|
||||
.stream().filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(JakartaXmlBindAnnotationIntrospector.class)).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors()
|
||||
.stream().filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class RequestContextFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
RequestContextFilter requestContextFilter() {
|
||||
return new RequestContextFilter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class RequestContextFilterRegistrationConfiguration {
|
||||
|
||||
@Bean
|
||||
FilterRegistrationBean<RequestContextFilter> customRequestContextFilterRegistration() {
|
||||
return new FilterRegistrationBean<>(new RequestContextFilter());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.jersey;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom application path.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.jersey.application-path=/api")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationWithoutApplicationPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/api/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.boot.autoconfigure.web.servlet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyApplicationPath}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyApplicationPathTests {
|
||||
|
||||
@Test
|
||||
void getRelativePathReturnsRelativePath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getRelativePath("boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/").getRelativePath("boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getRelativePath("/boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/*").getRelativePath("/boot")).isEqualTo("spring/boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenHasSimplePathReturnPath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenHasPatternRemovesPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/*.do").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenPathEndsWithSlashRemovesSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathIsEmptyReturnsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "").getUrlMapping()).isEqualTo("/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathIsSlashReturnsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/").getUrlMapping()).isEqualTo("/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathContainsStarReturnsPath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/*.do").getUrlMapping()).isEqualTo("/spring/*.do");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathNotEndingSlashReturnsSlashStarPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/boot").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathDoesNotStartWithSlashPrependsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/boot").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathEndingWithSlashReturnsSlashStarPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/boot/").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user