diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsConfig.java b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsConfig.java new file mode 100644 index 0000000000..f2049554ab --- /dev/null +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsConfig.java @@ -0,0 +1,36 @@ +package com.baeldung.jsonparams.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = { "com.baeldung.jsonparams" }) +public class JsonParamsConfig implements WebMvcConfigurer { + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver bean = new InternalResourceViewResolver(); + bean.setPrefix("/WEB-INF/"); + bean.setSuffix(".jsp"); + return bean; + } + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } + +} diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsInit.java b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsInit.java new file mode 100644 index 0000000000..6db2a92350 --- /dev/null +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/config/JsonParamsInit.java @@ -0,0 +1,29 @@ +package com.baeldung.jsonparams.config; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; + +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +public class JsonParamsInit // implements WebApplicationInitializer +{ + + //uncomment to run the product controller example + //@Override + public void onStartup(ServletContext sc) throws ServletException { + AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); + root.register(JsonParamsConfig.class); + root.setServletContext(sc); + sc.addListener(new ContextLoaderListener(root)); + + DispatcherServlet dv = new DispatcherServlet(root); + + ServletRegistration.Dynamic appServlet = sc.addServlet("jsonparams-mvc", dv); + appServlet.setLoadOnStartup(1); + appServlet.addMapping("/"); + } + +} diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/controller/ProductController.java b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/controller/ProductController.java new file mode 100644 index 0000000000..e4e2ce085d --- /dev/null +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/controller/ProductController.java @@ -0,0 +1,57 @@ +package com.baeldung.jsonparams.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.baeldung.jsonparams.model.Product; +import com.baeldung.jsonparams.propertyeditor.ProductEditor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Controller +@RequestMapping("/products") +public class ProductController { + + private ObjectMapper objectMapper; + + @Autowired + public void setObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @InitBinder + public void initBinder(WebDataBinder binder) { + binder.registerCustomEditor(Product.class, new ProductEditor(objectMapper)); + } + + @PostMapping("/create") + @ResponseBody + public Product createProduct(@RequestBody Product product) { + // custom logic + return product; + } + + @GetMapping("/get") + @ResponseBody + public Product getProduct(@RequestParam String product) throws JsonMappingException, JsonProcessingException { + final Product prod = objectMapper.readValue(product, Product.class); + return prod; + } + + @GetMapping("/get2") + @ResponseBody + public Product get2Product(@RequestParam Product product) { + // custom logic + return product; + } + +} diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/model/Product.java b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/model/Product.java new file mode 100644 index 0000000000..b0baf0aa57 --- /dev/null +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/model/Product.java @@ -0,0 +1,37 @@ +package com.baeldung.jsonparams.model; + +public class Product { + + private int id; + private String name; + private double price; + + public Product() { + + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String nom) { + this.name = nom; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + +} diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/propertyeditor/ProductEditor.java b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/propertyeditor/ProductEditor.java new file mode 100644 index 0000000000..11766118cd --- /dev/null +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/jsonparams/propertyeditor/ProductEditor.java @@ -0,0 +1,34 @@ +package com.baeldung.jsonparams.propertyeditor; + +import java.beans.PropertyEditorSupport; + +import org.springframework.util.StringUtils; + +import com.baeldung.jsonparams.model.Product; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class ProductEditor extends PropertyEditorSupport { + + private ObjectMapper objectMapper; + + public ProductEditor(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.isEmpty(text)) { + setValue(null); + } else { + Product prod = new Product(); + try { + prod = objectMapper.readValue(text, Product.class); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException(e); + } + setValue(prod); + } + } + +} diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/jsonparams/JsonParamsIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/jsonparams/JsonParamsIntegrationTest.java new file mode 100644 index 0000000000..bceadc4896 --- /dev/null +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/jsonparams/JsonParamsIntegrationTest.java @@ -0,0 +1,71 @@ +package com.baeldung.jsonparams; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.AnnotationConfigWebContextLoader; +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.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.baeldung.jsonparams.config.JsonParamsConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { JsonParamsConfig.class }, loader = AnnotationConfigWebContextLoader.class) +public class JsonParamsIntegrationTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Before + public void setUp() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac) + .build(); + } + + @Test + public void whenJsonIsPassedWithPost_thenResponseOK() throws Exception { + + this.mockMvc.perform(post("/products/create").accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"id\": 1,\"name\": \"Asus Zenbook\",\"price\": 800}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value("1")) + .andExpect(jsonPath("$.name").value("Asus Zenbook")); + + } + + @Test + public void whenJsonIsPassedWithGet_thenResponseOK() throws Exception { + + this.mockMvc.perform(get("/products/get").contentType(MediaType.APPLICATION_JSON) + .queryParam("product", "{\"id\": 2,\"name\": \"HP EliteBook\",\"price\": 700}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value("2")) + .andExpect(jsonPath("$.name").value("HP EliteBook")); + + } + + @Test + public void whenJsonIsPassedWithGet2_thenResponseOK() throws Exception { + + this.mockMvc.perform(get("/products/get2").contentType(MediaType.APPLICATION_JSON) + .queryParam("product", "{\"id\": 3,\"name\": \"Dell G5 15\",\"price\": 1200}")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").value("3")) + .andExpect(jsonPath("$.name").value("Dell G5 15")); + + } + +}