Spring MVC 之控制器数据绑定
spring用于绑定数据的注解
1. @RequestParam绑定单个请求参数值;
2. @PathVariable绑定URI模板变量值;
3. @CookieValue绑定Cookie数据值
4. @RequestHeader绑定请求头数据;
5. @ModelValue绑定参数到命令对象;
6. @SessionAttributes绑定命令对象到session;
7. @RequestBody绑定请求的内容区数据并能进行自动类型转换等。
8. @RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的文件等。
各种注解的用法
@RequestParam
针对Controller中方法的参数使用的,主要有这些参数:
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL表达式,如“#{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)