View
17.367
Download
1
Category
Tags:
Preview:
DESCRIPTION
A presentation covering Spring MVC (version 3) with annotations and JSR-303 (Java Validation).
Citation preview
Spring MVC – Advanced topicsGuy Nir
January 2012
2
» Annotation driven controllers» Arguments and return types» Validation
Agenda
Spring MVC
Annotation driven controllers
4
» @Controller» @RequestMapping (class-level and method-level)» @PathVariable (URI template)» @ModelAttribute (method-level, argument-level)» @CookieValue, @HeaderValue» @DateTimeFormat» @RequestBody» @ResponseBody
Annotation driven controllers
Spring MVC – Advanced topics
5
» Spring stereotype that identify a class as being a Spring Bean.
» Has an optional ‘value’ property.
Annotation driven controllers@Controller
Spring MVC – Advanced topics
// Bean name is ‘loginController’@Controllerpublic class LoginController {}
// Bean name is ‘portal’.@Controller(“portal”)public class PortalController {}
6
» Define URL mapping for a class and/or method.
» Support deterministic and Ant-style mapping
Annotation driven controllers@RequestMapping
Spring MVC – Advanced topics
// Controller root URL: http://host.com/portal@Controller@RequestMapping(“/portal”)public class PortalController {
// Handle [GET] http://host.com/portal @RequestMapping(method = RequestMethod.GET) public String enterPortal() { ... }
// Handle [GET] http://host.com/portal/userProfile @RequestMapping(“/userProfile”) public String processUserProfileRequest() { ... }}
7
» Available properties: method – List of supported HTTP method (GET, POST, ...). produces/consumes – define expected content types.
Annotation driven controllers@RequestMapping
Spring MVC – Advanced topics
GET http://google.com/ HTTP/1.1Accept: text/html, application/xhtml+xml, */*Accept-Language: he-ILAccept-Encoding: gzip, deflate
HTTP/1.1 200 OKContent-Type: text/html; charset=UTF-8Date: Sun, 29 Jan 2012 19:45:21 GMTExpires: Tue, 28 Feb 2012 19:45:21 GMT
HTTP request
HTTP response
8
Annotation driven controllers@RequestMapping
Spring MVC – Advanced topics
@Controller@RequestMapping(“/portal”)public class UserInfoController {
@RequestMapping(value = “/userInfo/xml“, consumes = “application/json”, produces = “application/xml”) public UserInformation getUserInformationAsXML() { }
@RequestMapping(value = “/userInfo/yaml“, consumes = “application/json”, produces = “application/Json”) public UserInformation getUserInformationAsJSon() { }}
Requires message converters
9
» Required parameters.
» Required headers
Annotation driven controllers@RequestMapping
Spring MVC – Advanced topics
// URL must in a form of: http://host.com/?userId=...&username=admin@RequestMapping(value = “/“, params = { “userId”, “username!=guest”, “!password” })public UserInformation getUserInformationAsXML() {}
@RequestMapping(value = “/userInfo“, headers = { “Accept-Language=he-IL” })public UserInformation getUserInformationAsXML() {} GET http://google.com/
HTTP/1.1Accept-Language: he-ILAccept-Encoding: gzip, deflate
10
» Allow us to define part of the URI as a template token.» Support regular expressions to narrow scope of values.» Only for simple types, java.lang.String or Date variant.» Throw TypeMismatchException on failure to convert.
Annotation driven controllersURI templates (@PathVariable)
Spring MVC – Advanced topics
// Handle ‘userId’ with positive numbers only (0 or greater).@RequestMapping(“/users/{userId:[0-9]+})public void processUserRequest(@PathVariable(“userId”) int userId) { ... }
// Handle ‘userId’ with negative numbers only.@RequestMapping(“/users/{userId:-[0-9]+})public void processUserRequest(@PathVariable(“userId”) int userId) { ... }
11
» Define a new model attribute. Single attribute approach Multiple attributes approach
» Access existing model attribute.
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
12
» Definition of a single model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@Controllerpublic class PrepareFormController
@Override public ModelAndView prepareForm() { ModelAndView mav = new ModelAndView("details"); mav.addObject("userDetails", new UserDetails());
mav.addObject("months", createIntegerList(1, 12)); mav.addObject("years", createIntegerList(1940, 2011)); return mav; }}
13
» Definition of a single model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@Controllerpublic class PrepareFormController
@ModelAttribute("userDetails") public UserDetails newUserDetails() { return new UserDetails(); }
@ModelAttribute("months") public int[] getMonthList() { return new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; }}
14
» Definition of a single model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@Controllerpublic class ValidateUserFormController
@RequestMapping(method = RequestMethod.GET) public String validateForm(HttpServletRequest request, HttpServletResponse ...) { String firstName = request.getParameter(“firstName”); String lastName = request.getParameter(“lastName”);
// ... }}
15
» Definition of a single model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@Controllerpublic class ValidateUserFormController
@RequestMapping(method = RequestMethod.GET) public String validateForm(@ModelAttribute("userDetails") UserDetails details) { // ... }
@ModelAttribute("userDetails") public UserDetails getUserDetails(HttpServletRequest request) { UserDetails user = new UserDetails(); user.setFirstName(request.getParameter("firstName")); return user; }}
16
» Definition of a single model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
public class UserFormControllerTest {
@Test public void testValidateForm() { UserFormController formController = new UserFormController(); UserDetails userDetails = new UserDetails(); // ...
// Simple way to test a method. String viewName = formController.validateForm(userDetails);
Assert.assertEquals("OK", viewName); }}
17
» Definition of a multiple model attribute
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@ModelAttribute("months")public int[] getMonthList() { return new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };}
@ModelAttribute("months")public int[] getYears() { return new int[] { 1940, 1941, ... };}
@ModelAttributepublic void populateAllAttributes(Model model, HttpServletRequest ...) { model.addAttribute(“years", new int[] { ... }); model.addAttribute(“months", new int[] { ... });}
18
» Session attribute binding
Annotation driven controllers@ModelAttribute
Spring MVC – Advanced topics
@Controller@SessionAttributes("userDetails");public class ValidateUserFormController {
// UserDetails instance is extracted from the session. @RequestMapping(method = RequestMethod.GET) public String validateForm(@ModelAttribute("userDetails") UserDetails details) { // ... }}
19
» @CookieValue provide access to client-side cookies.» @HeaderValue provide access to HTTP request header
values.
Annotation driven controllers@CookieValue, @HeaderValue
Spring MVC – Advanced topics
20
» Allow conversion of a string to date-class type. long/java.lang.Long, java.util.Date, java.sql.Date, java.util.Calendar,
Joda time» Applies to @RequstParam and @PathVariable» Support various conventions.
Annotation driven controllers@DateTimeFormat
Spring MVC – Advanced topics
21
Annotation driven controllers@DateTimeFormat
Spring MVC – Advanced topics
@Controllerpublic class CheckDatesRangeController {
// http://host.com/checkDate?birthDate=1975/02/31 @RequestMapping public String checkDateRange( @RequestParam("birthdate") @DateTimeFormat(pattren = "yyyy/mm/dd") Date birthDate) { // ... }}
22
» Provide access to HTTP request body.
» Also supported: Byte array, Form, javax.xml.transform.Source
Annotation driven controllers@RequestBody
Spring MVC – Advanced topics
@Controllerpublic class PersistCommentController {
@RequestMapping(method = RequestMethod.POST) public String checkDateRange(@RequestBody String contents) { // ... }}
23
» Convert return value to HTTP response body.
Annotation driven controllers@ResponseBody
Spring MVC – Advanced topics
@Controllerpublic class FetchCommentController {
@RequestMapping @ResponseBody public String fetchComment(@RequestMapping (“commentId") int commentId) { // ... }
@RequestMapping @ResponseBody public byte[] fetchAsBinary(@RequestMapping (“commentId") int commentId) { // ... }}
Arguments and returntypes
25
Arguments and return types
Spring MVC – Advanced topics
@Controllerpublic class SomeController {
@RequestMapping public String someMethod(...) { ... }
}
Return value
Arguments
26
» HttpServletRequest, HttpServletResponse, HttpSession Servlet API
» WebRequest, NativeWebRequest Spring framework API
» java.util.Locale» java.io.InputStream, java.io.Reader» java.io.OutputStream, java.io.Writer
Arguments and return typesAllowed arguments
Spring MVC – Advanced topics
27
» java.security.Principle» HttpEntity
Spring framework API» java.util.Map, Model, ModelMap
Allow access to the current model.» Errors, BindingResult
Arguments and return typesAllowed arguments
Spring MVC – Advanced topics
28
» ModelAndView, Model, java.util.Map, View» String
Represents a view name, if not specified otherwise.» void» HttpEntity<?>, ResponseEntity<?>» Any other type that has a conversion.
Arguments and return typesAllowed return types
Spring MVC – Advanced topics
Validation
30
» Allow us to validate form in a discipline manner.» Provide a convenient and consistent way to validate
input.» Support JSR-303 (not covered by this presentation).
Validation
Spring MVC – Advanced topics
31
ValidationDeclaring binding process
Spring MVC – Advanced topics
@Controllerpublic class ValidateFormController {
@RequestMapping public String validateForm(UserDetails details, Errors errors) { if (details.getFirstName() == null) { errors.rejectValue("firstName", null, "Missing first name."); } }}
32
ValidationDeclaring binding process
Spring MVC – Advanced topics
@Controllerpublic class ValidateFormController {
@RequestMapping public String validateForm(UserDetails details, Errors errors) { ValidationUtils.rejectIfEmpty(errors, "firstName", null, "Missing first name."); }}
33
ValidationDeclaring binding process
Spring MVC – Advanced topics
<form:form action="form/validate.do" method="POST" modelAttribute="userDetails">
<!-- Prompt for user input --> First name: <form:input path="firstName" />
<!-- Display errors related to ‘firstName’ field --> <form:errors path="firstName"/>
</form:form>
34
» Spring framework support 3rd-party JSR-303 integration.
» Requires additional artifacts JSR-303 spec artifacts.» Requires RI (reference implementation)
e.g: Hibernate Validation
ValidationJSR-303 based validation
Spring MVC – Advanced topics
35
ValidationJSR-303 based validation
Spring MVC – Advanced topics
@RequestMappingpublic String validateForm(@Valid UserDetails details, Errors errors) { ... }
public class UserDetails {
@NotNull // JSR-303 annotation. private String firstName;
@Size(min = 2, max = 64) // JSR-303 annotations. private String lastName;
@Min(1) @Max(12) // JSR-303 annotations. private int birthMonth;}
Recommended