Polish
This commit is contained in:
parent
c136054e69
commit
7446235ff4
|
|
@ -30,6 +30,7 @@ import org.springframework.core.ResolvableType;
|
||||||
*
|
*
|
||||||
* @param <H> The health indicator type
|
* @param <H> The health indicator type
|
||||||
* @param <S> T he bean source type
|
* @param <S> T he bean source type
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 1.4.0
|
* @since 1.4.0
|
||||||
*/
|
*/
|
||||||
public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> {
|
public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> {
|
||||||
|
|
@ -61,8 +62,8 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
|
||||||
return indicatorClass.getConstructor(sourceClass).newInstance(source);
|
return indicatorClass.getConstructor(sourceClass).newInstance(source);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Unable to create indicator "
|
throw new IllegalStateException("Unable to create indicator " + indicatorClass
|
||||||
+ indicatorClass + " for source " + sourceClass, ex);
|
+ " for source " + sourceClass, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ class ElasticsearchHealthIndicatorConfiguration {
|
||||||
@ConditionalOnBean(Client.class)
|
@ConditionalOnBean(Client.class)
|
||||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||||
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
|
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
|
||||||
static class SpringData extends
|
static class ElasticsearchSpringDataHealthIndicatorConfiguration extends
|
||||||
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
|
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
|
||||||
|
|
||||||
private final Map<String, Client> clients;
|
private final Map<String, Client> clients;
|
||||||
|
|
||||||
private final ElasticsearchHealthIndicatorProperties properties;
|
private final ElasticsearchHealthIndicatorProperties properties;
|
||||||
|
|
||||||
SpringData(Map<String, Client> clients,
|
ElasticsearchSpringDataHealthIndicatorConfiguration(Map<String, Client> clients,
|
||||||
ElasticsearchHealthIndicatorProperties properties) {
|
ElasticsearchHealthIndicatorProperties properties) {
|
||||||
this.clients = clients;
|
this.clients = clients;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
|
@ -72,12 +72,12 @@ class ElasticsearchHealthIndicatorConfiguration {
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnBean(JestClient.class)
|
@ConditionalOnBean(JestClient.class)
|
||||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||||
static class Jest extends
|
static class ElasticsearchJestHealthIndicatorConfiguration extends
|
||||||
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
|
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
|
||||||
|
|
||||||
private final Map<String, JestClient> clients;
|
private final Map<String, JestClient> clients;
|
||||||
|
|
||||||
Jest(Map<String, JestClient> clients) {
|
ElasticsearchJestHealthIndicatorConfiguration(Map<String, JestClient> clients) {
|
||||||
this.clients = clients;
|
this.clients = clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,9 +88,11 @@ class ElasticsearchHealthIndicatorConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ElasticsearchJestHealthIndicator createHealthIndicator(JestClient client) {
|
protected ElasticsearchJestHealthIndicator createHealthIndicator(
|
||||||
|
JestClient client) {
|
||||||
return new ElasticsearchJestHealthIndicator(client);
|
return new ElasticsearchJestHealthIndicator(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,8 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
MongoDataAutoConfiguration.class, RabbitAutoConfiguration.class,
|
MongoDataAutoConfiguration.class, RabbitAutoConfiguration.class,
|
||||||
RedisAutoConfiguration.class, SolrAutoConfiguration.class })
|
RedisAutoConfiguration.class, SolrAutoConfiguration.class })
|
||||||
@EnableConfigurationProperties({ HealthIndicatorProperties.class })
|
@EnableConfigurationProperties({ HealthIndicatorProperties.class })
|
||||||
@Import({ ElasticsearchHealthIndicatorConfiguration.SpringData.class,
|
@Import({ ElasticsearchHealthIndicatorConfiguration.ElasticsearchSpringDataHealthIndicatorConfiguration.class,
|
||||||
ElasticsearchHealthIndicatorConfiguration.Jest.class })
|
ElasticsearchHealthIndicatorConfiguration.ElasticsearchJestHealthIndicatorConfiguration.class })
|
||||||
public class HealthIndicatorAutoConfiguration {
|
public class HealthIndicatorAutoConfiguration {
|
||||||
|
|
||||||
private final HealthIndicatorProperties properties;
|
private final HealthIndicatorProperties properties;
|
||||||
|
|
|
||||||
|
|
@ -70,4 +70,5 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
|
||||||
builder.withDetail("initializingShards", response.getInitializingShards());
|
builder.withDetail("initializingShards", response.getInitializingShards());
|
||||||
builder.withDetail("unassignedShards", response.getUnassignedShards());
|
builder.withDetail("unassignedShards", response.getUnassignedShards());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
||||||
public void elasticSearchIsDown() throws IOException {
|
public void elasticSearchIsDown() throws IOException {
|
||||||
given(this.jestClient.execute(any(Action.class))).willThrow(
|
given(this.jestClient.execute(any(Action.class))).willThrow(
|
||||||
new CouldNotConnectException("http://localhost:9200", new IOException()));
|
new CouldNotConnectException("http://localhost:9200", new IOException()));
|
||||||
|
|
||||||
Health health = this.healthIndicator.health();
|
Health health = this.healthIndicator.health();
|
||||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +68,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
||||||
public void elasticSearchIsOutOfService() throws IOException {
|
public void elasticSearchIsOutOfService() throws IOException {
|
||||||
given(this.jestClient.execute(any(Action.class)))
|
given(this.jestClient.execute(any(Action.class)))
|
||||||
.willReturn(createJestResult(4, 1));
|
.willReturn(createJestResult(4, 1));
|
||||||
|
|
||||||
Health health = this.healthIndicator.health();
|
Health health = this.healthIndicator.health();
|
||||||
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
|
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +75,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
||||||
private static JestResult createJestResult(int shards, int failedShards) {
|
private static JestResult createJestResult(int shards, int failedShards) {
|
||||||
String json = String.format("{_shards: {\n" + "total: %s,\n" + "successful: %s,\n"
|
String json = String.format("{_shards: {\n" + "total: %s,\n" + "successful: %s,\n"
|
||||||
+ "failed: %s\n" + "}}", shards, shards - failedShards, failedShards);
|
+ "failed: %s\n" + "}}", shards, shards - failedShards, failedShards);
|
||||||
|
|
||||||
SearchResult searchResult = new SearchResult(new Gson());
|
SearchResult searchResult = new SearchResult(new Gson());
|
||||||
searchResult.setJsonString(json);
|
searchResult.setJsonString(json);
|
||||||
searchResult.setJsonObject(new JsonParser().parse(json).getAsJsonObject());
|
searchResult.setJsonObject(new JsonParser().parse(json).getAsJsonObject());
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ public class JestAutoConfiguration {
|
||||||
|
|
||||||
private final ObjectProvider<Gson> gsonProvider;
|
private final ObjectProvider<Gson> gsonProvider;
|
||||||
|
|
||||||
public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gsonProvider) {
|
public JestAutoConfiguration(JestProperties properties,
|
||||||
|
ObjectProvider<Gson> gsonProvider) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.gsonProvider = gsonProvider;
|
this.gsonProvider = gsonProvider;
|
||||||
}
|
}
|
||||||
|
|
@ -62,8 +63,8 @@ public class JestAutoConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpClientConfig createHttpClientConfig() {
|
protected HttpClientConfig createHttpClientConfig() {
|
||||||
HttpClientConfig.Builder builder = new HttpClientConfig
|
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
|
||||||
.Builder(this.properties.getUris());
|
this.properties.getUris());
|
||||||
if (StringUtils.hasText(this.properties.getUsername())) {
|
if (StringUtils.hasText(this.properties.getUsername())) {
|
||||||
builder.defaultCredentials(this.properties.getUsername(),
|
builder.defaultCredentials(this.properties.getUsername(),
|
||||||
this.properties.getPassword());
|
this.properties.getPassword());
|
||||||
|
|
@ -73,8 +74,7 @@ public class JestAutoConfiguration {
|
||||||
builder.gson(gson);
|
builder.gson(gson);
|
||||||
}
|
}
|
||||||
return builder.connTimeout(this.properties.getConnectionTimeout())
|
return builder.connTimeout(this.properties.getConnectionTimeout())
|
||||||
.readTimeout(this.properties.getReadTimeout())
|
.readTimeout(this.properties.getReadTimeout()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ class ArtemisConnectionFactoryFactory {
|
||||||
Constructor<T> constructor = factoryClass.getConstructor(boolean.class,
|
Constructor<T> constructor = factoryClass.getConstructor(boolean.class,
|
||||||
TransportConfiguration[].class);
|
TransportConfiguration[].class);
|
||||||
T connectionFactory = constructor.newInstance(false,
|
T connectionFactory = constructor.newInstance(false,
|
||||||
new TransportConfiguration[] {transportConfiguration});
|
new TransportConfiguration[] { transportConfiguration });
|
||||||
String user = this.properties.getUser();
|
String user = this.properties.getUser();
|
||||||
if (StringUtils.hasText(user)) {
|
if (StringUtils.hasText(user)) {
|
||||||
connectionFactory.setUser(user);
|
connectionFactory.setUser(user);
|
||||||
|
|
|
||||||
|
|
@ -112,9 +112,10 @@ class HornetQConnectionFactoryFactory {
|
||||||
this.properties.getEmbedded().generateTransportParameters());
|
this.properties.getEmbedded().generateTransportParameters());
|
||||||
ServerLocator serviceLocator = HornetQClient
|
ServerLocator serviceLocator = HornetQClient
|
||||||
.createServerLocatorWithoutHA(transportConfiguration);
|
.createServerLocatorWithoutHA(transportConfiguration);
|
||||||
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
|
Constructor<T> constructor = factoryClass
|
||||||
ServerLocator.class);
|
.getDeclaredConstructor(HornetQProperties.class, ServerLocator.class);
|
||||||
return BeanUtils.instantiateClass(constructor, this.properties, serviceLocator);
|
return BeanUtils.instantiateClass(constructor, this.properties,
|
||||||
|
serviceLocator);
|
||||||
}
|
}
|
||||||
catch (NoClassDefFoundError ex) {
|
catch (NoClassDefFoundError ex) {
|
||||||
throw new IllegalStateException("Unable to create InVM "
|
throw new IllegalStateException("Unable to create InVM "
|
||||||
|
|
@ -130,8 +131,8 @@ class HornetQConnectionFactoryFactory {
|
||||||
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
|
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
|
||||||
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
||||||
NettyConnectorFactory.class.getName(), params);
|
NettyConnectorFactory.class.getName(), params);
|
||||||
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
|
Constructor<T> constructor = factoryClass.getDeclaredConstructor(
|
||||||
boolean.class, TransportConfiguration[].class);
|
HornetQProperties.class, boolean.class, TransportConfiguration[].class);
|
||||||
return BeanUtils.instantiateClass(constructor, this.properties, false,
|
return BeanUtils.instantiateClass(constructor, this.properties, false,
|
||||||
new TransportConfiguration[] { transportConfiguration });
|
new TransportConfiguration[] { transportConfiguration });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class HornetQXAConnectionFactoryConfiguration {
|
||||||
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
|
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
|
||||||
public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
|
public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
|
||||||
HornetQProperties properties, XAConnectionFactoryWrapper wrapper)
|
HornetQProperties properties, XAConnectionFactoryWrapper wrapper)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return wrapper.wrapConnectionFactory(
|
return wrapper.wrapConnectionFactory(
|
||||||
new HornetQConnectionFactoryFactory(beanFactory, properties)
|
new HornetQConnectionFactoryFactory(beanFactory, properties)
|
||||||
.createConnectionFactory(
|
.createConnectionFactory(
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class SpringBootHornetQConnectionFactory extends HornetQConnectionFactory {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Connection createConnection() throws JMSException {
|
public Connection createConnection() throws JMSException {
|
||||||
String user = this.properties.getUser();
|
String user = this.properties.getUser();
|
||||||
if (StringUtils.hasText(user)) {
|
if (StringUtils.hasText(user)) {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class SpringBootHornetQXAConnectionFactory extends HornetQXAConnectionFactory {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Connection createConnection() throws JMSException {
|
public Connection createConnection() throws JMSException {
|
||||||
String user = this.properties.getUser();
|
String user = this.properties.getUser();
|
||||||
if (StringUtils.hasText(user)) {
|
if (StringUtils.hasText(user)) {
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,8 @@ public class MongoProperties {
|
||||||
}
|
}
|
||||||
String host = this.host == null ? "localhost" : this.host;
|
String host = this.host == null ? "localhost" : this.host;
|
||||||
int port = determinePort(environment);
|
int port = determinePort(environment);
|
||||||
return new MongoClient(Collections.singletonList(new ServerAddress(host, port)),
|
return new MongoClient(
|
||||||
|
Collections.singletonList(new ServerAddress(host, port)),
|
||||||
credentials, options);
|
credentials, options);
|
||||||
}
|
}
|
||||||
// The options and credentials are in the URI
|
// The options and credentials are in the URI
|
||||||
|
|
|
||||||
|
|
@ -226,14 +226,13 @@ public class WebMvcAutoConfiguration {
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
|
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
|
||||||
public LocaleResolver localeResolver() {
|
public LocaleResolver localeResolver() {
|
||||||
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
|
if (this.mvcProperties
|
||||||
|
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
|
||||||
return new FixedLocaleResolver(this.mvcProperties.getLocale());
|
return new FixedLocaleResolver(this.mvcProperties.getLocale());
|
||||||
}
|
}
|
||||||
else {
|
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
|
||||||
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
|
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
|
||||||
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
|
return localeResolver;
|
||||||
return localeResolver;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ public class WebMvcProperties {
|
||||||
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
|
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locale to use. By default, this locale is overridden by the "Accept-Language" header.
|
* Locale to use. By default, this locale is overridden by the "Accept-Language"
|
||||||
|
* header.
|
||||||
*/
|
*/
|
||||||
private Locale locale;
|
private Locale locale;
|
||||||
|
|
||||||
|
|
@ -261,8 +262,8 @@ public class WebMvcProperties {
|
||||||
FIXED,
|
FIXED,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the "Accept-Language" header or the configured locale if the header
|
* Use the "Accept-Language" header or the configured locale if the header is not
|
||||||
* is not set.
|
* set.
|
||||||
*/
|
*/
|
||||||
ACCEPT_HEADER
|
ACCEPT_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ public class MongoAutoConfigurationTests {
|
||||||
MongoClient mongo = this.context.getBean(MongoClient.class);
|
MongoClient mongo = this.context.getBean(MongoClient.class);
|
||||||
MongoClientOptions options = mongo.getMongoClientOptions();
|
MongoClientOptions options = mongo.getMongoClientOptions();
|
||||||
assertThat(options.isSslEnabled()).isTrue();
|
assertThat(options.isSslEnabled()).isTrue();
|
||||||
assertThat(options.getSocketFactory()).isSameAs(this.context.getBean("mySocketFactory"));
|
assertThat(options.getSocketFactory())
|
||||||
|
.isSameAs(this.context.getBean("mySocketFactory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
@ -110,7 +111,8 @@ public class MongoAutoConfigurationTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MongoClientOptions mongoClientOptions() {
|
public MongoClientOptions mongoClientOptions() {
|
||||||
return MongoClientOptions.builder().sslEnabled(true).socketFactory(mySocketFactory()).build();
|
return MongoClientOptions.builder().sslEnabled(true)
|
||||||
|
.socketFactory(mySocketFactory()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
||||||
|
|
@ -2637,20 +2637,21 @@ and http://hibernate.org/orm/documentation/[Hibernate] reference documentation.
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
As of Hibernate 5.2, the `hibernate-entitymanager` module has been merged in
|
As of Hibernate 5.2, the `hibernate-entitymanager` module has been merged in
|
||||||
`hibernate-core`. If you need to downgrade, you'll have to add `hibernate-entitymanager`
|
`hibernate-core`. If you need to downgrade, you'll need to directly add the
|
||||||
yourself, something like:
|
dependency yourself, for example:
|
||||||
|
|
||||||
```xml
|
[source,xml,indent=0]
|
||||||
<dependency>
|
----
|
||||||
<groupId>org.springframework.boot</groupId>
|
<dependency>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
</dependency>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
<dependency>
|
</dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<dependency>
|
||||||
<artifactId>hibernate-entitymanager</artifactId>
|
<groupId>org.hibernate</groupId>
|
||||||
<version>${hibernate.version}</version>
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
</dependency>
|
<version>${hibernate.version}</version>
|
||||||
```
|
</dependency>
|
||||||
|
----
|
||||||
|
|
||||||
As Hibernate does not bundle the `hibernate-entitymanager` and `hibernate-java8`
|
As Hibernate does not bundle the `hibernate-entitymanager` and `hibernate-java8`
|
||||||
artifacts anymore, Spring Boot doesn't provide dependency management for them.
|
artifacts anymore, Spring Boot doesn't provide dependency management for them.
|
||||||
|
|
@ -3364,6 +3365,7 @@ configured:
|
||||||
To take full control over the registration, define a `JestClient` bean.
|
To take full control over the registration, define a `JestClient` bean.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[boot-features-connecting-to-elasticsearch]]
|
[[boot-features-connecting-to-elasticsearch]]
|
||||||
[[boot-features-connecting-to-elasticsearch-spring-data]]
|
[[boot-features-connecting-to-elasticsearch-spring-data]]
|
||||||
==== Connecting to Elasticsearch using Spring Data
|
==== Connecting to Elasticsearch using Spring Data
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package sample.jetty.jsp;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.context.web.SpringBootServletInitializer;
|
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SampleJettyJspApplication extends SpringBootServletInitializer {
|
public class SampleJettyJspApplication extends SpringBootServletInitializer {
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,15 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||||
Element returns = this.processingEnv.getTypeUtils()
|
Element returns = this.processingEnv.getTypeUtils()
|
||||||
.asElement(element.getReturnType());
|
.asElement(element.getReturnType());
|
||||||
if (returns instanceof TypeElement) {
|
if (returns instanceof TypeElement) {
|
||||||
ItemMetadata group = ItemMetadata.newGroup(prefix, this.typeUtils.getType(returns),
|
ItemMetadata group = ItemMetadata.newGroup(prefix,
|
||||||
|
this.typeUtils.getType(returns),
|
||||||
this.typeUtils.getType(element.getEnclosingElement()),
|
this.typeUtils.getType(element.getEnclosingElement()),
|
||||||
element.toString());
|
element.toString());
|
||||||
if (this.metadataCollector.hasSimilarGroup(group)) {
|
if (this.metadataCollector.hasSimilarGroup(group)) {
|
||||||
this.processingEnv.getMessager().printMessage(Kind.ERROR,
|
this.processingEnv.getMessager().printMessage(Kind.ERROR,
|
||||||
"Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'", element);
|
"Duplicate `@ConfigurationProperties` definition for prefix '"
|
||||||
|
+ prefix + "'",
|
||||||
|
element);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.metadataCollector.add(group);
|
this.metadataCollector.add(group);
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,7 @@ package org.springframework.boot.configurationsample.specific;
|
||||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the same type can be registered several times if the prefix is
|
* Test that the same type can be registered several times if the prefix is different.
|
||||||
* different.
|
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,19 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jetty {@link AbstractLifeCycle} to initialize jasper.
|
* Jetty {@link AbstractLifeCycle} to initialize Jasper.
|
||||||
*
|
*
|
||||||
* @author Vladimir Tsanev
|
* @author Vladimir Tsanev
|
||||||
|
* @author Phillip Webb
|
||||||
*/
|
*/
|
||||||
public class JasperInitializer extends AbstractLifeCycle {
|
class JasperInitializer extends AbstractLifeCycle {
|
||||||
|
|
||||||
|
private static final String[] INITIALIZER_CLASSES = {
|
||||||
|
"org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
|
||||||
|
"org.apache.jasper.servlet.JasperInitializer" };
|
||||||
|
|
||||||
private final WebAppContext context;
|
private final WebAppContext context;
|
||||||
|
|
||||||
private final ServletContainerInitializer initializer;
|
private final ServletContainerInitializer initializer;
|
||||||
|
|
||||||
JasperInitializer(WebAppContext context) {
|
JasperInitializer(WebAppContext context) {
|
||||||
|
|
@ -45,24 +51,17 @@ public class JasperInitializer extends AbstractLifeCycle {
|
||||||
this.initializer = newInitializer();
|
this.initializer = newInitializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServletContainerInitializer newInitializer() {
|
private ServletContainerInitializer newInitializer() {
|
||||||
try {
|
for (String className : INITIALIZER_CLASSES) {
|
||||||
try {
|
try {
|
||||||
return (ServletContainerInitializer) ClassUtils
|
Class<?> initializerClass = ClassUtils.forName(className, null);
|
||||||
.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
|
return (ServletContainerInitializer) initializerClass.newInstance();
|
||||||
null)
|
|
||||||
.newInstance();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
// try the original initializer
|
// Ignore
|
||||||
return (ServletContainerInitializer) ClassUtils
|
|
||||||
.forName("org.apache.jasper.servlet.JasperInitializer", null)
|
|
||||||
.newInstance();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -71,22 +70,14 @@ public class JasperInitializer extends AbstractLifeCycle {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
|
URL.setURLStreamHandlerFactory(new WarUrlStreamHandlerFactory());
|
||||||
@Override
|
|
||||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
|
||||||
if ("war".equals(protocol)) {
|
|
||||||
return new WarUrlStreamHandler();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Error ex) {
|
catch (Error ex) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
|
|
||||||
try {
|
try {
|
||||||
|
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
|
||||||
try {
|
try {
|
||||||
setExtendedListenerTypes(true);
|
setExtendedListenerTypes(true);
|
||||||
this.initializer.onStartup(null, this.context.getServletContext());
|
this.initializer.onStartup(null, this.context.getServletContext());
|
||||||
|
|
@ -109,23 +100,36 @@ public class JasperInitializer extends AbstractLifeCycle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link URLStreamHandlerFactory} to support {@literal war} protocol.
|
||||||
|
*/
|
||||||
|
private static class WarUrlStreamHandlerFactory implements URLStreamHandlerFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||||
|
if ("war".equals(protocol)) {
|
||||||
|
return new WarUrlStreamHandler();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link URLStreamHandler} for {@literal war} protocol compatible with jasper's
|
* {@link URLStreamHandler} for {@literal war} protocol compatible with jasper's
|
||||||
* {@link URL urls} produced by
|
* {@link URL urls} produced by
|
||||||
* {@link org.apache.tomcat.util.scan.JarFactory#getJarEntryURL(URL, String)}.
|
* {@link org.apache.tomcat.util.scan.JarFactory#getJarEntryURL(URL, String)}.
|
||||||
*/
|
*/
|
||||||
static class WarUrlStreamHandler extends URLStreamHandler {
|
private static class WarUrlStreamHandler extends URLStreamHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseURL(URL u, String spec, int start, int limit) {
|
protected void parseURL(URL u, String spec, int start, int limit) {
|
||||||
String path = "jar:" + spec.substring("war:".length());
|
String path = "jar:" + spec.substring("war:".length());
|
||||||
|
|
||||||
int separator = path.indexOf("*/");
|
int separator = path.indexOf("*/");
|
||||||
if (separator >= 0) {
|
if (separator >= 0) {
|
||||||
path = path.substring(0, separator) + "!/"
|
path = path.substring(0, separator) + "!/"
|
||||||
+ path.substring(separator + 2);
|
+ path.substring(separator + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
setURL(u, u.getProtocol(), "", -1, null, null, path, null, null);
|
setURL(u, u.getProtocol(), "", -1, null, null, path, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,12 +137,13 @@ public class JasperInitializer extends AbstractLifeCycle {
|
||||||
protected URLConnection openConnection(URL u) throws IOException {
|
protected URLConnection openConnection(URL u) throws IOException {
|
||||||
return new WarURLConnection(u);
|
return new WarURLConnection(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link URLConnection} to support {@literal war} protocol.
|
* {@link URLConnection} to support {@literal war} protocol.
|
||||||
*/
|
*/
|
||||||
static class WarURLConnection extends URLConnection {
|
private static class WarURLConnection extends URLConnection {
|
||||||
|
|
||||||
private final URLConnection connection;
|
private final URLConnection connection;
|
||||||
|
|
||||||
|
|
@ -160,6 +165,7 @@ public class JasperInitializer extends AbstractLifeCycle {
|
||||||
connect();
|
connect();
|
||||||
return this.connection.getInputStream();
|
return this.connection.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.tomcat;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.net.URLStreamHandler;
|
||||||
|
import java.net.URLStreamHandlerFactory;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.embedded.SslStoreProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
|
||||||
|
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class SslStoreProviderUrlStreamHandlerFactory implements URLStreamHandlerFactory {
|
||||||
|
|
||||||
|
private static final String PROTOCOL = "springbootssl";
|
||||||
|
|
||||||
|
private static final String KEY_STORE_PATH = "keyStore";
|
||||||
|
|
||||||
|
static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
|
||||||
|
|
||||||
|
private static final String TRUST_STORE_PATH = "trustStore";
|
||||||
|
|
||||||
|
static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
|
||||||
|
|
||||||
|
private final SslStoreProvider sslStoreProvider;
|
||||||
|
|
||||||
|
SslStoreProviderUrlStreamHandlerFactory(SslStoreProvider sslStoreProvider) {
|
||||||
|
this.sslStoreProvider = sslStoreProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||||
|
if (PROTOCOL.equals(protocol)) {
|
||||||
|
return new URLStreamHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected URLConnection openConnection(URL url) throws IOException {
|
||||||
|
try {
|
||||||
|
if (KEY_STORE_PATH.equals(url.getPath())) {
|
||||||
|
return new KeyStoreUrlConnection(url,
|
||||||
|
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||||
|
.getKeyStore());
|
||||||
|
}
|
||||||
|
if (TRUST_STORE_PATH.equals(url.getPath())) {
|
||||||
|
return new KeyStoreUrlConnection(url,
|
||||||
|
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||||
|
.getTrustStore());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
throw new IOException("Invalid path: " + url.getPath());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class KeyStoreUrlConnection extends URLConnection {
|
||||||
|
|
||||||
|
private final KeyStore keyStore;
|
||||||
|
|
||||||
|
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
|
||||||
|
super(url);
|
||||||
|
this.keyStore = keyStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
this.keyStore.store(stream, new char[0]);
|
||||||
|
return new ByteArrayInputStream(stream.toByteArray());
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,19 +16,11 @@
|
||||||
|
|
||||||
package org.springframework.boot.context.embedded.tomcat;
|
package org.springframework.boot.context.embedded.tomcat;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.net.URLStreamHandler;
|
|
||||||
import java.net.URLStreamHandlerFactory;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -63,7 +55,6 @@ import org.apache.coyote.http11.AbstractHttp11Protocol;
|
||||||
import org.apache.coyote.http11.Http11NioProtocol;
|
import org.apache.coyote.http11.Http11NioProtocol;
|
||||||
import org.apache.tomcat.util.net.SSLHostConfig;
|
import org.apache.tomcat.util.net.SSLHostConfig;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||||
import org.springframework.boot.context.embedded.Compression;
|
import org.springframework.boot.context.embedded.Compression;
|
||||||
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
||||||
|
|
@ -79,7 +70,6 @@ import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
@ -702,158 +692,6 @@ public class TomcatEmbeddedServletContainerFactory
|
||||||
return this.uriEncoding;
|
return this.uriEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
|
|
||||||
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
|
|
||||||
*/
|
|
||||||
private static final class SslStoreProviderUrlStreamHandlerFactory
|
|
||||||
implements URLStreamHandlerFactory {
|
|
||||||
|
|
||||||
private static final String PROTOCOL = "springbootssl";
|
|
||||||
|
|
||||||
private static final String KEY_STORE_PATH = "keyStore";
|
|
||||||
|
|
||||||
private static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
|
|
||||||
|
|
||||||
private static final String TRUST_STORE_PATH = "trustStore";
|
|
||||||
|
|
||||||
private static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
|
|
||||||
|
|
||||||
private final SslStoreProvider sslStoreProvider;
|
|
||||||
|
|
||||||
private SslStoreProviderUrlStreamHandlerFactory(
|
|
||||||
SslStoreProvider sslStoreProvider) {
|
|
||||||
this.sslStoreProvider = sslStoreProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
|
||||||
if (PROTOCOL.equals(protocol)) {
|
|
||||||
return new URLStreamHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected URLConnection openConnection(URL url) throws IOException {
|
|
||||||
try {
|
|
||||||
if (KEY_STORE_PATH.equals(url.getPath())) {
|
|
||||||
return new KeyStoreUrlConnection(url,
|
|
||||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
|
||||||
.getKeyStore());
|
|
||||||
}
|
|
||||||
if (TRUST_STORE_PATH.equals(url.getPath())) {
|
|
||||||
return new KeyStoreUrlConnection(url,
|
|
||||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
|
||||||
.getTrustStore());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new IOException(ex);
|
|
||||||
}
|
|
||||||
throw new IOException("Invalid path: " + url.getPath());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class KeyStoreUrlConnection extends URLConnection {
|
|
||||||
|
|
||||||
private final KeyStore keyStore;
|
|
||||||
|
|
||||||
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
|
|
||||||
super(url);
|
|
||||||
this.keyStore = keyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect() throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream() throws IOException {
|
|
||||||
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
this.keyStore.store(stream, new char[0]);
|
|
||||||
return new ByteArrayInputStream(stream.toByteArray());
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new IOException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TomcatErrorPage {
|
|
||||||
|
|
||||||
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
|
|
||||||
|
|
||||||
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
|
|
||||||
|
|
||||||
private final String location;
|
|
||||||
|
|
||||||
private final String exceptionType;
|
|
||||||
|
|
||||||
private final int errorCode;
|
|
||||||
|
|
||||||
private final Object nativePage;
|
|
||||||
|
|
||||||
TomcatErrorPage(ErrorPage errorPage) {
|
|
||||||
this.location = errorPage.getPath();
|
|
||||||
this.exceptionType = errorPage.getExceptionName();
|
|
||||||
this.errorCode = errorPage.getStatusCode();
|
|
||||||
this.nativePage = createNativePage(errorPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object createNativePage(ErrorPage errorPage) {
|
|
||||||
Object nativePage = null;
|
|
||||||
try {
|
|
||||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
|
||||||
nativePage = BeanUtils
|
|
||||||
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
|
|
||||||
}
|
|
||||||
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
|
|
||||||
nativePage = BeanUtils.instantiate(
|
|
||||||
ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException ex) {
|
|
||||||
// Swallow and continue
|
|
||||||
}
|
|
||||||
catch (LinkageError ex) {
|
|
||||||
// Swallow and continue
|
|
||||||
}
|
|
||||||
return nativePage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addToContext(Context context) {
|
|
||||||
Assert.state(this.nativePage != null,
|
|
||||||
"Neither Tomcat 7 nor 8 detected so no native error page exists");
|
|
||||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
|
||||||
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
|
|
||||||
errorPage.setLocation(this.location);
|
|
||||||
errorPage.setErrorCode(this.errorCode);
|
|
||||||
errorPage.setExceptionType(this.exceptionType);
|
|
||||||
context.addErrorPage(errorPage);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callMethod(this.nativePage, "setLocation", this.location, String.class);
|
|
||||||
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
|
|
||||||
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
|
|
||||||
String.class);
|
|
||||||
callMethod(context, "addErrorPage", this.nativePage,
|
|
||||||
this.nativePage.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void callMethod(Object target, String name, Object value, Class<?> type) {
|
|
||||||
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
|
|
||||||
ReflectionUtils.invokeMethod(method, target, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link LifecycleListener} that stores an empty merged web.xml. This is critical for
|
* {@link LifecycleListener} that stores an empty merged web.xml. This is critical for
|
||||||
* Jasper to prevent warnings about missing web.xml files and to enable EL.
|
* Jasper to prevent warnings about missing web.xml files and to enable EL.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.tomcat;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.apache.catalina.Context;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.boot.web.servlet.ErrorPage;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tomcat specific management for an {@link ErrorPage}.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class TomcatErrorPage {
|
||||||
|
|
||||||
|
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
|
||||||
|
|
||||||
|
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
|
||||||
|
|
||||||
|
private final String location;
|
||||||
|
|
||||||
|
private final String exceptionType;
|
||||||
|
|
||||||
|
private final int errorCode;
|
||||||
|
|
||||||
|
private final Object nativePage;
|
||||||
|
|
||||||
|
TomcatErrorPage(ErrorPage errorPage) {
|
||||||
|
this.location = errorPage.getPath();
|
||||||
|
this.exceptionType = errorPage.getExceptionName();
|
||||||
|
this.errorCode = errorPage.getStatusCode();
|
||||||
|
this.nativePage = createNativePage(errorPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object createNativePage(ErrorPage errorPage) {
|
||||||
|
Object nativePage = null;
|
||||||
|
try {
|
||||||
|
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||||
|
nativePage = BeanUtils
|
||||||
|
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
|
||||||
|
}
|
||||||
|
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
|
||||||
|
nativePage = BeanUtils
|
||||||
|
.instantiate(ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException ex) {
|
||||||
|
// Swallow and continue
|
||||||
|
}
|
||||||
|
catch (LinkageError ex) {
|
||||||
|
// Swallow and continue
|
||||||
|
}
|
||||||
|
return nativePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToContext(Context context) {
|
||||||
|
Assert.state(this.nativePage != null,
|
||||||
|
"Neither Tomcat 7 nor 8 detected so no native error page exists");
|
||||||
|
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||||
|
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
|
||||||
|
errorPage.setLocation(this.location);
|
||||||
|
errorPage.setErrorCode(this.errorCode);
|
||||||
|
errorPage.setExceptionType(this.exceptionType);
|
||||||
|
context.addErrorPage(errorPage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callMethod(this.nativePage, "setLocation", this.location, String.class);
|
||||||
|
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
|
||||||
|
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
|
||||||
|
String.class);
|
||||||
|
callMethod(context, "addErrorPage", this.nativePage,
|
||||||
|
this.nativePage.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callMethod(Object target, String name, Object value, Class<?> type) {
|
||||||
|
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
|
||||||
|
ReflectionUtils.invokeMethod(method, target, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -33,10 +33,9 @@ import com.google.gson.reflect.TypeToken;
|
||||||
*/
|
*/
|
||||||
public class GsonJsonParser implements JsonParser {
|
public class GsonJsonParser implements JsonParser {
|
||||||
|
|
||||||
private static final TypeToken<List<Object>> LIST_TYPE = new TypeToken<List<Object>>() {
|
private static final TypeToken<?> MAP_TYPE = new MapTypeToken();
|
||||||
};
|
|
||||||
private static final TypeToken<Map<String, Object>> MAP_TYPE = new TypeToken<Map<String, Object>>() {
|
private static final TypeToken<?> LIST_TYPE = new ListTypeToken();
|
||||||
};
|
|
||||||
|
|
||||||
private Gson gson = new GsonBuilder().create();
|
private Gson gson = new GsonBuilder().create();
|
||||||
|
|
||||||
|
|
@ -62,4 +61,12 @@ public class GsonJsonParser implements JsonParser {
|
||||||
throw new IllegalArgumentException("Cannot parse JSON");
|
throw new IllegalArgumentException("Cannot parse JSON");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class MapTypeToken extends TypeToken<Map<String, Object>> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ListTypeToken extends TypeToken<List<Object>> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
*/
|
*/
|
||||||
public class JacksonJsonParser implements JsonParser {
|
public class JacksonJsonParser implements JsonParser {
|
||||||
|
|
||||||
private static final TypeReference<List<Object>> LIST_TYPE = new TypeReference<List<Object>>() {
|
private static final TypeReference<?> MAP_TYPE = new MapTypeReference();
|
||||||
};
|
|
||||||
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {
|
private static final TypeReference<?> LIST_TYPE = new ListTypeReference();
|
||||||
};
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
|
@ -57,4 +56,12 @@ public class JacksonJsonParser implements JsonParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private static class ListTypeReference extends TypeReference<List<Object>> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,10 @@ public class TestEntityScanTests {
|
||||||
@Test
|
@Test
|
||||||
public void valueAndBasePackagesThrows() throws Exception {
|
public void valueAndBasePackagesThrows() throws Exception {
|
||||||
this.thrown.expect(AnnotationConfigurationException.class);
|
this.thrown.expect(AnnotationConfigurationException.class);
|
||||||
this.thrown.expectMessage(allOf(
|
this.thrown.expectMessage(allOf(containsString("'value'"),
|
||||||
containsString("'value'"),
|
containsString("'basePackages'"), containsString("com.mycorp.entity"),
|
||||||
containsString("'basePackages'"),
|
|
||||||
containsString("com.mycorp.entity"),
|
|
||||||
containsString("com.mycorp")));
|
containsString("com.mycorp")));
|
||||||
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -78,12 +78,10 @@ public class ServletComponentScanRegistrarTests {
|
||||||
@Test
|
@Test
|
||||||
public void packagesConfiguredWithBothValueAndBasePackages() {
|
public void packagesConfiguredWithBothValueAndBasePackages() {
|
||||||
this.thrown.expect(AnnotationConfigurationException.class);
|
this.thrown.expect(AnnotationConfigurationException.class);
|
||||||
this.thrown.expectMessage(allOf(
|
this.thrown.expectMessage(allOf(containsString("'value'"),
|
||||||
containsString("'value'"),
|
containsString("'basePackages'"), containsString("com.example.foo"),
|
||||||
containsString("'basePackages'"),
|
|
||||||
containsString("com.example.foo"),
|
|
||||||
containsString("com.example.bar")));
|
containsString("com.example.bar")));
|
||||||
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue