From 274aafe82394af4b6bd755c8defdf9270fe56067 Mon Sep 17 00:00:00 2001 From: M-Abdelbaset <31687750+M-Abdelbaset@users.noreply.github.com> Date: Thu, 14 Nov 2019 23:12:22 +0200 Subject: [PATCH] Bael-3395: Spring optional path variables (#8106) * initial test cases * changes in @requestMapping --- .../main/java/com/baeldung/model/Article.java | 22 +++++++ .../ArticleViewerController.java | 25 ++++++++ .../ArticleViewerWithMapParamController.java | 29 ++++++++++ ...icleViewerWithOptionalParamController.java | 28 +++++++++ ...ViewerWithRequiredAttributeController.java | 26 +++++++++ ...iewerWithTwoSeparateMethodsController.java | 27 +++++++++ ...rticleViewerControllerIntegrationTest.java | 55 ++++++++++++++++++ ...ollerWithOptionalParamIntegrationTest.java | 55 ++++++++++++++++++ ...rWithRequiredAttributeIntegrationTest.java | 55 ++++++++++++++++++ ...icleViewerWithMapParamIntegrationTest.java | 57 +++++++++++++++++++ ...WithTwoSeparateMethodsIntegrationTest.java | 56 ++++++++++++++++++ 11 files changed, 435 insertions(+) create mode 100644 spring-mvc-java/src/main/java/com/baeldung/model/Article.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java create mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java create mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java create mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java create mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java create mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Article.java b/spring-mvc-java/src/main/java/com/baeldung/model/Article.java new file mode 100644 index 0000000000..141bd17db7 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/model/Article.java @@ -0,0 +1,22 @@ +package com.baeldung.model; + +public class Article { + + public static final Article DEFAULT_ARTICLE = new Article(12); + + private Integer id; + + public Article(Integer articleId) { + this.id = articleId; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Article [id=" + id + "]"; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java new file mode 100644 index 0000000000..2a4f638407 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java @@ -0,0 +1,25 @@ +package com.baeldung.web.controller.optionalpathvars; + +import static com.baeldung.model.Article.DEFAULT_ARTICLE; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Article; + +@RestController +public class ArticleViewerController { + + @RequestMapping(value = {"/article", "/article/{id}"}) + public Article getArticle(@PathVariable(name = "id") Integer articleId) { + + if (articleId != null) { + return new Article(articleId); + } else { + return DEFAULT_ARTICLE; + } + + } + +} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java new file mode 100644 index 0000000000..2e79290c02 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java @@ -0,0 +1,29 @@ +package com.baeldung.web.controller.optionalpathvars; + +import static com.baeldung.model.Article.DEFAULT_ARTICLE; + +import java.util.Map; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Article; + +@RestController +@RequestMapping(value = "/mapParam") +public class ArticleViewerWithMapParamController { + + @RequestMapping(value = {"/article", "/article/{id}"}) + public Article getArticle(@PathVariable Map pathVarsMap) { + + String articleId = pathVarsMap.get("id"); + + if (articleId != null) { + return new Article(Integer.valueOf(articleId)); + } else { + return DEFAULT_ARTICLE; + } + } + +} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java new file mode 100644 index 0000000000..4c077b97c0 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java @@ -0,0 +1,28 @@ +package com.baeldung.web.controller.optionalpathvars; + +import static com.baeldung.model.Article.DEFAULT_ARTICLE; + +import java.util.Optional; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Article;; + +@RestController +@RequestMapping("/optionalParam") +public class ArticleViewerWithOptionalParamController { + + @RequestMapping(value = {"/article", "/article/{id}"}) + public Article getArticle(@PathVariable(name = "id") Optional optionalArticleId) { + + if(optionalArticleId.isPresent()) { + Integer articleId = optionalArticleId.get(); + return new Article(articleId); + }else { + return DEFAULT_ARTICLE; + } + } + +} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java new file mode 100644 index 0000000000..ab3f37c50a --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java @@ -0,0 +1,26 @@ +package com.baeldung.web.controller.optionalpathvars; + +import static com.baeldung.model.Article.DEFAULT_ARTICLE; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Article;; + +@RestController +@RequestMapping(value = "/requiredAttribute") +public class ArticleViewerWithRequiredAttributeController { + + @RequestMapping(value = {"/article", "/article/{id}"}) + public Article getArticle(@PathVariable(name = "id", required = false) Integer articleId) { + + if (articleId != null) { + return new Article(articleId); + } else { + return DEFAULT_ARTICLE; + } + + } + +} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java new file mode 100644 index 0000000000..b4832793ad --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java @@ -0,0 +1,27 @@ +package com.baeldung.web.controller.optionalpathvars; + +import static com.baeldung.model.Article.DEFAULT_ARTICLE; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Article; + +@RestController +@RequestMapping(value = "/seperateMethods") +public class ArticleViewerWithTwoSeparateMethodsController { + + @RequestMapping(value = "/article/{id}") + public Article getArticle(@PathVariable(name = "id") Integer articleId) { + + return new Article(articleId); + } + + @RequestMapping(value = "/article") + public Article getDefaultArticle() { + + return DEFAULT_ARTICLE; + } + +} \ No newline at end of file diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java new file mode 100644 index 0000000000..3e07cd7487 --- /dev/null +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.web.controller.optionalpathvars; + +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.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.spring.web.config.WebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }) +public class ArticleViewerControllerIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void whenIdPathVariableIsPassed_thenResponseOK() throws Exception { + + int articleId = 5; + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/article/{id}", articleId)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(articleId)); + + } + + @Test + public void whenIdPathVariableIsNotPassed_thenResponse500() throws Exception { + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/article")) + .andExpect(MockMvcResultMatchers.status().isInternalServerError()); + + } + + +} \ No newline at end of file diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java new file mode 100644 index 0000000000..c13e5bab4b --- /dev/null +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.web.controller.optionalpathvars; + +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.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.model.Article; +import com.baeldung.spring.web.config.WebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }) +public class ArticleViewerControllerWithOptionalParamIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void givenOPtionalParam_whenIdPathVariableIsPassed_thenResponseOK() throws Exception { + + int articleId = 154; + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/optionalParam/article/{id}", articleId)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(articleId)); + + } + + @Test + public void givenOPtionalParam_whenIdPathVariableIsNotPassed_thenResponseOK() throws Exception { + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/optionalParam/article")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(Article.DEFAULT_ARTICLE.getId())); + + } +} \ No newline at end of file diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java new file mode 100644 index 0000000000..de65e216be --- /dev/null +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.web.controller.optionalpathvars; + +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.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.model.Article; +import com.baeldung.spring.web.config.WebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }) +public class ArticleViewerControllerWithRequiredAttributeIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void givenRequiredAttributeIsFalse_whenIdPathVariableIsPassed_thenResponseOK() throws Exception { + + int articleId = 154; + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/requiredAttribute/article/{id}", articleId)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(articleId)); + + } + + @Test + public void givenRequiredAttributeIsFalse_whenIdPathVariableIsNotPassed_thenResponseOK() throws Exception { + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/requiredAttribute/article")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(Article.DEFAULT_ARTICLE.getId())); + + } +} \ No newline at end of file diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java new file mode 100644 index 0000000000..2fb330f03f --- /dev/null +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.web.controller.optionalpathvars; + +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.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.model.Article; +import com.baeldung.spring.web.config.WebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }) +public class ArticleViewerWithMapParamIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void givenPathVarsMapParam_whenIdPathVariableIsPassed_thenResponseOK() throws Exception { + + int articleId = 5; + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/mapParam/article/{id}", articleId)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(articleId)); + + } + + @Test + public void givenPathVarsMapParam_whenIdPathVariableIsNotPassed_thenResponseOK() throws Exception { + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/mapParam/article")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(Article.DEFAULT_ARTICLE.getId())); + + } + + +} \ No newline at end of file diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java new file mode 100644 index 0000000000..d417b4d397 --- /dev/null +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java @@ -0,0 +1,56 @@ +package com.baeldung.web.controller.optionalpathvars; + +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.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.model.Article; +import com.baeldung.spring.web.config.WebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }) +public class ArticleViewerWithTwoSeparateMethodsIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void givenTwoSeparateMethods_whenIdPathVariableIsPassed_thenResponseOK() throws Exception { + + int articleId = 5; + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/seperateMethods/article/{id}", articleId)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(articleId)); + + } + + @Test + public void givenTwoSeparateMethods_whenIdPathVariableIsNotPassed_thenResponseOK() throws Exception { + + this.mockMvc + .perform(MockMvcRequestBuilders.get("/seperateMethods/article")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(Article.DEFAULT_ARTICLE.getId())); + + } + +} \ No newline at end of file