By default Spring provides support for XML content-type to backing object conversion by using Jaxb2RootElementHttpMessageConverter . We just need to use @RequestBody or @ResponseBody on the target type.
Let's see some examples.
Create Backing Object
package com.logicbig.example;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@XmlRootElement
public class User implements Serializable {
private Long id;
private String name;
private String password;
private String emailAddress;
//getters and setters
}
Note that we have to use JAXB bind annotations for message conversion to work.
Using @RequestBody in our Controller
@Controller
@RequestMapping("users")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "register",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_XML_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public void handleXMLPostRequest (@RequestBody User user) {
System.out.println(user);
userService.saveUser(user);
}
}
The Unit test
Using Spring MVC Test Framework:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class RegistrationControllerTest {
@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 {
ResultMatcher ok = MockMvcResultMatchers.status()
.isOk();
MockHttpServletRequestBuilder builder =
MockMvcRequestBuilders.post("/users/register")
.contentType(MediaType.APPLICATION_XML)
.content(createUserInXml(
"joe",
"joe@example.com",
"abc"));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isCreated());
}
private static String createUserInXml (String name, String email, String password) {
return "<user>" +
"<name>" + name + "</name>" +
"<emailAddress>" + email + "</emailAddress>" +
"<password>" + password + "</password>" +
"</user>";
}
}
Using @ResponseBody in our Controller
In this example we are going to show how to return a List of users. JAXB requires to wrap the collection in a separate class to handle generic properly:
package com.logicbig.example;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement
public class UserList {
private List<User> users;
//getter and setter
}
@Controller
@RequestMapping("users")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET,
produces = MediaType.APPLICATION_XML_VALUE)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public UserList handleAllUserRequest () {
UserList list = new UserList();
list.setUsers(userService.getAllUsers());
return list;
}
}
The Unit test
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class RegistrationControllerTest {
@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 {
ResultMatcher ok = MockMvcResultMatchers.status()
.isOk();
MockHttpServletRequestBuilder builder =
MockMvcRequestBuilders.post("/users/register")
.contentType(MediaType.APPLICATION_XML)
.content(createUserInXml(
"joe",
"joe@example.com",
"abc"));
//create one more user
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isCreated());
builder = MockMvcRequestBuilders.post("/users/register")
.contentType(MediaType.APPLICATION_XML)
.content(createUserInXml("mike",
"mike@example.com",
"123"));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isCreated());
//getting all users and print them
builder = MockMvcRequestBuilders.get("/users")
.accept(MediaType.APPLICATION_XML);
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isOk())
.andDo(MockMvcResultHandlers.print());
}
....
}
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/xml]}
Handler:
Type = com.logicbig.example.UserController
Method = public com.logicbig.example.UserList com.logicbig.example.UserController.handleAllUserRequest()
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/xml]}
Content type = application/xml
Body = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><userList><users><emailAddress>joe@example.com</emailAddress><id>1</id><name>joe</name><password>abc</password></users><users><emailAddress>mike@example.com</emailAddress><id>2</id><name>mike</name><password>123</password></users></userList>
Forwarded URL = null
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.
- JDK 1.8
- Maven 3.0.4
|