Spring接收数据,传递数据
前提配置
POM
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-webmvc</artifactId> 4 <version>5.0.2.RELEASE</version> 5 </dependency> 6 <dependency> 7 <groupId>javax.servlet</groupId> 8 <artifactId>jstl</artifactId> 9 <version>1.2</version> 10 </dependency> 11 12 <dependency> 13 <groupId>javax.servlet</groupId> 14 <artifactId>javax.servlet-api</artifactId> 15 <version>3.1.0</version> 16 <scope>provided</scope> 17 </dependency>
applicationContext
1 <context:component-scan base-package="controller"/> 2 <mvc:annotation-driven/> 3 4 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 5 <property name="prefix" value="/WEB-INF/"/> 6 <property name="suffix" value=".jsp"/> 7 </bean>
接收数据
接收数据:从B(Browser)浏览器这一端,传递数据给S(Server)服务端。
数据来源
有以下几个地方
-
url查询字符串:/calc/add?id=100&name=cj -> [id:100],[name:cj]
-
cookie
-
表单(Form)
-
路径变量(Path Variable) /calc/add/a/b ->a,b 这2个值
-
等等
Spring mvc接收数据的形式
Spring自动会帮我们把数据接收,并转换为方法的参数。
数据绑定
Http协议里面的数据都是字符串类型,所以spring mvc帮我们自动绑定的时候,一般都会这么3个任务要做
-
类型转换:把字符串转换为方法参数的类型
-
数据校验
-
数据绑定:给我们设定的对象赋值。
-
简单类型:比如string,int,float等
-
复杂类型:就是自定义的POJO:比如UserInfo
-
接收数据的做法
-
自动
-
@RequestParam
-
@PathVariable
RequestParam
此注解有2个比较有用的属性,
-
required:表明是否必须给参数赋值
-
defaultValue:如果数据来源里面没有此参数的值,那么就采用默认值。
PathVariable
在控制器方法中这样声明
1 @RequestMapping("/data") 2 public class DataReceiveController{ 3 @RequestMapping("/first/{name}") 4 public void receive(UserInfo userInfo, 5 @RequestParam(defaultValue = "1") int id, @PathVariable("name") String xx){ 6 System.out.println(userInfo); 7 System.out.println(id); 8 System.out.println(xx); 9 } 10 }
输入下面的url访问
http://localhost:8080/data/first/abc?id=7
那么路径变量name的值就是abc
绑定到集合(List,Set,Map)
特殊的类型
比如下面这些
-
HttpServletRequest
-
HttpSession
-
HttpServletResponse
-
等
所有支持的类型
传递数据给视图
一般的方法有这么几种
-
利用ModelAndView
-
利用隐式的模型对象,Model,ModelMap,Map<String,Object>
-
原生的API,比如HttpServletRequest,HttpSession
-
@ModelAttribute传递
-
@SessionAttribute
-
RedirectAttributes传递
ModelAndView传递数据
1 @RequestMapping("/passBasic") 2 public ModelAndView basic(){ 3 ModelAndView modelAndView = new ModelAndView(); 4 modelAndView.setViewName("index"); 5 modelAndView.addObject("a", "aaa"); 6 modelAndView.addObject("b", "bbb"); 7 8 return modelAndView; 9 }
在index.jsp里面就可以这样取数据,默认数据是放在请求作用域里
1 <h1>a: ${a}</h1> 2 <h1>b: ${b}</h1>
Model,ModelMap,Map<String,Object>
1 @RequestMapping("/pass1") 2 public String pass1(Model model, ModelMap modelMap,Map<String,Object> map){ 3 modelMap.addAttribute("a", "aaa"); 4 return "index"; 5 }
在视图里面就可以这样取值,上面的数据仍然是放置在请求作用域的,而且三个类型赋值的都是同一个对象,通过调试模式可以看到对象是什么。
1 <h1>aaaa: ${a}</h1>
@ModelAttribute
@ModelAttribute的本质作用就是把数据放到隐式模型对象中
细分的话,可以分为两种,一种是作用在方法参数上,一种是作用在普通的方法上
作用在参数上
1 @RequestMapping("/pass2") 2 public String pass2(@ModelAttribute("b") String b,ModelMap modelMap){ 3 System.out.println("---pass2: " + b); 4 return "index"; 5 }
意思就是好把参数b的数据,以“b”(ModelAttribute指定的值)为键存放到隐式模型对象中,这样视图中就可以取到了。
1 <h1> ${b}</h1>
作用在普通方法上
1 @ModelAttribute("b") 2 public UserInfo getUserInfo(){ 3 UserInfo ui = new UserInfo(); 4 ui.setId(100); 5 ui.setName("100aa"); 6 return ui; 7 }
其含义是每次调用请求处理方法时,这个方法都会在请求处理方法执行前得到执行,并把userinfo对象以键“b" 存放到隐式模型数据中
然后在jsp页面里面就可以取值了 (作业:验证我这句话的正确性)
1 <h1>${af}</h1>
基于这些信息,布置下面的作业
-
添加多个@ModelAttribute修饰的方法,执行顺序会是怎么样的?
-
ModelAttribute修饰的方法的修饰符可以为private吗?
-
其方法能返回void吗?
-
其方法能添加参数,并且Spring mvc会自动注入值吗?
@ SessionAttribute
其作用就是从HttpSession中取值,并赋值给参数,比如下面的代码就是从HttpSession中取出键为session的数据,并自动绑定到name上。
1 @RequestMapping("/get") 2 public String get( @SessionAttribute("session") String name){ 3 // session.getAttribute() 4 System.out.println("get session--" + name); 5 return "index"; 6 }
RedirectAttributes
默认情况下 它的一个重要功能就是把数据临时放置到Session中,重定向一次后就会从session中删除。
下面是代码,请求/redirect时,通过addFlashAttribute方法会临时把数据放置到session中。
1 @RequestMapping("/redirect") 2 public String redirect(RedirectAttributes redirectAttributes){ 3 redirectAttributes.addAttribute("aa", "add attribute"); 4 redirectAttributes.addFlashAttribute("af","add flash"); 5 return "redirect:/redirect2"; 6 7 }
重定向这个方法后,仍然可以取出af的值。
1 @RequestMapping("/redirect2") 2 public String redirect2(ModelMap model){ 3 System.out.println("----已经重定向了。" + model.get("af")); 4 return "redirect:/redirect3"; 5 }
重定向到这个方法时,已经不能从session中取值了。(作业:如果这个方法加一个Model类型作为参数,里面可以看到af的值吗?)
1 @RequestMapping("/redirect3") 2 public String redirect3 (){ 3 return "index3"; 4 }
然后在index3.jsp里面也就无法取得数据了。
作业
作业:理解ModelAttribute
通过地址/abc,下面的代码能在视图中取到值吗?
1 @RequestMapping("/abc") 2 public String redirect3 (){ 3 return "index3"; 4 } 5 @ModelAttribute("b") 6 public UserInfo getUserInfo(){ 7 UserInfo ui = new UserInfo(); 8 ui.setId(100); 9 ui.setName("100aa"); 10 return ui; 11 }
jsp
1 <h1>${b.name}</h1>