###0.前言
《Java EE互联网轻量级框架整合开发——SSM框架(Spring MVC+Spring+MyBatis)和Redis实现》
本文主要记录Controller与页面数据传递
- Controller接收参数:
- 普通参数接收
- 对象类型参数接收
- 接收参数别名(@RequestParam)
- URL参数(@PathVariable)
- 请求实体提交(@RequestBody):数组类型、集合类型、JSON等
- Controller传递参数:
- 基础参数传递
- 对象类型参数传递
- 缓存数据到HTTP
- @RequestAttribute:获取HTTP的请求(request)对象属性值,用来传递给控制器的参数。
- @SessionAttribute/@SessionAttributes:在HTTP的会话(Session)对象属性中,用来传递给控制器的参数
- @CookieValue:获取cookie参数
- @RequestHeader:获取请求头参数
- 重定向(redirect)
###1. Controller接收参数
####1.1 普通参数接收
一般情况下保持HTTP的请求参数的名称和控制器方法的参数名称一致,就可以获取到HTTP的请求参数。
eg:
请求为: http://..../getRole?id=1&roleName=test
Controller中方法:(普通参数接收)
public ModelAndView getRole(String id,String roleName){
//...
}
####1.2 对象类型参数接收
存在一些情况导致接收参数过多,可以考虑通过POJO来管理参数
eg:
请求为:http://..../getRole?id=1&roleName=test
POJO类定义:
public class RoleParams{
private String id;
private String roleName;
//...getter/setter
}
Controller中方法: (对象类型参数接收)
public ModelAndView getRole(RoleParams roleParams){
//...
}
只要请求参数名与controller中的接收参数的名称一致,那么就能接收。
####1.3 参数别名接收
在多人开发的过程中,前端请求可能由第三方完成,导致命名规范不一样。
那么在不修改程序命名的情况下接收参数就需要用到@RequestParam
eg:
请求为:http://..../getRole?id=1&role_name=test
Controller中方法:(参数别名接收)
public ModelAndView getRole(String id,@RequestParam("role_name")String roleName){
//...
}
需要注意的是:使用@RequestParam注解后,参数默认情况下不为空,为空会抛出异常。
允许为空的设置:设置required = false
@RequestParam(value = "role_name",required = false)String roleName
####1.4 URL中的参数接收
如果使用RESTful风格的请求,那么参数的传递可能直接在URL中。
eg:
请求为:http://..../getRole/1
Controller中方法:(URL中的参数接收)
@RequestMapping("/getRole/{id}")
public ModelAndView getRole(@PathVariable("id")String id){ //@PathVariable允许参数为空
//...
}
####1.5 请求实体提交
在HTTP的Post请求中,存在一类需求是将数据序列化后直接提交到报文中的。
默认的POST提交的内容实体的格式为:key1=value1&key2=value2
需求需要提交JSON数据到报文中:contentType:"application/json"
,
内容为:{"key1":"value1","key2":"value2"}
POJO类定义:
public class JsonParams{
private String key1;
private String key2;
//...getter/setter
}
Controller中方法:(请求实体提交的参数接口)
public ModelAndView getData(@RequestBody JsonParams jsonParams){
//...
}
集合类JSON:[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}]
Controller中方法:(请求实体提交的参数接口(集合))
public ModelAndView getData(@RequestBody List<JsonParams> jsonParamsList){
//...
}
通常情况,复杂的数据结构都通过序列化为JSON格式后提交,controller中通过@RequestBody接收
###2. Controller传递参数
Controller可以通过Model、ModelMap和ModelAndView向页面传递参数,一般只需要在控制器的方法中添加它们的其中一个,Spring MVC运行的时候,会自动初始化它们。
Model:
public ModelAndView getRoleByModel(@RequestParam("id") Long id, Model model) { Role role = roleService.getRole(id); ModelAndView mv = new ModelAndView(); mv.setViewName("roleDetails"); model.addAttribute("name","test");//传递字符串对象 model.addAttribute("role", role); //传递Role对象到页面 return mv; }
ModelMap:
public ModelAndView getRoleByModelMap(@RequestParam("id") Long id, ModelMap modelMap) { Role role = roleService.getRole(id); ModelAndView mv = new ModelAndView(); mv.setViewName("roleDetails"); modelMap.addAttribute("name","test");//传递字符串对象 modelMap.addAttribute("role", role);//传递Role对象到页面 return mv; }
ModelAndView:
public ModelAndView getRoleByMv(@RequestParam("id") Long id, ModelAndView mv) { Role role = roleService.getRole(id); mv.setViewName("roleDetails"); mv.addObject("name","test");//传递字符串对象 mv.addObject("role", role); //传递Role对象到页面 return mv; }
页面的接收:
页面通过${参数名}
获取Controller传递到页面的值:
addAttribute("name","test")
对应:${name}
addAttribute("role", role)
对应:${role.id}
、${role.roleName}
等
需要注意:重定向不能通过这种方式传递POJO对象(使用RedirectAttributes.addFlashAttribute)
###3. 缓存数据到HTTP
####3.1 RequestAttribute
从Request对象中取出请求属性,有效期为:单次请求中。
JSP页面代码:
<%
//设置请求属性
request.setAttribute("id",1L);
//转发给控制器
request.getRequestDispatcher("./attribute/requestAttribute.do").forward(request, response);
%>
Controller中接收代码:
@RequestMapping("/requestAttribute")
public ModelAndView reqAttr(@RequestAttribute("id") Long id) {
//...
}
注:@RequestAttribute默认为非空。 可以为空需要设置:required = false
(类似@RequestParam)
####3.2 @SessionAttribute和@SessionAttributes
从HTTP的会话中取出属性,有效期是:本次会话期间
@SessionAttributes只能设置在类名上,不能设置在方法和参数上。
eg:
//可以配置数据模型的名称和类型,两者取或关系
@SessionAttributes(names ={"id"}, types = { Role.class })
public class AttributeController {
@RequestMapping("/sessionAttributes")
public ModelAndView sessionAttrs(Long id) {
ModelAndView mv = new ModelAndView();
Role role = roleService.getRole(id);
//根据类型,session将会保存角色信息
mv.addObject("role", role);
//根据名称,session将会保存id
mv.addObject("id", id);
//视图名称,定义跳转到一个JSP文件上
mv.setViewName("sessionAttribute");
return mv;
}
}
如上述代码:
AttributeController配置了两个session属性。分别是:
- 根据名称的:
id
- 根据类型的:
Role.class
JSP页面接收session代码:
<%
Role role = (Role) session.getAttribute("role");//获取Role类型参数
out.println("id = " + role.getId());
Long id = (Long) session.getAttribute("id");//获取名称为id的参数
out.println("id = " + id + "<p/>");
session.setAttribute("id",2L);//设置值到属性id中
//执行跳转
response.sendRedirect("./attribute/sessionAttribute.do");
%>
Controller类中接收session属性的方法
@RequestMapping("/sessionAttribute")
public ModelAndView sessionAttr(@SessionAttribute("id") Long id) {
//...
}
####3.3 @RequestHeader 和 @CookieValue
用户可以禁用Cookie,所以使用时候需要注意
@RequestMapping("/getHeaderAndCookie")
public String testHeaderAndCookie(
@RequestHeader(value="User-Agent", required = false, defaultValue = "attribute")
String userAgent,
@CookieValue(value = "JSESSIONID", required = true, defaultValue = "MyJsessionId")
String jsessionId) {
System.out.println("User-Agent:" + userAgent);
System.out.println("JSESSIONID:" + jsessionId);
return "index";
}
###4.重定向
在Spring MVC中当返回的字符串带有redirect的时候,它会认为这是一个重定向。
eg:
@RequestMapping("/test")
public String testRedirect(Model model){
model.addAttribute("name","test");//传递参数到index页面
return "redirect:./index";
}
或者:
@RequestMapping("/test")
public ModelAndView testRedirect(RedirectAttributes ra)
ModelAndView mv = new ModelAndView();
mv.addObject("name","test");//传递参数到index页面
ra.addFlashAttribute("obj",obj); //传递POJO对象参数到index页面
mv.setViewName("redirect:./index");
return mv;
}
addFlashAttribute(…)的功能主要是将POJO对象保存到session中,再执行重定向,在取出POJO数据后,清除session中保存的数据,最后显示页面。
###5.总结
- Spring MVC 中,页面与Controller之间的参数传递相对比较简单。
- Controller接收简单参数只需要在
方法中定义参数的名称
与请求参数的名称
一致就可以获取值。 - Controller中的数据传递到页面也只需要在方法中使用Model、ModelMap或者ModelAndView就可以了。
- 复杂的数据类型可以通过
@RequestBody
进行接收,传递可以通过序列化为JSON字符串
- Controller接收简单参数只需要在
- 把数据直接保存到HTTP的request对象、session对象、Cookie和请求头(Header)中,需要注意的是request和session需要遵循它们的有效期。 而Cookie需要考虑到用户是否禁止了Cookie功能。
- 重定向传递数据时,需要POJO类型的传递需要使用
RedirectAttributes
进行。
END
–Nowy
–2018.12.21