├── .gitignore
├── README.md
├── pom.xml
├── spring-boot-resteasy-parent
└── pom.xml
├── spring-boot-resteasy
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── boot
│ │ │ └── resteasy
│ │ │ └── autoconfigure
│ │ │ └── ResteasyAutoConfiguration.java
│ └── resources
│ │ └── META-INF
│ │ └── spring.factories
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── boot
│ └── resteasy
│ └── autoconfigure
│ └── ResteasyAutoConfigurationTests.java
└── spring-boot-sample-resteasy
├── pom.xml
└── src
├── main
├── java
│ └── sample
│ │ └── resteasy
│ │ ├── Endpoint.java
│ │ └── SampleResteasyApplication.java
└── resources
│ └── application.properties
└── test
└── java
└── sample
└── resteasy
└── SampleResteasyApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings
4 | target
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This project provides RESTEasy auto-configuration for a Spring Boot application.
2 |
3 | # Getting started
4 |
5 | Build this project and install it into your Maven repository:
6 |
7 | ```
8 | $ mvn install
9 | ```
10 |
11 | You should then add a dependency on `org.springframework.boot:spring-boot-resteasy:1.0.0.BUILD-SNAPSHOT`
12 | in your application's `build.gradle` or `pom.xml`.
13 |
14 | Now create a Spring Boot application with auto-configuration and component scanning enabled:
15 |
16 | ```java
17 | import org.springframework.boot.SpringApplication;
18 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
19 | import org.springframework.context.annotation.ComponentScan;
20 |
21 | @ComponentScan
22 | @EnableAutoConfiguration
23 | public class Application {
24 |
25 | public static void main(String[] args) {
26 | SpringApplication.run(Application.class, args);
27 | }
28 |
29 | }
30 | ```
31 |
32 | Next, create a REST endpoint Spring bean annotated using JAX-RS. For example:
33 |
34 | ```java
35 | import javax.ws.rs.GET;
36 | import javax.ws.rs.Path;
37 |
38 | import org.springframework.stereotype.Component;
39 |
40 | @Component
41 | @Path("/hello")
42 | public class Endpoint {
43 |
44 | private String msg;
45 |
46 | @GET
47 | public String message() {
48 | return "Hello " + msg;
49 | }
50 |
51 | }
52 | ```
53 |
54 | That's it! Since `Endpoint` is a Spring `@Component` its lifecycle is managed by Spring and you can
55 | use `@Autowired` dependencies and inject external configuration with `@Value`. Refer to
56 | `spring-boot-sample-resteasy` for a detailed example. It's an executable jar that can be built with
57 | `mvn package` and run with `java -jar`.
58 |
59 | # Limitations
60 |
61 | There's [a bug][1] in RESTEasy 3.0.10.Final that breaks its integration with Spring. The latest working
62 | version of RESTEasy is 3.0.9.Final.
63 |
64 | [1]: https://github.com/resteasy/Resteasy/pull/615
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.springframework.boot
7 | spring-boot-parent
8 | 1.2.1.RELEASE
9 |
10 |
11 | spring-boot-resteasy-build
12 | 1.0.0.BUILD-SNAPSHOT
13 | pom
14 | Spring Boot RESTEasy build
15 | Spring Boot RESTEasy build
16 |
17 |
18 | 3.0.0
19 |
20 |
21 |
22 | ${basedir}
23 |
24 |
25 |
26 | spring-boot-resteasy
27 | spring-boot-resteasy-parent
28 | spring-boot-sample-resteasy
29 |
30 |
31 |
--------------------------------------------------------------------------------
/spring-boot-resteasy-parent/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 1.2.1.RELEASE
10 |
11 |
12 |
13 | spring-boot-resteasy-parent
14 | 1.0.0.BUILD-SNAPSHOT
15 | pom
16 | Spring Boot RESTEasy parent
17 | Spring Boot RESTEasy parent
18 |
19 |
20 | 1.6
21 | 3.0.9.Final
22 |
23 |
24 |
25 |
26 |
27 | org.jboss.resteasy
28 | resteasy-spring
29 | ${resteasy.version}
30 |
31 |
32 |
33 |
34 | http://spring.io
35 |
36 | Pivotal
37 | http://spring.io
38 |
39 |
40 |
41 | Apache 2.0
42 | http://www.apache.org/licenses/LICENSE-2.0.txt
43 |
44 |
45 |
46 |
47 | http://github.com/wilkinsona/spring-boot-resteasy
48 | scm:git:git://github.com/wilkinsona/spring-boot-resteasy.git
49 | scm:git:ssh://git@github.com/wilkinsona/spring-boot-resteasy.git
50 |
51 |
52 |
53 |
54 | wilkinsona
55 | Andy Wilkinson
56 | awilkinson@pivotal.io
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/spring-boot-resteasy/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.springframework.boot
8 | spring-boot-resteasy-parent
9 | 1.0.0.BUILD-SNAPSHOT
10 | ../spring-boot-resteasy-parent
11 |
12 |
13 | spring-boot-resteasy
14 | Spring Boot RESTEasy
15 | Spring Boot auto-configuration for RESTEasy
16 |
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter
21 |
22 |
23 | org.springframework
24 | spring-webmvc
25 |
26 |
27 | org.jboss.resteasy
28 | resteasy-spring
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-web
33 | test
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-test
38 | test
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/spring-boot-resteasy/src/main/java/org/springframework/boot/resteasy/autoconfigure/ResteasyAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.boot.resteasy.autoconfigure;
18 |
19 | import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
20 | import org.jboss.resteasy.spi.ResteasyDeployment;
21 | import org.jboss.resteasy.spi.ResteasyProviderFactory;
22 | import org.jboss.resteasy.springmvc.ResteasyHandlerAdapter;
23 | import org.jboss.resteasy.springmvc.ResteasyHandlerMapping;
24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
26 | import org.springframework.boot.context.properties.ConfigurationProperties;
27 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
28 | import org.springframework.context.annotation.Bean;
29 | import org.springframework.context.annotation.Configuration;
30 | import org.springframework.core.Ordered;
31 |
32 | @ConditionalOnClass(ResteasyHandlerMapping.class)
33 | @EnableConfigurationProperties
34 | @Configuration
35 | public class ResteasyAutoConfiguration {
36 |
37 | @ConditionalOnMissingBean(ResteasyDeployment.class)
38 | @ConfigurationProperties(prefix="resteasy.deployment")
39 | @Bean(initMethod="start", destroyMethod="stop")
40 | public ResteasyDeployment resteasyDeployment(final SpringBeanProcessor springBeanProcessor) {
41 | ResteasyDeployment resteasyDeployment = new ResteasyDeployment() {
42 | public void start() {
43 | super.start();
44 | if (springBeanProcessor.getRegistry() == null) {
45 | springBeanProcessor.setRegistry(this.getRegistry());
46 | }
47 | }
48 | };
49 | resteasyDeployment.setProviderFactory(springBeanProcessor.getProviderFactory());
50 | return resteasyDeployment;
51 | }
52 |
53 | @ConditionalOnMissingBean(SpringBeanProcessor.class)
54 | @Bean
55 | public SpringBeanProcessor springBeanProcessor() {
56 | SpringBeanProcessor springBeanProcessor = new SpringBeanProcessor();
57 | springBeanProcessor.setProviderFactory(new ResteasyProviderFactory());
58 | return springBeanProcessor;
59 | }
60 |
61 | @ConditionalOnMissingBean(ResteasyHandlerMapping.class)
62 | @Bean
63 | public ResteasyHandlerMapping resteasyHandlerMapper(ResteasyDeployment deployment) {
64 | ResteasyHandlerMapping handlerMapping = new ResteasyHandlerMapping(deployment);
65 | handlerMapping.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
66 | return handlerMapping;
67 | }
68 |
69 | @ConditionalOnMissingBean(ResteasyHandlerAdapter.class)
70 | @Bean
71 | public ResteasyHandlerAdapter resteasyHandlerAdapter(ResteasyDeployment deployment) {
72 | return new ResteasyHandlerAdapter(deployment);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/spring-boot-resteasy/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | org.springframework.boot.resteasy.autoconfigure.ResteasyAutoConfiguration
--------------------------------------------------------------------------------
/spring-boot-resteasy/src/test/java/org/springframework/boot/resteasy/autoconfigure/ResteasyAutoConfigurationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.boot.resteasy.autoconfigure;
18 |
19 | import static org.junit.Assert.assertTrue;
20 |
21 | import org.jboss.resteasy.spi.ResteasyDeployment;
22 | import org.jboss.resteasy.springmvc.ResteasyHandlerAdapter;
23 | import org.jboss.resteasy.springmvc.ResteasyHandlerMapping;
24 | import org.junit.After;
25 | import org.junit.Test;
26 | import org.springframework.boot.test.EnvironmentTestUtils;
27 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
28 |
29 | public class ResteasyAutoConfigurationTests {
30 |
31 | private AnnotationConfigApplicationContext context;
32 |
33 | @After
34 | public void tearDown() {
35 | if (this.context != null) {
36 | this.context.close();
37 | }
38 | }
39 |
40 | @Test
41 | public void defaultBeanCreation() {
42 | this.context = new AnnotationConfigApplicationContext(ResteasyAutoConfiguration.class);
43 |
44 | this.context.getBean(ResteasyDeployment.class);
45 | this.context.getBean(ResteasyHandlerAdapter.class);
46 | this.context.getBean(ResteasyHandlerMapping.class);
47 | }
48 |
49 | @Test
50 | public void customizedDeploymentConfiguration() {
51 | this.context = new AnnotationConfigApplicationContext();
52 | this.context.register(ResteasyAutoConfiguration.class);
53 | EnvironmentTestUtils.addEnvironment(this.context, "resteasy.deployment.async_job_service_enabled:true");
54 | this.context.refresh();
55 |
56 | ResteasyDeployment deployment = this.context.getBean(ResteasyDeployment.class);
57 | assertTrue(deployment.isAsyncJobServiceEnabled());
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/spring-boot-sample-resteasy/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 1.2.1.RELEASE
10 |
11 |
12 |
13 | spring-boot-sample-resteasy
14 | 1.0.0.BUILD-SNAPSHOT
15 | Spring Boot RESTEasy sample
16 | Spring Boot RESTEasy sample
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-resteasy
22 | 1.0.0.BUILD-SNAPSHOT
23 |
24 |
25 | org.jboss.resteasy
26 | resteasy-spring
27 | 3.0.9.Final
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-test
36 | test
37 |
38 |
39 |
40 |
41 | sample.resteasy.SampleResteasyApplication
42 | 1.6
43 |
44 |
45 |
--------------------------------------------------------------------------------
/spring-boot-sample-resteasy/src/main/java/sample/resteasy/Endpoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package sample.resteasy;
18 |
19 | import javax.ws.rs.GET;
20 | import javax.ws.rs.Path;
21 |
22 | import org.springframework.beans.factory.annotation.Value;
23 | import org.springframework.stereotype.Component;
24 |
25 | @Component
26 | @Path("/hello")
27 | public class Endpoint {
28 |
29 | @Value("${message:World}")
30 | private String msg;
31 |
32 | @GET
33 | public String message() {
34 | return "Hello " + msg;
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/spring-boot-sample-resteasy/src/main/java/sample/resteasy/SampleResteasyApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package sample.resteasy;
18 |
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
21 | import org.springframework.context.annotation.ComponentScan;
22 |
23 | @ComponentScan
24 | @EnableAutoConfiguration
25 | public class SampleResteasyApplication {
26 |
27 | public static void main(String[] args) {
28 | SpringApplication.run(SampleResteasyApplication.class, args);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/spring-boot-sample-resteasy/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | resteasy.deployment.async_job_service_enabled=true
--------------------------------------------------------------------------------
/spring-boot-sample-resteasy/src/test/java/sample/resteasy/SampleResteasyApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package sample.resteasy;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | import java.net.URI;
22 |
23 | import org.junit.Test;
24 | import org.junit.runner.RunWith;
25 | import org.springframework.beans.factory.annotation.Value;
26 | import org.springframework.boot.test.IntegrationTest;
27 | import org.springframework.boot.test.SpringApplicationConfiguration;
28 | import org.springframework.boot.test.TestRestTemplate;
29 | import org.springframework.http.HttpStatus;
30 | import org.springframework.http.ResponseEntity;
31 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
32 | import org.springframework.test.context.web.WebAppConfiguration;
33 |
34 |
35 | @RunWith(SpringJUnit4ClassRunner.class)
36 | @SpringApplicationConfiguration(classes = SampleResteasyApplication.class)
37 | @WebAppConfiguration
38 | @IntegrationTest("server.port:0")
39 | public class SampleResteasyApplicationTests {
40 |
41 | @Value("${local.server.port}")
42 | private int port;
43 |
44 | @Test
45 | public void synchronousRequest() {
46 | ResponseEntity response = new TestRestTemplate()
47 | .getForEntity("http://localhost:" + port + "/hello", String.class);
48 | assertEquals(HttpStatus.OK, response.getStatusCode());
49 | assertEquals("Hello World", response.getBody());
50 |
51 | }
52 |
53 | @Test
54 | public void asynchronousRequest() {
55 | TestRestTemplate rest = new TestRestTemplate();
56 | ResponseEntity response = rest
57 | .getForEntity("http://localhost:" + port + "/hello?asynch=true", String.class);
58 | assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
59 |
60 | URI jobLocation = response.getHeaders().getLocation();
61 |
62 | HttpStatus jobStatus = HttpStatus.ACCEPTED;
63 | ResponseEntity jobResponse = null;
64 |
65 | while (jobStatus == HttpStatus.ACCEPTED) {
66 | jobResponse = rest.getForEntity(jobLocation, String.class);
67 | jobStatus = jobResponse.getStatusCode();
68 | }
69 |
70 | assertEquals(HttpStatus.OK, jobResponse.getStatusCode());
71 | assertEquals("Hello World", jobResponse.getBody());
72 |
73 | rest.delete(jobLocation);
74 |
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------