首先先做点大略的准备事情,写一个只包含一个button的jsp页面,这里可以瞥见,只是写了个大略按钮事宜,跳转的modelTest.do这个路径
<%@ page language=34;java" import="java.util." pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript" src="<%=basePath%>static/js/jquery.min.js"></script> </head> <script type="text/javascript"> $(function(){ $("#modelTest").on("click",function(){ window.location.href="<%=basePath%>model/modelTest.do"; }) }); </script> <body> <input type="button" id="modelTest" value="测试"> </body></html>
表明标记在方法上
下面,再让我们写一个controller掌握器,这里我们在掌握器中写两个方法,个中一个利用@RequestMapping方法路径标记为modelTest.do,其余一个方法不标记路径,利用@ModelAttribute标记
package com.lovo.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping(value="model")public class ModelAttributeTest { @ModelAttribute public void init() { System.out.println("最先实行的方法"); } @ModelAttribute public void init02() { System.out.println("最先实行的方法02"); } @RequestMapping(value="modelTest.do") public String modelTest() { System.out.println("然后实行的方法"); return "modelTest"; } @ModelAttribute public void init03() { System.out.println("最先实行的方法03"); }}
支配后运行,点击页面测试按钮,查看掌握台输出,这个时候你会创造,后台掌握器并没有直接进入modelTest.do的路径,而是先实行了被@ModelAttribute标记的init方法。该当这么理解,当同一个controller中有任意一个方法被@ModelAttribute表明标记,页面要求只要进入这个掌握器,不管要求那个方法,均会先实行被@ModelAttribute标记的方法,以是我们可以用@ModelAttribute表明的方法做一些初始化操作。当同一个controller中有多个方法被@ModelAttribute表明标记,所有被@ModelAttribute标记的方法均会被实行,按先后顺序实行,然后再进入要求的方法。
下面方法做一些变形,变形为带有参数的返回,这样也是实际开拓中常常会操作的首先像创建个pojo工具,工具包含userName,sex两个属性。并对JSP及掌握器代码做一些修正
页面利用EL表达式接管返回参数
<script type="text/javascript"> $(function(){ $("#modelTest").on("click",function(){ window.location.href="<%=basePath%>model/modelTest.do"; }) }); </script> <body> <input type="button" id="modelTest" value="测试"> <input type="text" value="${pojo.userName }"> <input type="text" value="${pojo.sex }"> </body>
@ModelAtterbute方法无返回值情形
@Controller@RequestMapping(value="model")public class ModelAttributeTest { @ModelAttribute public void init(Model mode) { PojoTest pojo=new PojoTest(null, "小明", "男"); mode.addAttribute("pojo", pojo); } @RequestMapping(value="modelTest.do") public String modelTest() { return "modelTest"; }}
访问ModelTest.jsp页面并点击测试
涌现如下结果
从实行结果看出,当访问要求时,会首先访问init方法,然后再对test方法进行访问,并且是同一个要求,由于model模型数据的浸染域与request相同,以是可以用此标记直接标记在方法上对实际要访问的方法进行一些初始化操作
@ModelAttribute标记方法有返回值
@Controller@RequestMapping(value="model")public class ModelAttributeTest { @ModelAttribute public String init(Model mode) { System.out.println("进入init方法"); PojoTest pojo=new PojoTest(null, "小明", "男"); mode.addAttribute("pojo", pojo); return "model/befor.do"; } @RequestMapping(value="befor.do") public String befor(){ System.out.println("进入befor方法"); return "index"; } @RequestMapping(value="modelTest.do") public String modelTest() { System.out.println("进入modelTest方法"); return "modelTest"; }}
这里轻微做了点变形,可以看到在被@ModelAttribute方法中设值了返回路径为befor方法,但是在在代码运行的过程中并不会跳转befor方法,而是在代码实行完成return之前直接跳转了实际要求的方法。
当@RequestMapping标记和@ModelAttribute同时标记在一个方法上
@Controller@RequestMapping(value="model")public class ModelAttributeTest { @RequestMapping(value="modelTest.do") @ModelAttribute(value="pojo") public String modelTest() { System.out.println("进入modelTest方法"); return "modelTest"; }}
点击测试页面创造进入掌握器后返回,页面报404,这是由于当两个表明标记到同一个方法上时,逻辑视图名并不是返回值,而是返回要求的路径,根据model/modelTest.do天生逻辑视图。在这里我们修正下代码,把controller上的@RequestMapping标记去掉,并修正下页面的要求路径,让天生的视图路径和访问的页面路径相同
@Controllerpublic class ModelAttributeTest { @RequestMapping(value="modelTest.do") @ModelAttribute(value="pojo") public String modelTest() { System.out.println("进入modelTest方法"); return "modelTest"; }}
<script type="text/javascript"> $(function(){ $("#modelTest").on("click",function(){ window.location.href="<%=basePath%>modelTest.do"; }) }); </script> <body> <input type="button" id="modelTest" value="测试"> <input type="text" value="${pojo }"> </body>
点击测试页面,会创造当两个表明同时表明到一个方法上时,方法的返回值会变成model模型的返回值,key是标记的名
@ModelAttribute标记在参数前
从from表单或url地址中取值,这里就以url地址为例,为了避免url地址中文乱码问题,这里调用了encodeURL函数
<script type="text/javascript"> $(function(){ $("#modelTest").on("click",function(){ window.location.href="<%=basePath%>model/modelTest.do?userName="+encodeURI('小明')+"&sex="+encodeURI('男'); }) }); </script> <body> <input type="button" id="modelTest" value="测试"> <input type="text" value="${pojo.userName }"> <input type="text" value="${pojo.sex }"> </body>
@Controller@RequestMapping(value="model")public class ModelAttributeTest { @RequestMapping(value="modelTest.do") public String modelTest(@ModelAttribute("pojo") PojoTest pojo) { try { pojo.setUserName(new String(pojo.getUserName().getBytes("iso-8859-1"),"utf-8")); pojo.setSex(new String(pojo.getSex().getBytes("iso-8859-1"),"utf-8")); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(pojo); return "modelTest"; }}
点击页面测试,页面文本框会显示URL地址通报过来的参数,由于SpringMVC会自动匹匹配页面通报过来的参数的name属性和后台掌握器中的方法中的参数名,如果参数名相同,会自动匹配,如果掌握器中方法是封装的bean,会自动匹配bean中的属性,实在这种取值办法不须要用@ModelAttribute表明,只要知足匹配哀求,也能拿得到值
从model工具中取值
@Controller@RequestMapping(value="model")public class ModelAttributeTest { @ModelAttribute("pojo") public PojoTest init( PojoTest pojo) { pojo.setSex("男"); return pojo; } @RequestMapping(value="modelTest.do") public String modelTest(@ModelAttribute("pojo") PojoTest pojo) { pojo.setUserName("小明"); return "modelTest"; }}
点击测试创造,modelTest拿到inint方法中的pojo工具,合并两次set的参数后返回页面