diff --git a/spring-rest/pom.xml b/spring-rest/pom.xml index c12028149d..6065d7e529 100644 --- a/spring-rest/pom.xml +++ b/spring-rest/pom.xml @@ -1,321 +1,329 @@ - 4.0.0 - com.baeldung - spring-rest - 0.1-SNAPSHOT - spring-rest - war + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung + spring-rest + 0.1-SNAPSHOT + spring-rest + war - - parent-boot-4 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-4 - + + parent-boot-4 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-4 + - + - + - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-devtools - - - org.springframework.boot - spring-boot-test - + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-test + - + - - org.springframework - spring-web - - - commons-logging - commons-logging - - - - - org.springframework - spring-webmvc - - - org.springframework - spring-oxm - + + org.springframework + spring-web + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + + + org.springframework + spring-oxm + - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + - - javax.servlet - javax.servlet-api - provided - + + javax.servlet + javax.servlet-api + provided + - - javax.servlet - jstl - runtime - + + javax.servlet + jstl + runtime + - + - - com.fasterxml.jackson.core - jackson-databind - + + com.fasterxml.jackson.core + jackson-databind + - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml - + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + - - com.thoughtworks.xstream - xstream - ${xstream.version} - + + com.thoughtworks.xstream + xstream + ${xstream.version} + - + - - com.google.guava - guava - ${guava.version} - + + com.google.guava + guava + ${guava.version} + - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - + - - com.squareup.okhttp3 - okhttp - ${com.squareup.okhttp3.version} - + + com.squareup.okhttp3 + okhttp + ${com.squareup.okhttp3.version} + - + - - org.hamcrest - hamcrest-core - test - - - org.hamcrest - hamcrest-library - test - + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + - - org.mockito - mockito-core - test - + + org.mockito + mockito-core + test + - - org.springframework - spring-test - + + org.springframework + spring-test + - - - com.google.protobuf - protobuf-java - ${protobuf-java.version} - - - com.googlecode.protobuf-java-format - protobuf-java-format - ${protobuf-java-format.version} - + + + com.google.protobuf + protobuf-java + ${protobuf-java.version} + + + com.googlecode.protobuf-java-format + protobuf-java-format + ${protobuf-java-format.version} + - - com.esotericsoftware - kryo - ${kryo.version} - + + com.esotericsoftware + kryo + ${kryo.version} + - - com.jayway.jsonpath - json-path - + + com.jayway.jsonpath + json-path + - - - spring-rest - - - src/main/resources - true - - + + + commons-io + commons-io + 2.4 + - - - org.springframework.boot - spring-boot-maven-plugin - - true - - - - org.apache.maven.plugins - maven-war-plugin - + - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - tomcat8x - embedded - - - - - - - 8082 - - - - + + spring-rest + + + src/main/resources + true + + - + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + org.apache.maven.plugins + maven-war-plugin + - + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + tomcat8x + embedded + + + + + + + 8082 + + + + - + - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - none - - - **/*IntegrationTest.java - - - - - + - - - + - - live - - - - org.codehaus.cargo - cargo-maven2-plugin - - - start-server - pre-integration-test - - start - - - - stop-server - post-integration-test - - stop - - - - + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*IntegrationTest.java + + + + + - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - none - - - **/*LiveTest.java - - - cargo - - - - - + + + - - - + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + - + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + - - 1.3.2 - 4.0.0 - 1.4 - 3.1.0 - 3.5 - 1.4.9 + + + - - 20.0 + - - 1.6.0 - 3.0.4 + + 1.3.2 + 4.0.0 + 1.4 + 3.1.0 + 3.5 + 1.4.9 - - 3.4.1 + + 20.0 - 2.2.0 - + + 1.6.0 + 3.0.4 + + + 3.4.1 + + 2.2.0 + diff --git a/spring-rest/src/main/java/com/baeldung/web/log/app/Application.java b/spring-rest/src/main/java/com/baeldung/web/log/app/Application.java new file mode 100644 index 0000000000..9bdbbd0d9f --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/app/Application.java @@ -0,0 +1,18 @@ +package com.baeldung.web.log.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; + +@EnableAutoConfiguration +@ComponentScan("com.baeldung.web.log") +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + + public static void main(final String[] args) { + SpringApplication.run(Application.class, args); + } + +} \ No newline at end of file diff --git a/spring-rest/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java b/spring-rest/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java new file mode 100644 index 0000000000..831d236edd --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java @@ -0,0 +1,44 @@ +package com.baeldung.web.log.app; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import org.springframework.web.util.ContentCachingRequestWrapper; + +import com.baeldung.web.log.util.RequestLoggingUtil; + +@Component +public class TaxiFareRequestInterceptor extends HandlerInterceptorAdapter { + + Logger LOGGER = LoggerFactory.getLogger(TaxiFareRequestInterceptor.class); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String postData = null; + HttpServletRequest requestCacheWrapperObject = null; + try { + // Uncomment to produce the stream closed issue + // postData = RequestLoggingUtil.getStringFromInputStream(request.getInputStream()); + + // To overcome request stream closed issue + requestCacheWrapperObject = new ContentCachingRequestWrapper(request); + requestCacheWrapperObject.getParameterMap(); + } catch (Exception exception) { + exception.printStackTrace(); + } finally { + postData = RequestLoggingUtil.readPayload(requestCacheWrapperObject); + LOGGER.info("REQUEST DATA: " + postData); + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + LOGGER.info("RESPONSE: " + response.getStatus()); + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java b/spring-rest/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java new file mode 100644 index 0000000000..bc9ad1cf84 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.web.log.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.CommonsRequestLoggingFilter; + +@Configuration +public class RequestLoggingFilterConfig { + + @Bean + public CommonsRequestLoggingFilter logFilter() { + CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); + filter.setIncludeQueryString(true); + filter.setIncludePayload(true); + filter.setMaxPayloadLength(10000); + filter.setIncludeHeaders(false); + filter.setAfterMessagePrefix("REQUEST DATA : "); + return filter; + } +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java b/spring-rest/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java new file mode 100644 index 0000000000..fa26706ff0 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.web.log.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import com.baeldung.web.log.app.TaxiFareRequestInterceptor; + +@Configuration +public class TaxiFareMVCConfig extends WebMvcConfigurerAdapter { + + @Autowired + private TaxiFareRequestInterceptor taxiFareRequestInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(taxiFareRequestInterceptor).addPathPatterns("/**/taxifare/**/"); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/controller/TaxiFareController.java b/spring-rest/src/main/java/com/baeldung/web/log/controller/TaxiFareController.java new file mode 100644 index 0000000000..28bf07e8a6 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/controller/TaxiFareController.java @@ -0,0 +1,43 @@ +package com.baeldung.web.log.controller; + +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.baeldung.web.log.data.RateCard; +import com.baeldung.web.log.data.TaxiRide; +import com.baeldung.web.log.service.TaxiFareCalculatorService; + +@Controller +public class TaxiFareController { + + @Autowired + private TaxiFareCalculatorService taxiFareCalculatorService; + + private static final Logger LOGGER = LoggerFactory.getLogger(TaxiFareController.class); + + @RequestMapping(method = RequestMethod.GET, value = "/taxifare/get/") + @ResponseBody + public RateCard getTaxiFare() { + LOGGER.debug("getTaxiFare() - START"); + return new RateCard(); + } + + @RequestMapping(method = RequestMethod.POST, value = "/taxifare/calculate/") + @ResponseBody + public String calculateTaxiFare(@RequestBody @Valid TaxiRide taxiRide) { + LOGGER.debug("calculateTaxiFare() - START"); + String totalFare = taxiFareCalculatorService.calculateFare(taxiRide); + LOGGER.debug("calculateTaxiFare() - Total Fare : {}",totalFare); + LOGGER.debug("calculateTaxiFare() - END"); + return totalFare; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/data/RateCard.java b/spring-rest/src/main/java/com/baeldung/web/log/data/RateCard.java new file mode 100644 index 0000000000..35ae38fd11 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/data/RateCard.java @@ -0,0 +1,28 @@ +package com.baeldung.web.log.data; + +public class RateCard { + + private String nightSurcharge; + private String ratePerMile; + + public RateCard(){ + nightSurcharge="Extra $ 100"; + ratePerMile="$ 10 Per Mile"; + } + + + public String getNightSurcharge() { + return nightSurcharge; + } + public void setNightSurcharge(String nightSurcharge) { + this.nightSurcharge = nightSurcharge; + } + public String getRatePerMile() { + return ratePerMile; + } + public void setRatePerMile(String ratePerMile) { + this.ratePerMile = ratePerMile; + } + + +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/data/TaxiRide.java b/spring-rest/src/main/java/com/baeldung/web/log/data/TaxiRide.java new file mode 100644 index 0000000000..0877cdced4 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/data/TaxiRide.java @@ -0,0 +1,32 @@ +package com.baeldung.web.log.data; + +public class TaxiRide { + + private Boolean isNightSurcharge; + private Long distanceInMile; + + public TaxiRide(){} + + public TaxiRide(Boolean isNightSurcharge, Long distanceInMile){ + this.isNightSurcharge = isNightSurcharge; + this.distanceInMile = distanceInMile; + } + + + public Boolean getIsNightSurcharge() { + return isNightSurcharge; + } + + public void setIsNightSurcharge(Boolean isNightSurcharge) { + this.isNightSurcharge = isNightSurcharge; + } + + public Long getDistanceInMile() { + return distanceInMile; + } + + public void setDistanceInMile(Long distanceInMile) { + this.distanceInMile = distanceInMile; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/service/TaxiFareCalculatorService.java b/spring-rest/src/main/java/com/baeldung/web/log/service/TaxiFareCalculatorService.java new file mode 100644 index 0000000000..ec9c81187a --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/service/TaxiFareCalculatorService.java @@ -0,0 +1,20 @@ +package com.baeldung.web.log.service; + +import org.springframework.stereotype.Service; + +import com.baeldung.web.log.data.TaxiRide; + +@Service +public class TaxiFareCalculatorService { + + public String calculateFare(TaxiRide taxiRide) { + Long fare = 0l; + if (taxiRide.getIsNightSurcharge()) { + fare = taxiRide.getDistanceInMile() * 10 + 100; + } else { + fare = taxiRide.getDistanceInMile() * 10; + } + return String.valueOf(fare); + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java b/spring-rest/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java new file mode 100644 index 0000000000..c13d35b55c --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java @@ -0,0 +1,38 @@ +package com.baeldung.web.log.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.io.IOUtils; +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.WebUtils; + +public class RequestLoggingUtil { + + public static String getStringFromInputStream(InputStream is) { + StringWriter writer = new StringWriter(); + String encoding = "UTF-8"; + try { + IOUtils.copy(is, writer, encoding); + } catch (IOException e) { + e.printStackTrace(); + } + return writer.toString(); + } + + public static String readPayload(final HttpServletRequest request) throws IOException { + String payloadData = null; + ContentCachingRequestWrapper contentCachingRequestWrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class); + if (null != contentCachingRequestWrapper) { + byte[] buf = contentCachingRequestWrapper.getContentAsByteArray(); + if (buf.length > 0) { + payloadData = new String(buf, 0, buf.length, contentCachingRequestWrapper.getCharacterEncoding()); + } + } + return payloadData; + } + +} diff --git a/spring-rest/src/main/resources/logback.xml b/spring-rest/src/main/resources/logback.xml index ec0dc2469a..3496a4a03c 100644 --- a/spring-rest/src/main/resources/logback.xml +++ b/spring-rest/src/main/resources/logback.xml @@ -6,6 +6,10 @@ + + + + diff --git a/spring-rest/src/test/java/com/baeldung/web/log/test/TestTaxiFareController.java b/spring-rest/src/test/java/com/baeldung/web/log/test/TestTaxiFareController.java new file mode 100644 index 0000000000..935275983f --- /dev/null +++ b/spring-rest/src/test/java/com/baeldung/web/log/test/TestTaxiFareController.java @@ -0,0 +1,33 @@ +package com.baeldung.web.log.test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.baeldung.web.log.data.TaxiRide; + +public class TestTaxiFareController { + + private static final String URL = "http://localhost:" + 8082 + "/spring-rest/taxifare/"; + + @Test + public void givenRequest_thenfetchTaxiFareRateCard() { + TestRestTemplate testRestTemplate = new TestRestTemplate(); + ResponseEntity response = testRestTemplate.getForEntity(URL + "get/", String.class); + assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + } + + @Test + public void givenTaxiRide_thenGetCalculatedFare() { + TestRestTemplate testRestTemplate = new TestRestTemplate(); + TaxiRide taxiRide = new TaxiRide(true,10l); + String fare = testRestTemplate.postForObject(URL + "calculate/", taxiRide,String.class); + assertThat(fare, equalTo("200")); + } + + +}