From 9f108905017774816697c9e763b0c1a879bd321b Mon Sep 17 00:00:00 2001 From: eugenp Date: Fri, 24 Feb 2017 13:50:46 +0200 Subject: [PATCH] initial commit of spring 5 project --- spring-5/.gitignore | 13 + spring-5/README.md | 6 + spring-5/pom.xml | 345 ++++++++++ .../java/org/baeldung/config/Application.java | 16 + .../java/org/baeldung/config/WebConfig.java | 57 ++ .../converter/KryoHttpMessageConverter.java | 57 ++ .../BarMappingExamplesController.java | 47 ++ .../web/controller/CompanyController.java | 16 + .../web/controller/FooController.java | 45 ++ .../FooMappingExamplesController.java | 101 +++ .../web/controller/ItemController.java | 39 ++ .../web/controller/MyFooController.java | 76 +++ .../web/controller/SimplePostController.java | 73 +++ .../advice/JsonpControllerAdvice.java | 13 + .../mediatypes/CustomMediaTypeController.java | 20 + .../redirect/RedirectController.java | 52 ++ .../controller/status/ExampleController.java | 24 + .../controller/status/ForbiddenException.java | 10 + .../org/baeldung/web/dto/BaeldungItem.java | 13 + .../org/baeldung/web/dto/BaeldungItemV2.java | 14 + .../java/org/baeldung/web/dto/Company.java | 38 ++ .../main/java/org/baeldung/web/dto/Foo.java | 45 ++ .../java/org/baeldung/web/dto/FooProtos.java | 597 ++++++++++++++++++ .../main/java/org/baeldung/web/dto/Item.java | 36 ++ .../org/baeldung/web/dto/ItemManager.java | 9 + .../main/java/org/baeldung/web/dto/Views.java | 9 + .../exception/ResourceNotFoundException.java | 8 + .../src/main/resources/application.properties | 2 + spring-5/src/main/resources/logback.xml | 20 + .../src/main/webapp/WEB-INF/api-servlet.xml | 56 ++ spring-5/src/main/webapp/WEB-INF/company.html | 44 ++ .../src/main/webapp/WEB-INF/spring-views.xml | 10 + spring-5/src/main/webapp/WEB-INF/web.xml | 41 ++ .../test/java/org/baeldung/client/Consts.java | 5 + .../client/RestTemplateBasicLiveTest.java | 216 +++++++ .../okhttp/DefaultContentTypeInterceptor.java | 24 + .../okhttp/OkHttpFileUploadingLiveTest.java | 65 ++ .../baeldung/okhttp/OkHttpGetLiveTest.java | 77 +++ .../baeldung/okhttp/OkHttpHeaderLiveTest.java | 45 ++ .../baeldung/okhttp/OkHttpMiscLiveTest.java | 99 +++ .../okhttp/OkHttpPostingLiveTest.java | 85 +++ .../okhttp/OkHttpRedirectLiveTest.java | 29 + .../okhttp/ProgressRequestWrapper.java | 73 +++ .../uribuilder/SpringUriBuilderTest.java | 49 ++ .../CustomMediaTypeControllerLiveTest.java | 37 ++ .../CustomMediaTypeControllerTest.java | 42 ++ .../web/controller/mediatypes/TestConfig.java | 11 + .../RedirectControllerIntegrationTest.java | 66 ++ .../ExampleControllerIntegrationTest.java | 42 ++ .../web/test/RequestMappingLiveTest.java | 63 ++ .../SpringHttpMessageConvertersLiveTest.java | 123 ++++ spring-5/src/test/resources/.gitignore | 13 + spring-5/src/test/resources/test.txt | 1 + 53 files changed, 3117 insertions(+) create mode 100644 spring-5/.gitignore create mode 100644 spring-5/README.md create mode 100644 spring-5/pom.xml create mode 100644 spring-5/src/main/java/org/baeldung/config/Application.java create mode 100644 spring-5/src/main/java/org/baeldung/config/WebConfig.java create mode 100644 spring-5/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/CompanyController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/FooController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/ItemController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/MyFooController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/SimplePostController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/status/ExampleController.java create mode 100644 spring-5/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/BaeldungItem.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/BaeldungItemV2.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/Company.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/Foo.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/FooProtos.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/Item.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/ItemManager.java create mode 100644 spring-5/src/main/java/org/baeldung/web/dto/Views.java create mode 100644 spring-5/src/main/java/org/baeldung/web/exception/ResourceNotFoundException.java create mode 100644 spring-5/src/main/resources/application.properties create mode 100644 spring-5/src/main/resources/logback.xml create mode 100644 spring-5/src/main/webapp/WEB-INF/api-servlet.xml create mode 100644 spring-5/src/main/webapp/WEB-INF/company.html create mode 100644 spring-5/src/main/webapp/WEB-INF/spring-views.xml create mode 100644 spring-5/src/main/webapp/WEB-INF/web.xml create mode 100644 spring-5/src/test/java/org/baeldung/client/Consts.java create mode 100644 spring-5/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/DefaultContentTypeInterceptor.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/OkHttpRedirectLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/okhttp/ProgressRequestWrapper.java create mode 100644 spring-5/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/controller/mediatypes/TestConfig.java create mode 100644 spring-5/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java create mode 100644 spring-5/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java create mode 100644 spring-5/src/test/resources/.gitignore create mode 100644 spring-5/src/test/resources/test.txt diff --git a/spring-5/.gitignore b/spring-5/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-5/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-5/README.md b/spring-5/README.md new file mode 100644 index 0000000000..0914388b49 --- /dev/null +++ b/spring-5/README.md @@ -0,0 +1,6 @@ +## Spring REST Example Project + +###The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: diff --git a/spring-5/pom.xml b/spring-5/pom.xml new file mode 100644 index 0000000000..c2545d920f --- /dev/null +++ b/spring-5/pom.xml @@ -0,0 +1,345 @@ + + 4.0.0 + com.baeldung + spring-5 + 0.1-SNAPSHOT + spring-5 + war + + + org.springframework.boot + spring-boot-starter-parent + + 2.0.0.BUILD-SNAPSHOT + + + + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + + + + + + org.springframework + spring-web + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + + + org.springframework + spring-oxm + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + + + javax.servlet + javax.servlet-api + provided + + + + javax.servlet + jstl + runtime + + + + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + + org.slf4j + jcl-over-slf4j + + + + org.slf4j + log4j-over-slf4j + + + + + + com.squareup.okhttp3 + okhttp + ${com.squareup.okhttp3.version} + + + + + + junit + junit + test + + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + + org.mockito + mockito-core + test + + + + org.springframework + spring-test + + + + com.jayway.restassured + rest-assured + ${rest-assured.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} + + + + + spring-5 + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-war-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + 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 + + + + + + + + + + + + + + 1.3.2 + 4.0.0 + 1.4 + 3.1.0 + 3.5 + 1.4.9 + + + 20.0 + 2.9.0 + + + 1.6.0 + 3.0.4 + + + 3.4.1 + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + diff --git a/spring-5/src/main/java/org/baeldung/config/Application.java b/spring-5/src/main/java/org/baeldung/config/Application.java new file mode 100644 index 0000000000..077213b04d --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/config/Application.java @@ -0,0 +1,16 @@ +package org.baeldung.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@EnableAutoConfiguration +@ComponentScan("org.baeldung") +public class Application extends WebMvcConfigurerAdapter { + + public static void main(final String[] args) { + SpringApplication.run(Application.class, args); + } + +} \ No newline at end of file diff --git a/spring-5/src/main/java/org/baeldung/config/WebConfig.java b/spring-5/src/main/java/org/baeldung/config/WebConfig.java new file mode 100644 index 0000000000..f40c9477d4 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/config/WebConfig.java @@ -0,0 +1,57 @@ +package org.baeldung.config; + +import org.baeldung.config.converter.KryoHttpMessageConverter; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter; +import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; +import org.springframework.oxm.xstream.XStreamMarshaller; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import java.text.SimpleDateFormat; +import java.util.List; + +/* + * Please note that main web configuration is in src/main/webapp/WEB-INF/api-servlet.xml + */ +@Configuration +@EnableWebMvc +@ComponentScan({ "org.baeldung.web" }) +public class WebConfig extends WebMvcConfigurerAdapter { + + public WebConfig() { + super(); + } + + // + + @Override + public void configureMessageConverters(final List> messageConverters) { + final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); + builder.indentOutput(true).dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm")); + messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build())); + // messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); + + // messageConverters.add(createXmlHttpMessageConverter()); + // messageConverters.add(new MappingJackson2HttpMessageConverter()); + + messageConverters.add(new ProtobufHttpMessageConverter()); + messageConverters.add(new KryoHttpMessageConverter()); + super.configureMessageConverters(messageConverters); + } + + private HttpMessageConverter createXmlHttpMessageConverter() { + final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); + + final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); + xmlConverter.setMarshaller(xstreamMarshaller); + xmlConverter.setUnmarshaller(xstreamMarshaller); + + return xmlConverter; + } + +} diff --git a/spring-5/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java b/spring-5/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java new file mode 100644 index 0000000000..7e63a3ba9e --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/config/converter/KryoHttpMessageConverter.java @@ -0,0 +1,57 @@ +package org.baeldung.config.converter; + +import java.io.IOException; + +import org.baeldung.web.dto.Foo; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + +/** + * An {@code HttpMessageConverter} that can read and write Kryo messages. + */ +public class KryoHttpMessageConverter extends AbstractHttpMessageConverter { + + public static final MediaType KRYO = new MediaType("application", "x-kryo"); + + private static final ThreadLocal kryoThreadLocal = new ThreadLocal() { + @Override + protected Kryo initialValue() { + final Kryo kryo = new Kryo(); + kryo.register(Foo.class, 1); + return kryo; + } + }; + + public KryoHttpMessageConverter() { + super(KRYO); + } + + @Override + protected boolean supports(final Class clazz) { + return Object.class.isAssignableFrom(clazz); + } + + @Override + protected Object readInternal(final Class clazz, final HttpInputMessage inputMessage) throws IOException { + final Input input = new Input(inputMessage.getBody()); + return kryoThreadLocal.get().readClassAndObject(input); + } + + @Override + protected void writeInternal(final Object object, final HttpOutputMessage outputMessage) throws IOException { + final Output output = new Output(outputMessage.getBody()); + kryoThreadLocal.get().writeClassAndObject(output, object); + output.flush(); + } + + @Override + protected MediaType getDefaultContentType(final Object object) { + return KRYO; + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java b/spring-5/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java new file mode 100644 index 0000000000..1c3a1086ca --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java @@ -0,0 +1,47 @@ +package org.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/ex") +public class BarMappingExamplesController { + + public BarMappingExamplesController() { + super(); + } + + // API + + // with @RequestParam + + @RequestMapping(value = "/bars") + @ResponseBody + public String getBarBySimplePathWithRequestParam(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + @RequestMapping(value = "/bars", params = "id") + @ResponseBody + public String getBarBySimplePathWithExplicitRequestParam(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + @RequestMapping(value = "/bars", params = { "id", "second" }) + @ResponseBody + public String getBarBySimplePathWithExplicitRequestParams(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + // with @PathVariable + + @RequestMapping(value = "/bars/{numericId:[\\d]+}") + @ResponseBody + public String getBarsBySimplePathWithPathVariable(@PathVariable final long numericId) { + return "Get a specific Bar with id=" + numericId; + } + +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/CompanyController.java b/spring-5/src/main/java/org/baeldung/web/controller/CompanyController.java new file mode 100644 index 0000000000..aa694c08ed --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/CompanyController.java @@ -0,0 +1,16 @@ +package org.baeldung.web.controller; + +import org.baeldung.web.dto.Company; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CompanyController { + + @RequestMapping(value = "/companyRest", produces = MediaType.APPLICATION_JSON_VALUE) + public Company getCompanyRest() { + final Company company = new Company(1, "Xpto"); + return company; + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/FooController.java b/spring-5/src/main/java/org/baeldung/web/controller/FooController.java new file mode 100644 index 0000000000..21ba3c6d13 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/FooController.java @@ -0,0 +1,45 @@ +package org.baeldung.web.controller; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; + +import org.baeldung.web.dto.Foo; +import org.baeldung.web.dto.FooProtos; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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 org.springframework.web.bind.annotation.ResponseStatus; + +@Controller +public class FooController { + + public FooController() { + super(); + } + + // API - read + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id) { + return new Foo(id, randomAlphabetic(4)); + } + + // API - write + + @RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public Foo updateFoo(@PathVariable("id") final String id, @RequestBody final Foo foo) { + return foo; + } + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}", produces = { "application/x-protobuf" }) + @ResponseBody + public FooProtos.Foo findProtoById(@PathVariable final long id) { + return FooProtos.Foo.newBuilder().setId(1).setName("Foo Name").build(); + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java b/spring-5/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java new file mode 100644 index 0000000000..5fb92d6d87 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/FooMappingExamplesController.java @@ -0,0 +1,101 @@ +package org.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/ex") +public class FooMappingExamplesController { + + public FooMappingExamplesController() { + super(); + } + + // API + + // mapping examples + + @RequestMapping(value = "/foos") + @ResponseBody + public String getFoosBySimplePath() { + return "Simple Get some Foos"; + } + + // with @PathVariable + + @RequestMapping(value = "/foos/{id}") + @ResponseBody + public String getFoosBySimplePathWithPathVariable(@PathVariable final long id) { + return "Get a specific Foo with id=" + id; + } + + @RequestMapping(value = "/foos/{fooid}/bar/{barid}") + @ResponseBody + public String getFoosBySimplePathWithPathVariables(@PathVariable final long fooid, @PathVariable final long barid) { + return "Get a specific Bar with id=" + barid + " from a Foo with id=" + fooid; + } + + // other HTTP verbs + + @RequestMapping(value = "/foos", method = RequestMethod.POST) + @ResponseBody + public String postFoos() { + return "Post some Foos"; + } + + // with headers + + @RequestMapping(value = "/foos", headers = "key=val") + @ResponseBody + public String getFoosWithHeader() { + return "Get some Foos with Header"; + } + + @RequestMapping(value = "/foos", headers = { "key1=val1", "key2=val2" }) + @ResponseBody + public String getFoosWithHeaders() { + return "Get some Foos with Header"; + } + + // @RequestMapping(value = "/foos", method = RequestMethod.GET, headers = "Accept=application/json") + // @ResponseBody + // public String getFoosAsJsonFromBrowser() { + // return "Get some Foos with Header Old"; + // } + + @RequestMapping(value = "/foos", produces = { "application/json", "application/xml" }) + @ResponseBody + public String getFoosAsJsonFromREST() { + return "Get some Foos with Header New"; + } + + // advanced - multiple mappings + + @RequestMapping(value = { "/advanced/bars", "/advanced/foos" }) + @ResponseBody + public String getFoosOrBarsByPath() { + return "Advanced - Get some Foos or Bars"; + } + + @RequestMapping(value = "*") + @ResponseBody + public String getFallback() { + return "Fallback for GET Requests"; + } + + @RequestMapping(value = "*", method = { RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + public String allFallback() { + return "Fallback for All Requests"; + } + + @RequestMapping(value = "/foos/multiple", method = { RequestMethod.PUT, RequestMethod.POST }) + @ResponseBody + public String putAndPostFoos() { + return "Advanced - PUT and POST within single method"; + } + +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/ItemController.java b/spring-5/src/main/java/org/baeldung/web/controller/ItemController.java new file mode 100644 index 0000000000..1cc3eae432 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/ItemController.java @@ -0,0 +1,39 @@ +package org.baeldung.web.controller; + +import java.util.Date; + +import org.baeldung.web.dto.Item; +import org.baeldung.web.dto.ItemManager; +import org.baeldung.web.dto.Views; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.annotation.JsonView; + +@RestController +public class ItemController { + + @JsonView(Views.Public.class) + @RequestMapping("/items/{id}") + public Item getItemPublic(@PathVariable final int id) { + return ItemManager.getById(id); + } + + @JsonView(Views.Internal.class) + @RequestMapping("/items/internal/{id}") + public Item getItemInternal(@PathVariable final int id) { + return ItemManager.getById(id); + } + + @RequestMapping("/date") + public Date getCurrentDate() throws Exception { + return new Date(); + } + + @RequestMapping("/delay/{seconds}") + public void getCurrentTime(@PathVariable final int seconds) throws Exception { + + Thread.sleep(seconds * 1000); + } +} \ No newline at end of file diff --git a/spring-5/src/main/java/org/baeldung/web/controller/MyFooController.java b/spring-5/src/main/java/org/baeldung/web/controller/MyFooController.java new file mode 100644 index 0000000000..f19ddca435 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/MyFooController.java @@ -0,0 +1,76 @@ +package org.baeldung.web.controller; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.baeldung.web.dto.Foo; +import org.baeldung.web.exception.ResourceNotFoundException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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 org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +@Controller +@RequestMapping(value = "/myfoos") +public class MyFooController { + + private final Map myfoos; + + public MyFooController() { + super(); + myfoos = new HashMap(); + myfoos.put(1L, new Foo(1L, "sample foo")); + } + + // API - read + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public Collection findAll() { + return myfoos.values(); + } + + @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = { "application/json" }) + @ResponseBody + public Foo findById(@PathVariable final long id) { + final Foo foo = myfoos.get(id); + if (foo == null) { + throw new ResourceNotFoundException(); + } + return foo; + } + + // API - write + + @RequestMapping(method = RequestMethod.PUT, value = "/{id}") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public Foo updateFoo(@PathVariable("id") final long id, @RequestBody final Foo foo) { + myfoos.put(id, foo); + return foo; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + public Foo createFoo(@RequestBody final Foo foo, HttpServletResponse response) { + myfoos.put(foo.getId(), foo); + response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentRequest().path("/" + foo.getId()).toUriString()); + return foo; + } + + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") + @ResponseStatus(HttpStatus.OK) + public void deleteById(@PathVariable final long id) { + myfoos.remove(id); + } + +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/SimplePostController.java b/spring-5/src/main/java/org/baeldung/web/controller/SimplePostController.java new file mode 100644 index 0000000000..f8407acb47 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/SimplePostController.java @@ -0,0 +1,73 @@ +package org.baeldung.web.controller; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.baeldung.web.dto.Foo; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +// used to test HttpClientPostingTest +@RestController +public class SimplePostController { + + @RequestMapping(value = "/users", method = RequestMethod.POST) + public String postUser(@RequestParam final String username, @RequestParam final String password) { + return "Success" + username; + } + + @RequestMapping(value = "/users/detail", method = RequestMethod.POST) + public String postUserDetail(@RequestBody final Foo entity) { + return "Success" + entity.getId(); + } + + @RequestMapping(value = "/users/multipart", method = RequestMethod.POST) + public String uploadFile(@RequestParam final String username, @RequestParam final String password, @RequestParam("file") final MultipartFile file) { + if (!file.isEmpty()) { + try { + final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss"); + final String fileName = dateFormat.format(new Date()); + final File fileServer = new File(fileName); + fileServer.createNewFile(); + final byte[] bytes = file.getBytes(); + final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer)); + stream.write(bytes); + stream.close(); + return "You successfully uploaded " + username; + } catch (final Exception e) { + return "You failed to upload " + e.getMessage(); + } + } else { + return "You failed to upload because the file was empty."; + } + } + + @RequestMapping(value = "/users/upload", method = RequestMethod.POST) + public String postMultipart(@RequestParam("file") final MultipartFile file) { + if (!file.isEmpty()) { + try { + final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss"); + final String fileName = dateFormat.format(new Date()); + final File fileServer = new File(fileName); + fileServer.createNewFile(); + final byte[] bytes = file.getBytes(); + final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer)); + stream.write(bytes); + stream.close(); + return "You successfully uploaded "; + } catch (final Exception e) { + return "You failed to upload " + e.getMessage(); + } + } else { + return "You failed to upload because the file was empty."; + } + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java b/spring-5/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java new file mode 100644 index 0000000000..996f229128 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/advice/JsonpControllerAdvice.java @@ -0,0 +1,13 @@ +package org.baeldung.web.controller.advice; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice; + +@ControllerAdvice +public class JsonpControllerAdvice extends AbstractJsonpResponseBodyAdvice { + + public JsonpControllerAdvice() { + super("callback"); + } + +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeController.java b/spring-5/src/main/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeController.java new file mode 100644 index 0000000000..410c72d34f --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeController.java @@ -0,0 +1,20 @@ +package org.baeldung.web.controller.mediatypes; + +import org.baeldung.web.dto.BaeldungItem; +import org.baeldung.web.dto.BaeldungItemV2; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value = "/", produces = "application/vnd.baeldung.api.v1+json") +public class CustomMediaTypeController { + + @RequestMapping(method = RequestMethod.GET, value = "/public/api/items/{id}", produces = "application/vnd.baeldung.api.v1+json") + public @ResponseBody BaeldungItem getItem(@PathVariable("id") String id) { + return new BaeldungItem("itemId1"); + } + + @RequestMapping(method = RequestMethod.GET, value = "/public/api/items/{id}", produces = "application/vnd.baeldung.api.v2+json") + public @ResponseBody BaeldungItemV2 getItemSecondAPIVersion(@PathVariable("id") String id) { + return new BaeldungItemV2("itemName"); + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java b/spring-5/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java new file mode 100644 index 0000000000..472c0c8bf5 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java @@ -0,0 +1,52 @@ +package org.baeldung.web.controller.redirect; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.view.RedirectView; + +@Controller +@RequestMapping("/") +public class RedirectController { + + @RequestMapping(value = "/redirectWithXMLConfig", method = RequestMethod.GET) + public ModelAndView redirectWithUsingXMLConfig(final ModelMap model) { + model.addAttribute("attribute", "redirectWithXMLConfig"); + return new ModelAndView("RedirectedUrl", model); + } + + @RequestMapping(value = "/redirectWithRedirectPrefix", method = RequestMethod.GET) + public ModelAndView redirectWithUsingRedirectPrefix(final ModelMap model) { + model.addAttribute("attribute", "redirectWithRedirectPrefix"); + return new ModelAndView("redirect:/redirectedUrl", model); + } + + @RequestMapping(value = "/redirectWithRedirectAttributes", method = RequestMethod.GET) + public RedirectView redirectWithRedirectAttributes(final RedirectAttributes redirectAttributes) { + redirectAttributes.addFlashAttribute("flashAttribute", "redirectWithRedirectAttributes"); + redirectAttributes.addAttribute("attribute", "redirectWithRedirectAttributes"); + return new RedirectView("redirectedUrl"); + } + + @RequestMapping(value = "/redirectWithRedirectView", method = RequestMethod.GET) + public RedirectView redirectWithUsingRedirectView(final ModelMap model) { + model.addAttribute("attribute", "redirectWithRedirectView"); + return new RedirectView("redirectedUrl"); + } + + @RequestMapping(value = "/forwardWithForwardPrefix", method = RequestMethod.GET) + public ModelAndView forwardWithUsingForwardPrefix(final ModelMap model) { + model.addAttribute("attribute", "redirectWithForwardPrefix"); + return new ModelAndView("forward:/redirectedUrl", model); + } + + @RequestMapping(value = "/redirectedUrl", method = RequestMethod.GET) + public ModelAndView redirection(final ModelMap model, @ModelAttribute("flashAttribute") final Object flashAttribute) { + model.addAttribute("redirectionAttribute", flashAttribute); + return new ModelAndView("redirection", model); + } +} \ No newline at end of file diff --git a/spring-5/src/main/java/org/baeldung/web/controller/status/ExampleController.java b/spring-5/src/main/java/org/baeldung/web/controller/status/ExampleController.java new file mode 100644 index 0000000000..ceda138768 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/status/ExampleController.java @@ -0,0 +1,24 @@ +package org.baeldung.web.controller.status; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class ExampleController { + + @RequestMapping(value = "/controller", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity sendViaResponseEntity() { + return new ResponseEntity(HttpStatus.NOT_ACCEPTABLE); + } + + @RequestMapping(value = "/exception", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity sendViaException() { + throw new ForbiddenException(); + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java b/spring-5/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java new file mode 100644 index 0000000000..458bdaf170 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/controller/status/ForbiddenException.java @@ -0,0 +1,10 @@ +package org.baeldung.web.controller.status; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "To show an example of a custom message") +public class ForbiddenException extends RuntimeException { + private static final long serialVersionUID = 6826605655586311552L; + +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItem.java b/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItem.java new file mode 100644 index 0000000000..9b3ecd33b9 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItem.java @@ -0,0 +1,13 @@ +package org.baeldung.web.dto; + +public class BaeldungItem { + private final String itemId; + + public BaeldungItem(String itemId) { + this.itemId = itemId; + } + + public String getItemId() { + return itemId; + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItemV2.java b/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItemV2.java new file mode 100644 index 0000000000..64df20a14e --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/BaeldungItemV2.java @@ -0,0 +1,14 @@ +package org.baeldung.web.dto; + + +public class BaeldungItemV2 { + private final String itemName; + + public BaeldungItemV2(String itemName) { + this.itemName = itemName; + } + + public String getItemName() { + return itemName; + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/Company.java b/spring-5/src/main/java/org/baeldung/web/dto/Company.java new file mode 100644 index 0000000000..3164d604ad --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/Company.java @@ -0,0 +1,38 @@ +package org.baeldung.web.dto; + +public class Company { + + private long id; + private String name; + + public Company() { + super(); + } + + public Company(final long id, final String name) { + this.id = id; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + @Override + public String toString() { + return "Company [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/Foo.java b/spring-5/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..240b368b50 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/Foo.java @@ -0,0 +1,45 @@ +package org.baeldung.web.dto; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +@XStreamAlias("Foo") +public class Foo { + private long id; + private String name; + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + + this.name = name; + } + + public Foo(final long id, final String name) { + super(); + + this.id = id; + this.name = name; + } + + // API + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/spring-5/src/main/java/org/baeldung/web/dto/FooProtos.java b/spring-5/src/main/java/org/baeldung/web/dto/FooProtos.java new file mode 100644 index 0000000000..8ca96c38fc --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/FooProtos.java @@ -0,0 +1,597 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: FooProtos.proto + +package org.baeldung.web.dto; + +public final class FooProtos { + private FooProtos() { + } + + public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) { + } + + public interface FooOrBuilder extends + // @@protoc_insertion_point(interface_extends:baeldung.Foo) + com.google.protobuf.MessageOrBuilder { + + /** + * required int64 id = 1; + */ + boolean hasId(); + + /** + * required int64 id = 1; + */ + long getId(); + + /** + * required string name = 2; + */ + boolean hasName(); + + /** + * required string name = 2; + */ + java.lang.String getName(); + + /** + * required string name = 2; + */ + com.google.protobuf.ByteString getNameBytes(); + } + + /** + * Protobuf type {@code baeldung.Foo} + */ + public static final class Foo extends com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:baeldung.Foo) + FooOrBuilder { + // Use Foo.newBuilder() to construct. + private Foo(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + + private Foo(boolean noInit) { + this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + + private static final Foo defaultInstance; + + public static Foo getDefaultInstance() { + return defaultInstance; + } + + public Foo getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private Foo(com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + id_ = input.readInt64(); + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + name_ = bs; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { + return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_fieldAccessorTable.ensureFieldAccessorsInitialized(org.baeldung.web.dto.FooProtos.Foo.class, org.baeldung.web.dto.FooProtos.Foo.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { + public Foo parsePartialFrom(com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { + return new Foo(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private long id_; + + /** + * required int64 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + + /** + * required int64 id = 1; + */ + public long getId() { + return id_; + } + + public static final int NAME_FIELD_NUMBER = 2; + private java.lang.Object name_; + + /** + * required string name = 2; + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + + /** + * required string name = 2; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + + /** + * required string name = 2; + */ + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + id_ = 0L; + name_ = ""; + } + + private byte memoizedIsInitialized = -1; + + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + + if (!hasId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt64(1, id_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) + return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream.computeInt64Size(1, id_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream.computeBytesSize(2, getNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + + @java.lang.Override + protected java.lang.Object writeReplace() throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(java.io.InputStream input) throws java.io.IOException { + return PARSER.parseFrom(input); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseDelimitedFrom(java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return PARSER.parseFrom(input); + } + + public static org.baeldung.web.dto.FooProtos.Foo parseFrom(com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(org.baeldung.web.dto.FooProtos.Foo prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + /** + * Protobuf type {@code baeldung.Foo} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:baeldung.Foo) + org.baeldung.web.dto.FooProtos.FooOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { + return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_fieldAccessorTable.ensureFieldAccessorsInitialized(org.baeldung.web.dto.FooProtos.Foo.class, org.baeldung.web.dto.FooProtos.Foo.Builder.class); + } + + // Construct using org.baeldung.web.dto.FooProtos.Foo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder(com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + id_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return org.baeldung.web.dto.FooProtos.internal_static_baeldung_Foo_descriptor; + } + + public org.baeldung.web.dto.FooProtos.Foo getDefaultInstanceForType() { + return org.baeldung.web.dto.FooProtos.Foo.getDefaultInstance(); + } + + public org.baeldung.web.dto.FooProtos.Foo build() { + org.baeldung.web.dto.FooProtos.Foo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.baeldung.web.dto.FooProtos.Foo buildPartial() { + org.baeldung.web.dto.FooProtos.Foo result = new org.baeldung.web.dto.FooProtos.Foo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.id_ = id_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.name_ = name_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.baeldung.web.dto.FooProtos.Foo) { + return mergeFrom((org.baeldung.web.dto.FooProtos.Foo) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.baeldung.web.dto.FooProtos.Foo other) { + if (other == org.baeldung.web.dto.FooProtos.Foo.getDefaultInstance()) + return this; + if (other.hasId()) { + setId(other.getId()); + } + if (other.hasName()) { + bitField0_ |= 0x00000002; + name_ = other.name_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasId()) { + + return false; + } + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom(com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { + org.baeldung.web.dto.FooProtos.Foo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.baeldung.web.dto.FooProtos.Foo) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int bitField0_; + + private long id_; + + /** + * required int64 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + + /** + * required int64 id = 1; + */ + public long getId() { + return id_; + } + + /** + * required int64 id = 1; + */ + public Builder setId(long value) { + bitField0_ |= 0x00000001; + id_ = value; + onChanged(); + return this; + } + + /** + * required int64 id = 1; + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000001); + id_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object name_ = ""; + + /** + * required string name = 2; + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + + /** + * required string name = 2; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + + /** + * required string name = 2; + */ + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + /** + * required string name = 2; + */ + public Builder setName(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + + /** + * required string name = 2; + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000002); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + /** + * required string name = 2; + */ + public Builder setNameBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:baeldung.Foo) + } + + static { + defaultInstance = new Foo(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:baeldung.Foo) + } + + private static final com.google.protobuf.Descriptors.Descriptor internal_static_baeldung_Foo_descriptor; + private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_baeldung_Foo_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + return descriptor; + } + + private static com.google.protobuf.Descriptors.FileDescriptor descriptor; + static { + java.lang.String[] descriptorData = { "\n\017FooProtos.proto\022\010baeldung\"\037\n\003Foo\022\n\n\002id" + "\030\001 \002(\003\022\014\n\004name\030\002 \002(\tB!\n\024org.baeldung.web" + ".dtoB\tFooProtos" }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors(com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {}, assigner); + internal_static_baeldung_Foo_descriptor = getDescriptor().getMessageTypes().get(0); + internal_static_baeldung_Foo_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable(internal_static_baeldung_Foo_descriptor, new java.lang.String[] { "Id", "Name", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/Item.java b/spring-5/src/main/java/org/baeldung/web/dto/Item.java new file mode 100644 index 0000000000..536c72020f --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/Item.java @@ -0,0 +1,36 @@ +package org.baeldung.web.dto; + +import com.fasterxml.jackson.annotation.JsonView; + +public class Item { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String itemName; + + @JsonView(Views.Internal.class) + public String ownerName; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final String ownerName) { + this.id = id; + this.itemName = itemName; + this.ownerName = ownerName; + } + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public String getOwnerName() { + return ownerName; + } +} \ No newline at end of file diff --git a/spring-5/src/main/java/org/baeldung/web/dto/ItemManager.java b/spring-5/src/main/java/org/baeldung/web/dto/ItemManager.java new file mode 100644 index 0000000000..74ffada300 --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/ItemManager.java @@ -0,0 +1,9 @@ +package org.baeldung.web.dto; + +public class ItemManager { + + public static Item getById(final int id) { + final Item item = new Item(2, "book", "John"); + return item; + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/dto/Views.java b/spring-5/src/main/java/org/baeldung/web/dto/Views.java new file mode 100644 index 0000000000..6231e12bcc --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/dto/Views.java @@ -0,0 +1,9 @@ +package org.baeldung.web.dto; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/spring-5/src/main/java/org/baeldung/web/exception/ResourceNotFoundException.java b/spring-5/src/main/java/org/baeldung/web/exception/ResourceNotFoundException.java new file mode 100644 index 0000000000..aab737b6ec --- /dev/null +++ b/spring-5/src/main/java/org/baeldung/web/exception/ResourceNotFoundException.java @@ -0,0 +1,8 @@ +package org.baeldung.web.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { +} diff --git a/spring-5/src/main/resources/application.properties b/spring-5/src/main/resources/application.properties new file mode 100644 index 0000000000..300589f561 --- /dev/null +++ b/spring-5/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.port= 8082 +server.context-path=/spring-rest \ No newline at end of file diff --git a/spring-5/src/main/resources/logback.xml b/spring-5/src/main/resources/logback.xml new file mode 100644 index 0000000000..1146dade63 --- /dev/null +++ b/spring-5/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-5/src/main/webapp/WEB-INF/api-servlet.xml b/spring-5/src/main/webapp/WEB-INF/api-servlet.xml new file mode 100644 index 0000000000..0f80990c16 --- /dev/null +++ b/spring-5/src/main/webapp/WEB-INF/api-servlet.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + /WEB-INF/spring-views.xml + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-5/src/main/webapp/WEB-INF/company.html b/spring-5/src/main/webapp/WEB-INF/company.html new file mode 100644 index 0000000000..d2072bfd3c --- /dev/null +++ b/spring-5/src/main/webapp/WEB-INF/company.html @@ -0,0 +1,44 @@ + + + + + Company Data + + + + + + + +
+ + + \ No newline at end of file diff --git a/spring-5/src/main/webapp/WEB-INF/spring-views.xml b/spring-5/src/main/webapp/WEB-INF/spring-views.xml new file mode 100644 index 0000000000..2944828d6d --- /dev/null +++ b/spring-5/src/main/webapp/WEB-INF/spring-views.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/spring-5/src/main/webapp/WEB-INF/web.xml b/spring-5/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..a439de8a05 --- /dev/null +++ b/spring-5/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,41 @@ + + + + Spring MVC Application + + + + contextClass + + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + + contextConfigLocation + org.baeldung.config + + + + org.springframework.web.context.ContextLoaderListener + + + + + api + org.springframework.web.servlet.DispatcherServlet + 1 + + + api + / + + + + + + + diff --git a/spring-5/src/test/java/org/baeldung/client/Consts.java b/spring-5/src/test/java/org/baeldung/client/Consts.java new file mode 100644 index 0000000000..b40561d9c3 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/client/Consts.java @@ -0,0 +1,5 @@ +package org.baeldung.client; + +public interface Consts { + int APPLICATION_PORT = 8082; +} diff --git a/spring-5/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-5/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java new file mode 100644 index 0000000000..a47c60e9d8 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java @@ -0,0 +1,216 @@ +package org.baeldung.client; + +import static org.apache.commons.codec.binary.Base64.encodeBase64; +import static org.baeldung.client.Consts.APPLICATION_PORT; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.Set; + +import org.baeldung.web.dto.Foo; +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RequestCallback; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; + +public class RestTemplateBasicLiveTest { + + private RestTemplate restTemplate; + private static final String fooResourceUrl = "http://localhost:" + APPLICATION_PORT + "/spring-rest/myfoos"; + + @Before + public void beforeTest() { + restTemplate = new RestTemplate(); + } + + // GET + + @Test + public void givenResourceUrl_whenSendGetForRequestEntity_thenStatusOk() throws IOException { + final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); + + assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); + } + + @Test + public void givenResourceUrl_whenSendGetForRequestEntity_thenBodyCorrect() throws IOException { + final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); + + final ObjectMapper mapper = new ObjectMapper(); + final JsonNode root = mapper.readTree(response.getBody()); + final JsonNode name = root.path("name"); + assertThat(name.asText(), notNullValue()); + } + + @Test + public void givenResourceUrl_whenRetrievingResource_thenCorrect() throws IOException { + final Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class); + + assertThat(foo.getName(), notNullValue()); + assertThat(foo.getId(), is(1L)); + } + + // HEAD, OPTIONS + + @Test + public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeadersForThatResource() { + final HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl); + + assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); + } + + // POST + + @Test + public void givenFooService_whenPostForObject_thenCreatedObjectIsReturned() { + final HttpEntity request = new HttpEntity<>(new Foo("bar")); + final Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class); + assertThat(foo, notNullValue()); + assertThat(foo.getName(), is("bar")); + } + + @Test + public void givenFooService_whenPostForLocation_thenCreatedLocationIsReturned() { + final HttpEntity request = new HttpEntity<>(new Foo("bar")); + final URI location = restTemplate.postForLocation(fooResourceUrl, request); + assertThat(location, notNullValue()); + } + + @Test + public void givenFooService_whenPostResource_thenResourceIsCreated() { + final RestTemplate template = new RestTemplate(); + + final HttpEntity request = new HttpEntity<>(new Foo("bar")); + + final ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + final Foo foo = response.getBody(); + assertThat(foo, notNullValue()); + assertThat(foo.getName(), is("bar")); + } + + @Test + public void givenFooService_whenCallOptionsForAllow_thenReceiveValueOfAllowHeader() { + final Set optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl); + final HttpMethod[] supportedMethods = { HttpMethod.GET, HttpMethod.POST, HttpMethod.HEAD }; + + assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods))); + } + + // PUT + + @Test + public void givenFooService_whenPutExistingEntity_thenItIsUpdated() { + final RestTemplate template = new RestTemplate(); + final HttpHeaders headers = prepareBasicAuthHeaders(); + final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); + + // Create Resource + final ResponseEntity createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + + // Update Resource + final Foo updatedInstance = new Foo("newName"); + updatedInstance.setId(createResponse.getBody().getId()); + final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId(); + final HttpEntity requestUpdate = new HttpEntity<>(updatedInstance, headers); + template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class); + + // Check that Resource was updated + final ResponseEntity updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); + final Foo foo = updateResponse.getBody(); + assertThat(foo.getName(), is(updatedInstance.getName())); + } + + @Test + public void givenFooService_whenPutExistingEntityWithCallback_thenItIsUpdated() { + final RestTemplate template = new RestTemplate(); + final HttpHeaders headers = prepareBasicAuthHeaders(); + final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); + + // Create entity + ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + + // Update entity + final Foo updatedInstance = new Foo("newName"); + updatedInstance.setId(response.getBody().getId()); + final String resourceUrl = fooResourceUrl + '/' + response.getBody().getId(); + template.execute(resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null); + + // Check that entity was updated + response = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); + final Foo foo = response.getBody(); + assertThat(foo.getName(), is(updatedInstance.getName())); + } + + // DELETE + + @Test + public void givenFooService_whenCallDelete_thenEntityIsRemoved() { + final Foo foo = new Foo("remove me"); + final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); + assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + + final String entityUrl = fooResourceUrl + "/" + response.getBody().getId(); + restTemplate.delete(entityUrl); + try { + restTemplate.getForEntity(entityUrl, Foo.class); + fail(); + } catch (final HttpClientErrorException ex) { + assertThat(ex.getStatusCode(), is(HttpStatus.NOT_FOUND)); + } + } + + // + + private HttpHeaders prepareBasicAuthHeaders() { + final HttpHeaders headers = new HttpHeaders(); + final String encodedLogPass = getBase64EncodedLogPass(); + headers.add(HttpHeaders.AUTHORIZATION, "Basic " + encodedLogPass); + return headers; + } + + private String getBase64EncodedLogPass() { + final String logPass = "user1:user1Pass"; + final byte[] authHeaderBytes = encodeBase64(logPass.getBytes(Charsets.US_ASCII)); + return new String(authHeaderBytes, Charsets.US_ASCII); + } + + private RequestCallback requestCallback(final Foo updatedInstance) { + return clientHttpRequest -> { + final ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); + clientHttpRequest.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + clientHttpRequest.getHeaders().add(HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); + }; + } + + // Simply setting restTemplate timeout using ClientHttpRequestFactory + + ClientHttpRequestFactory getSimpleClientHttpRequestFactory() { + final int timeout = 5; + final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); + clientHttpRequestFactory.setConnectTimeout(timeout * 1000); + return clientHttpRequestFactory; + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/DefaultContentTypeInterceptor.java b/spring-5/src/test/java/org/baeldung/okhttp/DefaultContentTypeInterceptor.java new file mode 100644 index 0000000000..c4fc689fad --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/DefaultContentTypeInterceptor.java @@ -0,0 +1,24 @@ +package org.baeldung.okhttp; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class DefaultContentTypeInterceptor implements Interceptor { + + private final String contentType; + + public DefaultContentTypeInterceptor(String contentType) { + this.contentType = contentType; + } + + public Response intercept(Interceptor.Chain chain) throws IOException { + + Request originalRequest = chain.request(); + Request requestWithUserAgent = originalRequest.newBuilder().header("Content-Type", contentType).build(); + + return chain.proceed(requestWithUserAgent); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java new file mode 100644 index 0000000000..a33742b8de --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java @@ -0,0 +1,65 @@ +package org.baeldung.okhttp; + +import static org.baeldung.client.Consts.APPLICATION_PORT; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import org.junit.Before; +import org.junit.Test; + +public class OkHttpFileUploadingLiveTest { + + private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; + + OkHttpClient client; + + @Before + public void init() { + client = new OkHttpClient(); + } + + @Test + public void whenUploadFile_thenCorrect() throws IOException { + + final RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", "file.txt", RequestBody.create(MediaType.parse("application/octet-stream"), new File("src/test/resources/test.txt"))).build(); + + final Request request = new Request.Builder().url(BASE_URL + "/users/upload").post(requestBody).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenGetUploadFileProgress_thenCorrect() throws IOException { + + final RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", "file.txt", RequestBody.create(MediaType.parse("application/octet-stream"), new File("src/test/resources/test.txt"))).build(); + + final ProgressRequestWrapper countingBody = new ProgressRequestWrapper(requestBody, (long bytesWritten, long contentLength) -> { + + final float percentage = (100f * bytesWritten) / contentLength; + assertFalse(Float.compare(percentage, 100) > 0); + }); + + final Request request = new Request.Builder().url(BASE_URL + "/users/upload").post(countingBody).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java new file mode 100644 index 0000000000..6aa33b06b1 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java @@ -0,0 +1,77 @@ +package org.baeldung.okhttp; + +import static org.baeldung.client.Consts.APPLICATION_PORT; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import org.junit.Before; +import org.junit.Test; + +public class OkHttpGetLiveTest { + + private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; + + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + + @Test + public void whenGetRequest_thenCorrect() throws IOException { + final Request request = new Request.Builder().url(BASE_URL + "/date").build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenGetRequestWithQueryParameter_thenCorrect() throws IOException { + final HttpUrl.Builder urlBuilder = HttpUrl.parse(BASE_URL + "/ex/bars").newBuilder(); + urlBuilder.addQueryParameter("id", "1"); + + final String url = urlBuilder.build().toString(); + + final Request request = new Request.Builder().url(url).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenAsynchronousGetRequest_thenCorrect() throws InterruptedException { + final Request request = new Request.Builder().url(BASE_URL + "/date").build(); + + final Call call = client.newCall(request); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) throws IOException { + System.out.println("OK"); + } + + @Override + public void onFailure(Call call, IOException e) { + fail(); + } + }); + + Thread.sleep(3000); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java new file mode 100644 index 0000000000..cfec119fe0 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java @@ -0,0 +1,45 @@ +package org.baeldung.okhttp; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class OkHttpHeaderLiveTest { + + private static final String SAMPLE_URL = "http://www.github.com"; + + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + + @Test + public void whenSetHeader_thenCorrect() throws IOException { + Request request = new Request.Builder().url(SAMPLE_URL).addHeader("Content-Type", "application/json").build(); + + Call call = client.newCall(request); + Response response = call.execute(); + response.close(); + } + + @Test + public void whenSetDefaultHeader_thenCorrect() throws IOException { + + OkHttpClient clientWithInterceptor = new OkHttpClient.Builder().addInterceptor(new DefaultContentTypeInterceptor("application/json")).build(); + + Request request = new Request.Builder().url(SAMPLE_URL).build(); + + Call call = clientWithInterceptor.newCall(request); + Response response = call.execute(); + response.close(); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java new file mode 100644 index 0000000000..52662262e1 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java @@ -0,0 +1,99 @@ +package org.baeldung.okhttp; + +import static org.baeldung.client.Consts.APPLICATION_PORT; + +import java.io.File; +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import okhttp3.Cache; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OkHttpMiscLiveTest { + + private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; + private static Logger logger = LoggerFactory.getLogger(OkHttpMiscLiveTest.class); + + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + + @Test(expected = SocketTimeoutException.class) + public void whenSetRequestTimeout_thenFail() throws IOException { + final OkHttpClient clientWithTimeout = new OkHttpClient.Builder().readTimeout(1, TimeUnit.SECONDS).build(); + + final Request request = new Request.Builder().url(BASE_URL + "/delay/2") // This URL is served with a 2 second delay. + .build(); + + final Call call = clientWithTimeout.newCall(request); + final Response response = call.execute(); + response.close(); + } + + @Test(expected = IOException.class) + public void whenCancelRequest_thenCorrect() throws IOException { + final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + + final Request request = new Request.Builder().url(BASE_URL + "/delay/2") // This URL is served with a 2 second delay. + .build(); + + final int seconds = 1; + final long startNanos = System.nanoTime(); + + final Call call = client.newCall(request); + + // Schedule a job to cancel the call in 1 second. + executor.schedule(() -> { + + logger.debug("Canceling call: " + ((System.nanoTime() - startNanos) / 1e9f)); + call.cancel(); + logger.debug("Canceled call: " + ((System.nanoTime() - startNanos) / 1e9f)); + + }, seconds, TimeUnit.SECONDS); + + logger.debug("Executing call: " + ((System.nanoTime() - startNanos) / 1e9f)); + final Response response = call.execute(); + logger.debug("Call completed: " + ((System.nanoTime() - startNanos) / 1e9f), response); + } + + @Test + public void whenSetResponseCache_thenCorrect() throws IOException { + + final int cacheSize = 10 * 1024 * 1024; // 10 MiB + final File cacheDirectory = new File("src/test/resources/cache"); + final Cache cache = new Cache(cacheDirectory, cacheSize); + + final OkHttpClient clientCached = new OkHttpClient.Builder().cache(cache).build(); + + final Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); + + final Response response1 = clientCached.newCall(request).execute(); + logResponse(response1); + + final Response response2 = clientCached.newCall(request).execute(); + logResponse(response2); + } + + private void logResponse(Response response) throws IOException { + + logger.debug("Response response: " + response); + logger.debug("Response cache response: " + response.cacheResponse()); + logger.debug("Response network response: " + response.networkResponse()); + logger.debug("Response responseBody: " + response.body().string()); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java new file mode 100644 index 0000000000..77a78c2634 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java @@ -0,0 +1,85 @@ +package org.baeldung.okhttp; + +import static org.baeldung.client.Consts.APPLICATION_PORT; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Credentials; +import okhttp3.FormBody; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import org.junit.Before; +import org.junit.Test; + +public class OkHttpPostingLiveTest { + + private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; + private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php"; + + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + + @Test + public void whenSendPostRequest_thenCorrect() throws IOException { + final RequestBody formBody = new FormBody.Builder().add("username", "test").add("password", "test").build(); + + final Request request = new Request.Builder().url(BASE_URL + "/users").post(formBody).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenSendPostRequestWithAuthorization_thenCorrect() throws IOException { + final String postBody = "test post"; + + final Request request = new Request.Builder().url(URL_SECURED_BY_BASIC_AUTHENTICATION).addHeader("Authorization", Credentials.basic("test", "test")).post(RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"), "test post")).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenPostJson_thenCorrect() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\"}"; + + final RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{\"id\":1,\"name\":\"John\"}"); + final Request request = new Request.Builder().url(BASE_URL + "/users/detail").post(body).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } + + @Test + public void whenSendMultipartRequest_thenCorrect() throws IOException { + final RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("username", "test").addFormDataPart("password", "test") + .addFormDataPart("file", "file.txt", RequestBody.create(MediaType.parse("application/octet-stream"), new File("src/test/resources/test.txt"))).build(); + + final Request request = new Request.Builder().url(BASE_URL + "/users/multipart").post(requestBody).build(); + + final Call call = client.newCall(request); + final Response response = call.execute(); + + assertThat(response.code(), equalTo(200)); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/OkHttpRedirectLiveTest.java b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpRedirectLiveTest.java new file mode 100644 index 0000000000..58f84f06a2 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/OkHttpRedirectLiveTest.java @@ -0,0 +1,29 @@ +package org.baeldung.okhttp; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import org.junit.Test; + +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class OkHttpRedirectLiveTest { + + @Test + public void whenSetFollowRedirects_thenNotRedirected() throws IOException { + + OkHttpClient client = new OkHttpClient().newBuilder().followRedirects(false).build(); + + Request request = new Request.Builder().url("http://t.co/I5YYd9tddw").build(); + + Call call = client.newCall(request); + Response response = call.execute(); + + assertThat(response.code(), equalTo(301)); + } +} diff --git a/spring-5/src/test/java/org/baeldung/okhttp/ProgressRequestWrapper.java b/spring-5/src/test/java/org/baeldung/okhttp/ProgressRequestWrapper.java new file mode 100644 index 0000000000..fcae69c609 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/okhttp/ProgressRequestWrapper.java @@ -0,0 +1,73 @@ +package org.baeldung.okhttp; + +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; + +public class ProgressRequestWrapper extends RequestBody { + + protected RequestBody delegate; + protected ProgressListener listener; + + protected CountingSink countingSink; + + public ProgressRequestWrapper(RequestBody delegate, ProgressListener listener) { + this.delegate = delegate; + this.listener = listener; + } + + @Override + public MediaType contentType() { + return delegate.contentType(); + } + + @Override + public long contentLength() throws IOException { + return delegate.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + + BufferedSink bufferedSink; + + countingSink = new CountingSink(sink); + bufferedSink = Okio.buffer(countingSink); + + delegate.writeTo(bufferedSink); + + bufferedSink.flush(); + } + + protected final class CountingSink extends ForwardingSink { + + private long bytesWritten = 0; + + public CountingSink(Sink delegate) { + super(delegate); + } + + @Override + public void write(Buffer source, long byteCount) throws IOException { + + super.write(source, byteCount); + + bytesWritten += byteCount; + listener.onRequestProgress(bytesWritten, contentLength()); + } + + } + + public interface ProgressListener { + + void onRequestProgress(long bytesWritten, long contentLength); + + } +} diff --git a/spring-5/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java b/spring-5/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java new file mode 100644 index 0000000000..84ae1063d9 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java @@ -0,0 +1,49 @@ +package org.baeldung.uribuilder; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +public class SpringUriBuilderTest { + + @Test + public void constructUri() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com").path("/junit-5").build(); + + assertEquals("http://www.baeldung.com/junit-5", uriComponents.toUriString()); + } + + @Test + public void constructUriEncoded() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com").path("/junit 5").build().encode(); + + assertEquals("http://www.baeldung.com/junit%205", uriComponents.toUriString()); + } + + @Test + public void constructUriFromTemplate() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com").path("/{article-name}").buildAndExpand("junit-5"); + + assertEquals("http://www.baeldung.com/junit-5", uriComponents.toUriString()); + } + + @Test + public void constructUriWithQueryParameter() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.google.com").path("/").query("q={keyword}").buildAndExpand("baeldung"); + + assertEquals("http://www.google.com/?q=baeldung", uriComponents.toUriString()); + } + + @Test + public void expandWithRegexVar() { + String template = "/myurl/{name:[a-z]{1,5}}/show"; + UriComponents uriComponents = UriComponentsBuilder.fromUriString(template).build(); + uriComponents = uriComponents.expand(Collections.singletonMap("name", "test")); + + assertEquals("/myurl/test/show", uriComponents.getPath()); + } +} diff --git a/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerLiveTest.java b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerLiveTest.java new file mode 100644 index 0000000000..e8d5ff9f17 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerLiveTest.java @@ -0,0 +1,37 @@ +package org.baeldung.web.controller.mediatypes; + +import com.jayway.restassured.http.ContentType; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import static com.jayway.restassured.RestAssured.given; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class) +public class CustomMediaTypeControllerLiveTest { + private static final String URL_PREFIX = "http://localhost:8082/spring-rest"; + + @Test + public void givenServiceEndpoint_whenGetRequestFirstAPIVersion_thenShouldReturn200() { + given() + .accept("application/vnd.baeldung.api.v1+json") + .when() + .get(URL_PREFIX + "/public/api/items/1") + .then() + .contentType(ContentType.JSON).and().statusCode(200); + } + + + @Test + public void givenServiceEndpoint_whenGetRequestSecondAPIVersion_thenShouldReturn200() { + given() + .accept("application/vnd.baeldung.api.v2+json") + .when() + .get(URL_PREFIX + "/public/api/items/2") + .then() + .contentType(ContentType.JSON).and().statusCode(200); + } +} diff --git a/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerTest.java b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerTest.java new file mode 100644 index 0000000000..a38177f78b --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/CustomMediaTypeControllerTest.java @@ -0,0 +1,42 @@ +package org.baeldung.web.controller.mediatypes; + +import org.baeldung.config.WebConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = WebConfig.class) +@WebAppConfiguration +public class CustomMediaTypeControllerTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void givenServiceUrl_whenGetWithProperAcceptHeaderFirstAPIVersion_thenReturn200() throws Exception { + mockMvc.perform(get("/public/api/items/1").accept("application/vnd.baeldung.api.v1+json")).andExpect(status().isOk()); + } + + @Test + public void givenServiceUrl_whenGetWithProperAcceptHeaderSecondVersion_thenReturn200() throws Exception { + mockMvc.perform(get("/public/api/items/2").accept("application/vnd.baeldung.api.v2+json")).andExpect(status().isOk()); + } +} \ No newline at end of file diff --git a/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/TestConfig.java b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/TestConfig.java new file mode 100644 index 0000000000..66ffe4947d --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/controller/mediatypes/TestConfig.java @@ -0,0 +1,11 @@ +package org.baeldung.web.controller.mediatypes; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + + +@Configuration +@ComponentScan({ "org.baeldung.web" }) +public class TestConfig { + +} diff --git a/spring-5/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java b/spring-5/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java new file mode 100644 index 0000000000..c604db596a --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java @@ -0,0 +1,66 @@ +package org.baeldung.web.controller.redirect; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("file:src/main/webapp/WEB-INF/api-servlet.xml") +@WebAppConfiguration +public class RedirectControllerIntegrationTest { + + private MockMvc mockMvc; + + @Autowired + protected WebApplicationContext wac; + + @Before + public void setup() { + mockMvc = webAppContextSetup(wac).build(); + } + + @Test + public void whenRedirectOnUrlWithUsingXMLConfig_thenStatusRedirectionAndRedirectedOnUrl() throws Exception { + mockMvc.perform(get("/redirectWithXMLConfig")).andExpect(status().is3xxRedirection()).andExpect(view().name("RedirectedUrl")).andExpect(model().attribute("attribute", equalTo("redirectWithXMLConfig"))) + .andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithXMLConfig")); + } + + @Test + public void whenRedirectOnUrlWithUsingRedirectPrefix_thenStatusRedirectionAndRedirectedOnUrl() throws Exception { + mockMvc.perform(get("/redirectWithRedirectPrefix")).andExpect(status().is3xxRedirection()).andExpect(view().name("redirect:/redirectedUrl")).andExpect(model().attribute("attribute", equalTo("redirectWithRedirectPrefix"))) + .andExpect(redirectedUrl("/redirectedUrl?attribute=redirectWithRedirectPrefix")); + } + + @Test + public void whenRedirectOnUrlWithUsingRedirectAttributes_thenStatusRedirectionAndRedirectedOnUrlAndAddedAttributeToFlashScope() throws Exception { + mockMvc.perform(get("/redirectWithRedirectAttributes")).andExpect(status().is3xxRedirection()).andExpect(flash().attribute("flashAttribute", equalTo("redirectWithRedirectAttributes"))) + .andExpect(model().attribute("attribute", equalTo("redirectWithRedirectAttributes"))).andExpect(model().attribute("flashAttribute", equalTo(null))).andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithRedirectAttributes")); + } + + @Test + public void whenRedirectOnUrlWithUsingRedirectView_thenStatusRedirectionAndRedirectedOnUrlAndAddedAttributeToFlashScope() throws Exception { + mockMvc.perform(get("/redirectWithRedirectView")).andExpect(status().is3xxRedirection()).andExpect(model().attribute("attribute", equalTo("redirectWithRedirectView"))).andExpect(redirectedUrl("redirectedUrl?attribute=redirectWithRedirectView")); + } + + @Test + public void whenRedirectOnUrlWithUsingForwardPrefix_thenStatusOkAndForwardedOnUrl() throws Exception { + mockMvc.perform(get("/forwardWithForwardPrefix")).andExpect(status().isOk()).andExpect(view().name("forward:/redirectedUrl")).andExpect(model().attribute("attribute", equalTo("redirectWithForwardPrefix"))).andExpect(forwardedUrl("/redirectedUrl")); + } + +} diff --git a/spring-5/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java b/spring-5/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java new file mode 100644 index 0000000000..e29bef501e --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java @@ -0,0 +1,42 @@ +package org.baeldung.web.controller.status; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.baeldung.config.WebConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = WebConfig.class) +@WebAppConfiguration +public class ExampleControllerIntegrationTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void whenGetRequestSentToController_thenReturnsStatusNotAcceptable() throws Exception { + mockMvc.perform(get("/controller")).andExpect(status().isNotAcceptable()); + } + + @Test + public void whenGetRequestSentToException_thenReturnsStatusForbidden() throws Exception { + mockMvc.perform(get("/exception")).andExpect(status().isForbidden()); + } +} diff --git a/spring-5/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java b/spring-5/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java new file mode 100644 index 0000000000..7828df7304 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java @@ -0,0 +1,63 @@ +package org.baeldung.web.test; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; + +import org.junit.Test; + +import com.jayway.restassured.RestAssured; + +public class RequestMappingLiveTest { + private static String BASE_URI = "http://localhost:8082/spring-rest/ex/"; + + @Test + public void givenSimplePath_whenGetFoos_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "foos").then().assertThat().body(equalTo("Simple Get some Foos")); + } + + @Test + public void whenPostFoos_thenOk() { + RestAssured.given().accept("text/html").post(BASE_URI + "foos").then().assertThat().body(equalTo("Post some Foos")); + } + + @Test + public void givenOneHeader_whenGetFoos_thenOk() { + RestAssured.given().accept("text/html").header("key", "val").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header")); + } + + @Test + public void givenMultipleHeaders_whenGetFoos_thenOk() { + RestAssured.given().accept("text/html").headers("key1", "val1", "key2", "val2").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header")); + } + + @Test + public void givenAcceptHeader_whenGetFoos_thenOk() { + RestAssured.given().accept("application/json").get(BASE_URI + "foos").then().assertThat().body(containsString("Get some Foos with Header New")); + } + + @Test + public void givenPathVariable_whenGetFoos_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "foos/1").then().assertThat().body(equalTo("Get a specific Foo with id=1")); + } + + @Test + public void givenMultiplePathVariable_whenGetFoos_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "foos/1/bar/2").then().assertThat().body(equalTo("Get a specific Bar with id=2 from a Foo with id=1")); + } + + @Test + public void givenPathVariable_whenGetBars_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "bars/1").then().assertThat().body(equalTo("Get a specific Bar with id=1")); + } + + @Test + public void givenParams_whenGetBars_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "bars?id=100&second=something").then().assertThat().body(equalTo("Get a specific Bar with id=100")); + } + + @Test + public void whenGetFoosOrBars_thenOk() { + RestAssured.given().accept("text/html").get(BASE_URI + "advanced/foos").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars")); + RestAssured.given().accept("text/html").get(BASE_URI + "advanced/bars").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars")); + } +} diff --git a/spring-5/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java b/spring-5/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java new file mode 100644 index 0000000000..7f250653ab --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java @@ -0,0 +1,123 @@ +package org.baeldung.web.test; + +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; + +import org.baeldung.config.converter.KryoHttpMessageConverter; +import org.baeldung.web.dto.Foo; +import org.baeldung.web.dto.FooProtos; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +/** + * Integration Test class. Tests methods hits the server's rest services. + */ +public class SpringHttpMessageConvertersLiveTest { + + private static String BASE_URI = "http://localhost:8082/spring-rest/"; + + /** + * Without specifying Accept Header, uses the default response from the + * server (in this case json) + */ + @Test + public void whenRetrievingAFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + final Foo resource = restTemplate.getForObject(URI, Foo.class, "1"); + + assertThat(resource, notNullValue()); + } + + @Test + public void givenConsumingXml_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML)); + final HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + @Test + public void givenConsumingJson_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + final HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + @Test + public void givenConsumingXml_whenWritingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + final RestTemplate restTemplate = new RestTemplate(); + + final Foo resource = new Foo(4, "jason"); + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + headers.setContentType((MediaType.APPLICATION_XML)); + final HttpEntity entity = new HttpEntity(resource, headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.PUT, entity, Foo.class, resource.getId()); + final Foo fooResponse = response.getBody(); + + Assert.assertEquals(resource.getId(), fooResponse.getId()); + } + + @Test + public void givenConsumingProtobuf_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(Arrays.asList(new ProtobufHttpMessageConverter())); + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(ProtobufHttpMessageConverter.PROTOBUF)); + final HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, FooProtos.Foo.class, "1"); + final FooProtos.Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + @Test + public void givenConsumingKryo_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(Arrays.asList(new KryoHttpMessageConverter())); + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(KryoHttpMessageConverter.KRYO)); + final HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + +} diff --git a/spring-5/src/test/resources/.gitignore b/spring-5/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-5/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-5/src/test/resources/test.txt b/spring-5/src/test/resources/test.txt new file mode 100644 index 0000000000..95d09f2b10 --- /dev/null +++ b/spring-5/src/test/resources/test.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file