diff --git a/spring-cucumber-demo/pom.xml b/spring-cucumber-demo/pom.xml
new file mode 100644
index 0000000000..fca8835194
--- /dev/null
+++ b/spring-cucumber-demo/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-cucumber-demo
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.5.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+ 1.2.4
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ info.cukes
+ cucumber-core
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-java
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-junit
+ ${cucumber.java.version}
+ test
+
+
+
+ info.cukes
+ cucumber-spring
+ ${cucumber.java.version}
+ test
+
+
+
+
+ org.apache.commons
+ commons-io
+ 1.3.2
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-cucumber-demo/src/main/java/com/baeldung/BaeldungController.java b/spring-cucumber-demo/src/main/java/com/baeldung/BaeldungController.java
new file mode 100644
index 0000000000..0bb249b814
--- /dev/null
+++ b/spring-cucumber-demo/src/main/java/com/baeldung/BaeldungController.java
@@ -0,0 +1,22 @@
+package com.baeldung;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class BaeldungController {
+
+ @RequestMapping(method={RequestMethod.GET},value={"/hello"})
+ public String sayHello(HttpServletResponse response){
+ return "hello";
+ }
+
+ @RequestMapping(method={RequestMethod.POST},value={"/baeldung"})
+ public String sayHelloPost(HttpServletResponse response){
+ return "hello";
+ }
+
+}
diff --git a/spring-cucumber-demo/src/main/java/com/baeldung/SpringDemoApplication.java b/spring-cucumber-demo/src/main/java/com/baeldung/SpringDemoApplication.java
new file mode 100644
index 0000000000..d490b23aa2
--- /dev/null
+++ b/spring-cucumber-demo/src/main/java/com/baeldung/SpringDemoApplication.java
@@ -0,0 +1,19 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.web.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class SpringDemoApplication extends SpringBootServletInitializer{
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringDemoApplication.class, args);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
+ return application.sources(SpringDemoApplication.class);
+ }
+}
diff --git a/spring-cucumber-demo/src/main/java/com/baeldung/VersionController.java b/spring-cucumber-demo/src/main/java/com/baeldung/VersionController.java
new file mode 100644
index 0000000000..7c72a78a05
--- /dev/null
+++ b/spring-cucumber-demo/src/main/java/com/baeldung/VersionController.java
@@ -0,0 +1,14 @@
+package com.baeldung;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class VersionController {
+
+ @RequestMapping(method={RequestMethod.GET},value={"/version"})
+ public String getVersion(){
+ return "1.0";
+ }
+}
diff --git a/spring-cucumber-demo/src/main/resources/application.properties b/spring-cucumber-demo/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/CucumberTest.java b/spring-cucumber-demo/src/test/java/com/baeldung/CucumberTest.java
new file mode 100644
index 0000000000..feb340d00d
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/CucumberTest.java
@@ -0,0 +1,11 @@
+package com.baeldung;
+
+import cucumber.api.CucumberOptions;
+import cucumber.api.junit.Cucumber;
+import org.junit.runner.RunWith;
+
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "src/test/resources")
+public class CucumberTest{
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/HeaderSettingRequestCallback.java b/spring-cucumber-demo/src/test/java/com/baeldung/HeaderSettingRequestCallback.java
new file mode 100644
index 0000000000..719ce59892
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/HeaderSettingRequestCallback.java
@@ -0,0 +1,34 @@
+package com.baeldung;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpRequest;
+import org.springframework.web.client.RequestCallback;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+public class HeaderSettingRequestCallback implements RequestCallback{
+ final Map requestHeaders;
+
+ private String body;
+
+ public HeaderSettingRequestCallback(final Map headers){
+ this.requestHeaders = headers;
+ }
+
+ public void setBody(final String postBody ){
+ this.body = postBody;
+ }
+
+ @Override
+ public void doWithRequest(ClientHttpRequest request) throws IOException{
+ final HttpHeaders clientHeaders = request.getHeaders();
+ for( final Map.Entry entry : requestHeaders.entrySet() ){
+ clientHeaders.add(entry.getKey(),entry.getValue());
+ }
+ if( null != body ){
+ request.getBody().write( body.getBytes() );
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/OtherDefs.java b/spring-cucumber-demo/src/test/java/com/baeldung/OtherDefs.java
new file mode 100644
index 0000000000..428343d06a
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/OtherDefs.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import cucumber.api.java.en.Given;
+import cucumber.api.java.en.When;
+
+
+public class OtherDefs extends SpringIntegrationTest{
+ @When("^the client calls /baeldung$")
+ public void the_client_issues_POST_hello() throws Throwable{
+ executePost("http://localhost:8080/baeldung");
+ }
+
+ @Given("^the client calls /hello$")
+ public void the_client_issues_GET_hello() throws Throwable{
+ executeGet("http://localhost:8080/hello");
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/ResponseResults.java b/spring-cucumber-demo/src/test/java/com/baeldung/ResponseResults.java
new file mode 100644
index 0000000000..c7cee44222
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/ResponseResults.java
@@ -0,0 +1,34 @@
+package com.baeldung;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.http.client.ClientHttpResponse;
+
+
+public class ResponseResults{
+ private final ClientHttpResponse theResponse;
+ private final String body;
+
+ protected ResponseResults(final ClientHttpResponse response) throws IOException{
+ this.theResponse = response;
+ final InputStream bodyInputStream = response.getBody();
+ if (null == bodyInputStream){
+ this.body = "{}";
+ }else{
+ final StringWriter stringWriter = new StringWriter();
+ IOUtils.copy(bodyInputStream, stringWriter);
+ this.body = stringWriter.toString();
+ }
+ }
+
+ protected ClientHttpResponse getTheResponse(){
+ return theResponse;
+ }
+
+ protected String getBody(){
+ return body;
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber-demo/src/test/java/com/baeldung/SpringIntegrationTest.java
new file mode 100644
index 0000000000..dc78ba8ce3
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/SpringIntegrationTest.java
@@ -0,0 +1,102 @@
+package com.baeldung;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationContextLoader;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.ResponseExtractor;
+import org.springframework.web.client.RestTemplate;
+
+
+//@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = SpringDemoApplication.class, loader = SpringApplicationContextLoader.class)
+@WebAppConfiguration
+@IntegrationTest
+public class SpringIntegrationTest {
+ protected static ResponseResults latestResponse = null;
+
+ protected RestTemplate restTemplate = null;
+
+ protected void executeGet(String url) throws IOException{
+ final Map headers = new HashMap<>();
+ headers.put("Accept","application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ if (restTemplate == null){
+ restTemplate = new RestTemplate();
+ }
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate.execute(url,
+ HttpMethod.GET,
+ requestCallback,
+ new ResponseExtractor(){
+ @Override
+ public ResponseResults extractData(ClientHttpResponse response) throws IOException {
+ if (errorHandler.hadError){
+ return (errorHandler.getResults());
+ } else{
+ return (new ResponseResults(response));
+ }
+ }
+ });
+
+ }
+
+ protected void executePost(String url) throws IOException{
+ final Map headers = new HashMap<>();
+ headers.put("Accept","application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ if (restTemplate == null){
+ restTemplate = new RestTemplate();
+ }
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate.execute(url,
+ HttpMethod.POST,
+ requestCallback,
+ new ResponseExtractor(){
+ @Override
+ public ResponseResults extractData(ClientHttpResponse response) throws IOException {
+ if (errorHandler.hadError){
+ return (errorHandler.getResults());
+ } else{
+ return (new ResponseResults(response));
+ }
+ }
+ });
+
+ }
+
+ private class ResponseResultErrorHandler implements ResponseErrorHandler{
+ private ResponseResults results = null;
+ private Boolean hadError = false;
+
+ private ResponseResults getResults(){
+ return results;
+ }
+
+ @Override
+ public boolean hasError(ClientHttpResponse response) throws IOException{
+ hadError = response.getRawStatusCode() >= 400;
+ return hadError;
+ }
+
+ @Override
+ public void handleError(ClientHttpResponse response) throws IOException {
+ results = new ResponseResults(response);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/java/com/baeldung/StepDefs.java b/spring-cucumber-demo/src/test/java/com/baeldung/StepDefs.java
new file mode 100644
index 0000000000..98a55af4c0
--- /dev/null
+++ b/spring-cucumber-demo/src/test/java/com/baeldung/StepDefs.java
@@ -0,0 +1,28 @@
+package com.baeldung;
+
+import cucumber.api.java.en.And;
+import cucumber.api.java.en.Then;
+import cucumber.api.java.en.When;
+import org.springframework.http.HttpStatus;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+public class StepDefs extends SpringIntegrationTest{
+
+ @When("^the client calls /version$")
+ public void the_client_issues_GET_version() throws Throwable{
+ executeGet("http://localhost:8080/version");
+ }
+
+ @Then("^the client receives status code of (\\d+)$")
+ public void the_client_receives_status_code_of(int statusCode) throws Throwable{
+ final HttpStatus currentStatusCode = latestResponse.getTheResponse().getStatusCode();
+ assertThat("status code is incorrect : "+ latestResponse.getBody(), currentStatusCode.value(), is(statusCode) );
+ }
+
+ @And("^the client receives server version (.+)$")
+ public void the_client_receives_server_version_body(String version) throws Throwable{
+ assertThat(latestResponse.getBody(), is(version)) ;
+ }
+}
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/resources/baelung.feature b/spring-cucumber-demo/src/test/resources/baelung.feature
new file mode 100644
index 0000000000..21f18db3a4
--- /dev/null
+++ b/spring-cucumber-demo/src/test/resources/baelung.feature
@@ -0,0 +1,9 @@
+Feature: the message can be retrieved
+ Scenario: client makes call to POST /baeldung
+ When the client calls /baeldung
+ Then the client receives status code of 200
+ And the client receives server version hello
+ Scenario: client makes call to GET /hello
+ Given the client calls /hello
+ When the client receives status code of 200
+ Then the client receives server version hello
\ No newline at end of file
diff --git a/spring-cucumber-demo/src/test/resources/version.feature b/spring-cucumber-demo/src/test/resources/version.feature
new file mode 100644
index 0000000000..12f77137ff
--- /dev/null
+++ b/spring-cucumber-demo/src/test/resources/version.feature
@@ -0,0 +1,6 @@
+Feature: the version can be retrieved
+ Scenario: client makes call to GET /version
+ When the client calls /version
+ Then the client receives status code of 200
+ And the client receives server version 1.0
+
\ No newline at end of file