Spring provides support for JSON content-type to backing object conversion by using MappingJackson2HttpMessageConverter . This message converter won't get activated unless we add jackson-databind jar in the classpath.
Let's see how we can do that with a step by step example.
Add jackson-databind dependency
Add this dependency in maven pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.2</version>
</dependency>
Create Backing Object
public class User implements Serializable {
private Long id;
private String name;
private String password;
private String emailAddress;
//getters and setters
}
Create Controller
@Controller
@RequestMapping("users")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "register", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public void handleJsonPostRequest (@RequestBody User user, Model model) {
System.out.println("saving user: "+user);
userService.saveUser(user);
}
@RequestMapping(method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public List<User> handleAllUserRequest () {
return userService.getAllUsers();
}
}
Note that unlike XML message conversion, we don't have to wrap the collection type into a new class.
Unit Test
Using Spring MVC Test Framework
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class ControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup () {
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
this.mockMvc = builder.build();
}
@Test
public void testUserController () throws Exception {
MockHttpServletRequestBuilder builder =
MockMvcRequestBuilders.post("/users/register")
.contentType(MediaType.APPLICATION_JSON)
.content(createUserInJson("joe",
"joe@example.com",
"abc"));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isCreated());
// create one more user
builder = MockMvcRequestBuilders.post("/users/register")
.contentType(MediaType.APPLICATION_JSON)
.content(createUserInJson("mike",
"mike@example.com",
"123"));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isCreated());
// get all users
builder = MockMvcRequestBuilders.get("/users")
.accept(MediaType.APPLICATION_JSON);
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isOk())
.andDo(MockMvcResultHandlers.print());
}
private static String createUserInJson (String name, String email, String password) {
return "{ \"name\": \"" + name + "\", " +
"\"emailAddress\":\"" + email + "\"," +
"\"password\":\"" + password + "\"}";
}
}
Output:
saving user: User{id=null, name='joe', password='abc', emailAddress='joe@example.com'}
saving user: User{id=null, name='mike', password='123', emailAddress='mike@example.com'}
MockHttpServletRequest:
HTTP Method = GET
Request URI = /users
Parameters = {}
Headers = {Accept=[application/json]}
Handler:
Type = com.logicbig.example.UserController
Method = public java.util.List<com.logicbig.example.User> com.logicbig.example.UserController.handleAllUserRequest()
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = users
View = null
Attribute = userList
value = [User{id=1, name='joe', password='abc', emailAddress='joe@example.com'}, User{id=2, name='mike', password='123', emailAddress='mike@example.com'}]
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = /WEB-INF/views/users.jsp
Redirected URL = null
Cookies = []
Example ProjectDependencies and Technologies Used: - Spring Web MVC 4.2.4.RELEASE: Spring Web MVC.
- Spring TestContext Framework 4.2.4.RELEASE: Spring TestContext Framework.
- Java Servlet API 3.0.1
- JUnit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
- jackson-databind 2.7.2: General data-binding functionality for Jackson: works on core streaming API.
- JDK 1.8
- Maven 3.0.4
|