Controller data binding in Spring MVC
Spring's annotations for binding data
1. @RequestParam binds a single request parameter value;
2. @PathVariable binds the URI template variable value;
3. @CookieValue binds the cookie data value
4. @RequestHeader binds the request header data;
5. @ModelValue binds parameters to the command object;
6. @SessionAttributes binds the command object to the session;
7. @RequestBody binds the requested content area data and can perform automatic type conversion, etc.
8. @RequestPart binds "multipart/data" data, in addition to the request parameters that @RequestParam can do, it can also bind uploaded files, etc.
Usage of various annotations
@RequestParam
For the parameters of the methods in the Controller, there are mainly these parameters:
value: parameter name, that is, the name of the input request parameter. For example, username indicates that the value of the parameter named username in the parameter area of the request will be passed in;
required: Whether it is required, the default is true, indicating that there must be corresponding parameters in the request, otherwise a 404 error code will be reported;
defaultValue: The default value, which means the default value if there is no parameter with the same name in the request. The default value can be a SpEL expression, such as "#{systemProperties['java.vm.version']}".
public String requestparam2(@RequestParam("username") String username) public String requestparam4(@RequestParam(value="username",required=false) String username) public String requestparam5( @RequestParam(value="username", required=true, defaultValue="zhang") String username) public String requestparam7(@RequestParam(value="role") String roleList) public String requestparam7(@RequestParam(value="role") String[] roleList) public String requestparam8(@RequestParam(value="list") List<String> list)
@PathVariable
主要用于从URL中取出参数
@RequestMapping(value="/users/{userId}/topics/{topicId}") public String test( @PathVariable(value="userId") int userId, @PathVariable(value="topicId") int topicId)
@CookieValue
用于将请求的Cookie数据映射到功能处理方法的参数上。
public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId) public String test2(@CookieValue(value="JSESSIONID", defaultValue="") Cookie sessionId)
@RequestHeader
用于将请求的头信息区数据映射到功能处理方法的参数上。
@RequestMapping(value="/header") public String test( @RequestHeader("User-Agent") String userAgent, @RequestHeader(value="Accept") String[] accepts)
@Value
用于将一个SpEL表达式结果映射到到功能处理方法的参数上。
public String test(@Value("#{systemProperties['java.vm.version']}") String jvmVersion)
@ModelAttribute
绑定请求参数到命令对象。
@ModelAttribute的作用有三个:
1. 绑定请求参数到命令对象:将参数绑定到一个对象上,并且这个对象可以让jsp直接使用
2. 暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
3. 暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
4. 匿名绑定命令参数
绑定请求参数到命令对象
如用户登录,我们需要捕获用户登录的请求参数(用户名、密码)并封装为用户对象,此时我们可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。
public String test1(@ModelAttribute("user") UserModel user)
1. 只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。
2. 绑定请求参数到命令对象支持对象图导航式的绑定,如请求参数包含“?username=zhang&password=123&workInfo.city=bj”自动绑定到user中的workInfo属性的city属性中。
@RequestMapping(value="/model2/{username}") public String test2(@ModelAttribute("model") DataBinderTestModel model) {当URI模板变量和请求参数同名时,URI模板变量具有高优先权。
暴露表单引用对象为模型数据
@ModelAttribute("cityList") public List<String> cityList() { return Arrays.asList("北京", "山东"); }如上代码会在执行功能处理方法之前执行,并将其自动添加到模型对象中,在功能处理方法中调用Model 入参的containsAttribute("cityList")将会返回true。
@ModelAttribute("user") //① public UserModel getUser(@RequestParam(value="username", defaultValue="") String username) { //TODO 去数据库根据用户名查找用户对象 UserModel user = new UserModel(); user.setRealname("zhang"); return user; }如你要修改用户资料时一般需要根据用户的编号/用户名查找用户来进行编辑,此时可以通过如上代码查找要编辑的用户。
也可以进行一些默认值的处理。
@RequestMapping(value="/model1") //② public String test1(@ModelAttribute("user") UserModel user, Model model)1. 首先执行@ModelAttribute注解的方法,准备视图展示时所需要的模型数据;@ModelAttribute注解方法形式参数规则和@RequestMapping规则一样,如可以有@RequestParam等;
2. 执行@RequestMapping注解方法,进行模型绑定时首先查找模型数据中是否含有同名对象,如果有直接使用,如果没有通过反射创建一个,因此②处的user将使用①处返回的命令对象。即②处的user等于①处的user。
暴露@RequestMapping方法返回值为模型数据
public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user)
匿名绑定命令参数
public String test4(@ModelAttribute UserModel user, Model model) 或 public String test5(UserModel user, Model model)此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字为“userModel”。
public @ModelAttribute List<String> test6() 或 public @ModelAttribute List<UserModel> test7()对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List<String>生成的模型对象属性名为“stringList”,List<UserModel>生成的模型对象属性名为“userModelList”。
其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map<String, UserModel>类型的模型对象属性名为“map”。
@SessionAttributes
绑定命令对象到session
有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据,如多步骤提交的表单。Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。
//1、在控制器类头上添加@SessionAttributes注解 @SessionAttributes(value = {"user"}) //① public class SessionAttributeController //2、@ModelAttribute注解的方法进行表单引用对象的创建 @ModelAttribute("user") //② public UserModel initUser() //3、@RequestMapping注解方法的@ModelAttribute注解的参数进行命令对象的绑定 @RequestMapping("/session1") //③ public String session1(@ModelAttribute("user") UserModel user) //4、通过SessionStatus的setComplete()方法清除@SessionAttributes指定的会话数据 @RequestMapping("/session2") //③ public String session(@ModelAttribute("user") UserModel user, SessionStatus status) { if(true) { //④ status.setComplete(); } return "success"; }
Controller中方法能够支持的参数类型
1. ServletRequest/HttpServletRequest 和 ServletResponse/HttpServletResponse
public String requestOrResponse ( ServletRequest servletRequest, HttpServletRequest httpServletRequest, ServletResponse servletResponse, HttpServletResponse httpServletResponse )
2. InputStream/OutputStream 和 Reader/Writer
public void inputOrOutBody(InputStream requestBodyIn, OutputStream responseBodyOut) throws IOException { responseBodyOut.write("success".getBytes()); } public void readerOrWriteBody(Reader reader, Writer writer) throws IOException { writer.write("hello"); }
3. WebRequest/NativeWebRequest
public String webRequest(WebRequest webRequest, NativeWebRequest nativeWebRequest) { System.out.println(webRequest.getParameter("test"));//①得到请求参数test的值 webRequest.setAttribute("name", "value", WebRequest.SCOPE_REQUEST);//② System.out.println(webRequest.getAttribute("name", WebRequest.SCOPE_REQUEST)); HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);//③ HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class); return "success"; }
4. HttpSession
public String session(HttpSession session) { System.out.println(session); return "success"; }
5. 命令/表单对象
@RequestMapping(value = "/commandObject", method = RequestMethod.GET) public String toCreateUser(HttpServletRequest request, UserModel user) { return "customer/create"; } @RequestMapping(value = "/commandObject", method = RequestMethod.POST) public String createUser(HttpServletRequest request, UserModel user) { System.out.println(user); return "success"; }
6. Model、Map、ModelMap
@RequestMapping(value = "/model") public String createUser(Model model, Map model2, ModelMap model3) { model.addAttribute("a", "a"); model2.put("b", "b"); model3.put("c", "c"); System.out.println(model == model2); System.out.println(model2 == model3); return "success";} @RequestMapping(value = "/mergeModel") public ModelAndView mergeModel(Model model) { model.addAttribute("a", "a");//①添加模型数据 ModelAndView mv = new ModelAndView("success"); mv.addObject("a", "update");//②在视图渲染之前更新③处同名模型数据 model.addAttribute("a", "new");//③修改①处同名模型数据 //视图页面的a将显示为"update" 而不是"new" return mv; }
7. Errors/BindingResult
@RequestMapping(value = "/error1") public String error1(UserModel user, BindingResult result) @RequestMapping(value = "/error2") public String error2(UserModel user, BindingResult result, Model model) { @RequestMapping(value = "/error3") public String error3(UserModel user, Errors errors) @RequestMapping(value = "/error4") public String error4(UserModel user, Model model, Errors errors) }
8. 其他
public String other(Locale locale, Principal principal)