Use HttpStatus in ErrorPage
parent
dc30add6c5
commit
8bfe07c730
@ -1,177 +0,0 @@
|
|||||||
# Spring Bootstrap
|
|
||||||
|
|
||||||
Spring Bootstrap is "Spring for Snowboarders". If you are kewl, or
|
|
||||||
just impatient, and you want to use Spring, then this is the place to
|
|
||||||
be. Spring Bootstrap is a toolkit and runtime platform that will get
|
|
||||||
you up and running with Spring-powered, production-grade applications
|
|
||||||
and services with absolute minimum fuss. It takes an opinionated view
|
|
||||||
of the Spring family so that new and existing users can quickly get to
|
|
||||||
the bits they need. Assumes no knowledge of the Java development
|
|
||||||
ecosystem. Absolutely no code generation and no XML (unless you really
|
|
||||||
want it).
|
|
||||||
|
|
||||||
The goals are:
|
|
||||||
|
|
||||||
* Radically faster and widely accessible getting started experience
|
|
||||||
for Spring development
|
|
||||||
* Be opinionated out of the box, but get out of the way quickly as
|
|
||||||
requirements start to diverge from the defaults
|
|
||||||
* Provide a range of non-functional features that are common to large
|
|
||||||
classes of projects (e.g. embedded servers, security, metrics,
|
|
||||||
health checks, externalized configuration)
|
|
||||||
* First class support for REST-ful services, modern web applications,
|
|
||||||
batch jobs, and enterprise integration
|
|
||||||
* Applications that adapt their behaviour or configuration to their
|
|
||||||
environment
|
|
||||||
* Optionally use Groovy features like DSLs and AST transformations to
|
|
||||||
accelerate the implementation of basic business requirements
|
|
||||||
|
|
||||||
## Installing
|
|
||||||
You need to build from source for now, but when it's done instructions will look like this:
|
|
||||||
|
|
||||||
1) Get Java. Download and install the Java SDK from www.java.com
|
|
||||||
|
|
||||||
2) Get Spring
|
|
||||||
|
|
||||||
$ curl -s try.spring.io | bash
|
|
||||||
|
|
||||||
or use the Windows installer
|
|
||||||
|
|
||||||
3) Get to Work!
|
|
||||||
|
|
||||||
$ cat > app.groovy
|
|
||||||
@Controller
|
|
||||||
class ThisWillActuallyRun {
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
String home() {
|
|
||||||
return "Hello World!"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$ spring run app.groovy
|
|
||||||
$ curl localhost:8080
|
|
||||||
Hello World!
|
|
||||||
|
|
||||||
|
|
||||||
## What? It's Groovy then? or like Grails? or another Roo?
|
|
||||||
|
|
||||||
There is a command line tool that uses Groovy underneath so that we
|
|
||||||
can present simple snippets that can just run just like the slimline
|
|
||||||
`app.groovy` example above. Groovy makes this really easy.
|
|
||||||
|
|
||||||
If you don't want to use the command line tool, or you would rather
|
|
||||||
work using Java and an IDE you can. Just add a `main()` method that
|
|
||||||
calls `SpringApplication` and add `@EnableAutoConfiguration`:
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.*;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.bootstrap.context.annotation.*;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
public class SampleController {
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
String home() {
|
|
||||||
return "Hello World!"
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
SpringApplication.run(SampleController.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
## Spring Bootstrap Themes
|
|
||||||
|
|
||||||
There are a number of themes in Bootstrap. Here are the important
|
|
||||||
ones:
|
|
||||||
|
|
||||||
### The Spring CLI
|
|
||||||
|
|
||||||
The 'spring' command line application compiles and runs Groovy source,
|
|
||||||
making it super easy to write the absolute minimum of code to get an
|
|
||||||
application running. Spring CLI can also watch files, automatically
|
|
||||||
recompiling and restarting when they change.
|
|
||||||
|
|
||||||
### Bootstrap Core
|
|
||||||
|
|
||||||
The main library providing features that support the other parts of
|
|
||||||
Spring Bootstrap. Features include:
|
|
||||||
|
|
||||||
* `SpringApplication` - a class with static convenience methods that
|
|
||||||
make it really easy to write a standalone Spring Application. Its
|
|
||||||
sole job is to create and refresh an appropriate Spring
|
|
||||||
`ApplicationContext`.
|
|
||||||
* Embedded web applications with a choice of container (Tomcat or
|
|
||||||
Jetty for now)
|
|
||||||
* `@EnableAutoConfigure` is an annotation that triggers
|
|
||||||
auto-configuration of the Spring context. Auto-configuration
|
|
||||||
attempts to guess what beans a user might want based on their
|
|
||||||
classpath. For example, If a 'HSQLDB' is on the classpath the user
|
|
||||||
probably wants an in-memory database to be
|
|
||||||
defined. Auto-configuration will back away as the user starts to
|
|
||||||
define their own beans.
|
|
||||||
* `@Conditional` is an annotation in Spring 4.0 that allows you to
|
|
||||||
control which parts of an application are used at runtime. Spring
|
|
||||||
Bootstrap provides some concrete implementations of conditional
|
|
||||||
configuration, e.g. `@ConditionalOnBean`,
|
|
||||||
`@ConditionalOnMissingBean` and `@ConditionalOnClass`.
|
|
||||||
|
|
||||||
### Spring Bootstrap Service
|
|
||||||
|
|
||||||
<!-- FIXME: change the name -->
|
|
||||||
|
|
||||||
Spring Bootstrap Service uses auto-configuration features to decorate
|
|
||||||
your application with features that make it instantly deployable and
|
|
||||||
supportable in production. For instance if you are writing a JSON web
|
|
||||||
service then it will provide a server, security, logging, externalized
|
|
||||||
configuration, management endpoints, an audit abstraction, and more.
|
|
||||||
If you want to switch off the built in features, or extend or replace
|
|
||||||
them, it makes that really easy as well.
|
|
||||||
|
|
||||||
### Spring Bootstrap Applications
|
|
||||||
|
|
||||||
<!-- FIXME: change the name -->
|
|
||||||
|
|
||||||
Spring Bootstrap Applications are a set of convenient dependency
|
|
||||||
descriptors that you can include in your application. You get a
|
|
||||||
one-stop-shop for all the Spring and related technology that you need
|
|
||||||
without having to hunt through sample code and copy paste loads of
|
|
||||||
dependency descriptors. For example, if you want to get started using
|
|
||||||
Spring and JPA for database access just include one dependency in your
|
|
||||||
project, and you are good to go.
|
|
||||||
|
|
||||||
## Building the code
|
|
||||||
Use maven to build the source code.
|
|
||||||
|
|
||||||
$ mvn clean install
|
|
||||||
|
|
||||||
## Importing into eclipse
|
|
||||||
You can use m2e or `maven eclipse:eclipse`.
|
|
||||||
|
|
||||||
Project specific settings are configured for source formatting. If you
|
|
||||||
are using m2e you can follow these steps to install eclipse support
|
|
||||||
for formatting:
|
|
||||||
|
|
||||||
* Select `Install new software` from the `help` menu
|
|
||||||
* Click `Add...` to add a new repository
|
|
||||||
* Click the `Archive...` button
|
|
||||||
* Select `org.eclipse.m2e.maveneclipse.site-0.0.1-SNAPSHOT-site.zip`
|
|
||||||
from the `eclipse` folder in this checkout
|
|
||||||
* Install "Maven Integration for the maven-eclipse-plugin"
|
|
||||||
|
|
||||||
Or if you prefer you can import settings manually from the `/eclipse` folder.
|
|
||||||
|
|
||||||
## Samples
|
|
||||||
The following samples are included. To run use `java -jar target/<archive>.jar`
|
|
||||||
|
|
||||||
* spring-bootstrap-simple-sample - A simple command line application
|
|
||||||
* spring-bootstrap-jetty-sample - Embedded Jetty
|
|
||||||
* spring-bootstrap-tomcat-sample - Embedded Tomcat
|
|
||||||
* spring-bootstrap-service-sample - Simple REST service with production features
|
|
||||||
* spring-batch-sample - Define and run a Batch job in a few lines of code
|
|
||||||
* spring-bootstrap-data-sample - Spring Data JPA + Hibernate + HSQLDB
|
|
||||||
|
|
@ -1,387 +0,0 @@
|
|||||||
<style>
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-collapse:collapse;
|
|
||||||
}
|
|
||||||
table,th, td
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
# Spring Bootstrap Services
|
|
||||||
|
|
||||||
Minimum fuss for getting RESTful services up and running in
|
|
||||||
production, and in other environments.
|
|
||||||
|
|
||||||
|Feature |Implementation |Notes |
|
|
||||||
|---|---|---|
|
|
||||||
|Server |Tomcat or Jetty | Whatever is on the classpath |
|
|
||||||
|REST |Spring MVC | |
|
|
||||||
|Security |Spring Security | If on the classpath |
|
|
||||||
|Logging |Logback, Log4j or JDK | Whatever is on the classpath. Sensible defaults. |
|
|
||||||
|Database |HSQLDB or H2 | Per classpath, or define a DataSource to override |
|
|
||||||
|Externalized configuration | Properties or YAML | Support for Spring profiles. Bind automatically to @Bean. |
|
|
||||||
|Audit | Spring Security and Spring ApplicationEvent |Flexible abstraction with sensible defaults for security events |
|
|
||||||
|Validation | JSR-303 |If on the classpath |
|
|
||||||
|Management endpoints | Spring MVC | Health, basic metrics, request tracing, shutdown, thread dumps |
|
|
||||||
|Error pages | Spring MVC | Sensible defaults based on exception and status code |
|
|
||||||
|JSON |Jackson 2 | |
|
|
||||||
|ORM |Spring Data JPA | If on the classpath |
|
|
||||||
|Batch |Spring Batch | If enabled and on the classpath |
|
|
||||||
|Integration Patterns |Spring Integration | If on the classpath |
|
|
||||||
|
|
||||||
# Getting Started
|
|
||||||
|
|
||||||
You will need Java (6 at least) and a build tool (Maven is what we use
|
|
||||||
below, but you are more than welcome to use gradle). These can be
|
|
||||||
downloaded or installed easily in most operating systems. For Ubuntu:
|
|
||||||
|
|
||||||
$ sudo apt-get install openjdk-6-jdk maven
|
|
||||||
|
|
||||||
<!--FIXME: short instructions for Mac.-->
|
|
||||||
|
|
||||||
## A basic project
|
|
||||||
|
|
||||||
If you are using Maven create a really simple `pom.xml` with 2 dependencies:
|
|
||||||
|
|
||||||
<project>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>com.mycompany</groupId>
|
|
||||||
<artifactId>myproject</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.bootstrap</groupId>
|
|
||||||
<artifactId>spring-bootstrap-applications</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.bootstrap</groupId>
|
|
||||||
<artifactId>spring-bootstrap-web-application</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.bootstrap</groupId>
|
|
||||||
<artifactId>spring-bootstrap-service</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
|
|
||||||
If you like Gradle, that's fine, and you will know what to do with
|
|
||||||
those dependencies. The first dependency adds Spring Bootstrap auto
|
|
||||||
configuration and the Jetty container to your application, and the
|
|
||||||
second one adds some more opinionated stuff like the default
|
|
||||||
management endpoints. If you prefer Tomcat you can just add the
|
|
||||||
embedded Tomcat jars to your classpath instead of Jetty.
|
|
||||||
|
|
||||||
You should be able to run it already:
|
|
||||||
|
|
||||||
$ mvn package
|
|
||||||
$ java -jar target/myproject-1.0.0-SNAPSHOT.jar
|
|
||||||
|
|
||||||
Then in another terminal
|
|
||||||
|
|
||||||
$ curl localhost:8080/healthz
|
|
||||||
ok
|
|
||||||
$ curl localhost:8080/varz
|
|
||||||
{"counter.status.200.healthz":1.0,"gauge.response.healthz":10.0,"mem":120768.0,"mem.free":105012.0,"processors":4.0}
|
|
||||||
|
|
||||||
`/healthz` is the default location for the health endpoint - it tells
|
|
||||||
you if the application is running and healthy. `/varz` is the default
|
|
||||||
location for the metrics endpoint - it gives you basic counts and
|
|
||||||
response timing data by default but there are plenty of ways to
|
|
||||||
customize it. You can also try `/trace` and `/dump` to get some
|
|
||||||
interesting information about how and what your app is doing.
|
|
||||||
|
|
||||||
What about the home page?
|
|
||||||
|
|
||||||
$ curl localhost:8080/
|
|
||||||
{"status": 404, "error": "Not Found", "message": "Not Found"}
|
|
||||||
|
|
||||||
That's OK, we haven't added any business content yet. But it shows
|
|
||||||
that there are sensible defaults built in for rendering HTTP and
|
|
||||||
server-side errors.
|
|
||||||
|
|
||||||
## Adding a business endpoint
|
|
||||||
|
|
||||||
To do something useful to your business you need to add at least one
|
|
||||||
endpoint. An endpoint can be implemented as a Spring MVC
|
|
||||||
`@Controller`, e.g.
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
public class SampleController {
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
public Map<String, String> helloWorld() {
|
|
||||||
return Collections.singletonMap("message", "Hello World");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
SpringApplication.run(SampleController.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
You can launch that straight away using the Spring Bootstrap CLI
|
|
||||||
(without the `@EnableAutoConfiguration` and even without the import
|
|
||||||
statements that your IDE will add if you are using one), or you can
|
|
||||||
use the main method to launch it from your project jar. Just add a
|
|
||||||
`start-class` in the properties section of the `pom` above pointing to
|
|
||||||
the fully qualified name of your `SampleController`, e.g.
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<start-class>com.mycompany.sample.SampleController</start-class>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
and re-package:
|
|
||||||
|
|
||||||
$ mvn package
|
|
||||||
$ java -jar target/myproject-1.0.0-SNAPSHOT.jar
|
|
||||||
$ curl localhost:8080/
|
|
||||||
{"message": "Hello World"}
|
|
||||||
|
|
||||||
## Running the application
|
|
||||||
|
|
||||||
You can package the app and run it as a jar (as above) and that's very
|
|
||||||
convenient for production usage. Or there are other options, many of
|
|
||||||
which are more convenient at development time. Here are a few:
|
|
||||||
|
|
||||||
1. Use the Maven exec plugin, e.g.
|
|
||||||
|
|
||||||
$ mvn exec:java
|
|
||||||
|
|
||||||
2. Run directly in your IDE, e.g. Eclipse or IDEA let you right click
|
|
||||||
on a class and run it.
|
|
||||||
|
|
||||||
3. Use a different Maven plugin.
|
|
||||||
|
|
||||||
4. Find feature in Gradle that does the same thing.
|
|
||||||
|
|
||||||
5. Use the Spring executable. <!--FIXME: document this maybe.-->
|
|
||||||
|
|
||||||
## Externalizing configuration
|
|
||||||
|
|
||||||
Spring Bootstrap likes you to externalize your configuration so you
|
|
||||||
can work with the same application code in different environments. To
|
|
||||||
get started with this you create a file in the root of your classpath
|
|
||||||
(`src/main/resources` if using Maven) - if you like YAML you can call
|
|
||||||
it `application.yml`, e.g.:
|
|
||||||
|
|
||||||
server:
|
|
||||||
port: 9000
|
|
||||||
management:
|
|
||||||
port: 9001
|
|
||||||
logging:
|
|
||||||
file: target/log.out
|
|
||||||
|
|
||||||
or if you like Java `Properties` files, you can call it
|
|
||||||
`application.properties`, e.g.:
|
|
||||||
|
|
||||||
server.port: 9000
|
|
||||||
management.port: 9001
|
|
||||||
logging.file: target/log.out
|
|
||||||
|
|
||||||
Those examples are properties that Spring Bootstrap itself binds to
|
|
||||||
out of the box, so if you make that change and run the app again, you
|
|
||||||
will find the home page on port 9000 instead of 8080:
|
|
||||||
|
|
||||||
$ curl localhost:9000/
|
|
||||||
{"message": "Hello World"}
|
|
||||||
|
|
||||||
and the management endpoints on port 9001 instead of 8080:
|
|
||||||
|
|
||||||
$ curl localhost:9001/healthz
|
|
||||||
ok
|
|
||||||
|
|
||||||
To externalize business configuration you can simply add a default
|
|
||||||
value to your configuration file, e.g.
|
|
||||||
|
|
||||||
server:
|
|
||||||
port: 9000
|
|
||||||
management:
|
|
||||||
port: 9001
|
|
||||||
logging:
|
|
||||||
file: target/log.out
|
|
||||||
service:
|
|
||||||
message: Awesome Message
|
|
||||||
|
|
||||||
and then bind to it in the application code. The simplest way to do
|
|
||||||
that is to simply refer to it in an `@Value` annotation, e.g.
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
public class SampleController {
|
|
||||||
|
|
||||||
@Value("${service.message:Hello World}")
|
|
||||||
private String value = "Goodbye Everypone"
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
public Map<String, String> helloWorld() {
|
|
||||||
return Collections.singletonMap("message", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
That's a little bit confusing because we have provided a message value
|
|
||||||
in three different places - in the external configuration ("Awesome
|
|
||||||
Message"), in the `@Value` annotation after the colon ("Hello World"),
|
|
||||||
and in the filed initializer ("Goodbye Everyone"). That was only to
|
|
||||||
show you how and you only need it once, so it's your choice (it's
|
|
||||||
useful for unit testing to have the Java initializer as well as the
|
|
||||||
external value). Note that the YAML object is flattened using period
|
|
||||||
separators.
|
|
||||||
|
|
||||||
For simple Strings where you have sensible defaults `@Value` is
|
|
||||||
perfect, but if you want more and you like everything strongly typed
|
|
||||||
then you can have Spring bind the properties and validate them
|
|
||||||
automatically in a separate value object. For instance:
|
|
||||||
|
|
||||||
// ServiceProperties.java
|
|
||||||
@ConfigurationProperties(name="service")
|
|
||||||
public class ServiceProperties {
|
|
||||||
private String message;
|
|
||||||
private int value = 0;
|
|
||||||
... getters and setters
|
|
||||||
}
|
|
||||||
|
|
||||||
// SampleController.java
|
|
||||||
@Controller
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
@EnableConfigurationProperties(ServiceProperties.class)
|
|
||||||
public class SampleController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ServiceProperties properties;
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
public Map<String, String> helloWorld() {
|
|
||||||
return Collections.singletonMap("message", properties.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
When you ask to
|
|
||||||
`@EnableConfigurationProperties(ServiceProperties.class)` you are
|
|
||||||
saying you want a bean of type `ServiceProperties` and that you want
|
|
||||||
to bind it to the Spring Environment. The Spring Environment is a
|
|
||||||
collection of name-value pairs taken from (in order of decreasing
|
|
||||||
precedence) 1) the command line, 2) the external configuration file,
|
|
||||||
3) System properties, 4) the OS environment. Validation is done based
|
|
||||||
on JSR-303 annotations by default provided that library (and an
|
|
||||||
implementation) is on the classpath.
|
|
||||||
|
|
||||||
## Adding security
|
|
||||||
|
|
||||||
If you add Spring Security java config to your runtime classpath you
|
|
||||||
will enable HTTP basic authentication by default on all the endpoints.
|
|
||||||
In the `pom.xml` it would look like this:
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-javaconfig</artifactId>
|
|
||||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
(Spring Security java config is still work in progress so we have used
|
|
||||||
a snapshot. Beware of sudden changes.)
|
|
||||||
|
|
||||||
<!--FIXME: update Spring Security to full release -->
|
|
||||||
|
|
||||||
Try it out:
|
|
||||||
|
|
||||||
$ curl localhost:8080/
|
|
||||||
{"status": 403, "error": "Forbidden", "message": "Access Denied"}
|
|
||||||
$ curl user:password@localhost:8080/
|
|
||||||
{"message": "Hello World"}
|
|
||||||
|
|
||||||
The default auto configuration has an in-memory user database with one
|
|
||||||
entry. If you want to extend or expand that, or point to a database
|
|
||||||
or directory server, you only need to provide a `@Bean` definition for
|
|
||||||
an `AuthenticationManager`, e.g. in your `SampleController`:
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthenticationManager authenticationManager() throws Exception {
|
|
||||||
return new AuthenticationBuilder().inMemoryAuthentication().withUser("client")
|
|
||||||
.password("secret").roles("USER").and().and().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
Try it out:
|
|
||||||
|
|
||||||
$ curl user:password@localhost:8080/
|
|
||||||
{"status": 403, "error": "Forbidden", "message": "Access Denied"}
|
|
||||||
$ curl client:secret@localhost:8080/
|
|
||||||
{"message": "Hello World"}
|
|
||||||
|
|
||||||
## Adding a database
|
|
||||||
|
|
||||||
Just add `spring-jdbc` and an embedded database to your dependencies:
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-jdbc</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hsqldb</groupId>
|
|
||||||
<artifactId>hsqldb</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
Then you will be able to inject a `DataSource` into your controller:
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
@EnableConfigurationProperties(ServiceProperties.class)
|
|
||||||
public class SampleController {
|
|
||||||
|
|
||||||
private JdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SampleController(DataSource dataSource) {
|
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
|
||||||
@ResponseBody
|
|
||||||
public Map<String, String> helloWorld() {
|
|
||||||
return jdbcTemplate.queryForMap("SELECT * FROM MESSAGES WHERE ID=?", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
The app will run (going back to the default security configuration):
|
|
||||||
|
|
||||||
$ curl user:password@localhost:8080/
|
|
||||||
{"error":"Internal Server Error", "status":500, "exception":...}
|
|
||||||
|
|
||||||
but there's no data in the database yet and the `MESSAGES` table
|
|
||||||
doesn't even exist, so there's an error. One easy way to fix it is
|
|
||||||
to provide a `schema.sql` script in the root of the classpath, e.g.
|
|
||||||
|
|
||||||
create table MESSAGES (
|
|
||||||
ID BIGINT NOT NULL PRIMARY KEY,
|
|
||||||
MESSAGE VARCHAR(255)
|
|
||||||
);
|
|
||||||
INSERT INTO MESSAGES (ID, MESSAGE) VALUES (0, 'Hello Phil');
|
|
||||||
|
|
||||||
Now when you run the app you get a sensible response:
|
|
||||||
|
|
||||||
$ curl user:password@localhost:8080/
|
|
||||||
{"ID":0, "MESSAGE":"Hello Phil"}
|
|
||||||
|
|
||||||
Obviously, this is only the start, but hopefully you have a good grasp
|
|
||||||
of the basics and are ready to try it out yourself.
|
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2013 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.bootstrap.actuate.properties;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
|
import org.springframework.bootstrap.bind.RelaxedDataBinder;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Externalized configuration for server properties
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ServerPropertiesTests {
|
||||||
|
|
||||||
|
private ServerProperties properties = new ServerProperties();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddressBinding() throws Exception {
|
||||||
|
RelaxedDataBinder binder = new RelaxedDataBinder(this.properties, "server");
|
||||||
|
binder.bind(new MutablePropertyValues(Collections.singletonMap("server.address",
|
||||||
|
"127.0.0.1")));
|
||||||
|
assertFalse(binder.getBindingResult().hasErrors());
|
||||||
|
assertEquals(InetAddress.getLocalHost(), this.properties.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPortBinding() throws Exception {
|
||||||
|
new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues(
|
||||||
|
Collections.singletonMap("server.port", "9000")));
|
||||||
|
assertEquals(9000, this.properties.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue