38-三大框架-SpringMVC-参数绑定
SpringMVC参数绑定( 传参 )
当项目中引入springmvc框架后,所有的请求流转将由springmvc进行控制,当客户端发送的请求中包含数据(也就是请求参数)时,那么该如何在controller层获取这些参数呢?
springmvc会自动的将请求中包含的参数和方法的参数进行匹配,也就是说只要保证,请求中的参数名称和方法中的参数名称相对应(另,参数的格式也要正确),在方法中就可以使用这些参数—即请求中的参数。
转发和重定向
SpringMVC使用comtroller类中, return的时候, 就会调用视图解析器进行拼接前缀和后缀, 然后进行转发. 所以实际上return就是转发
在springmVc中,从controller跳转到jsp,默认就是请求转发!
理由:
得通过转发才能访问WEB-INF目录下的资源
从controller跳转到jsp,地址栏地址没变化,说明是转发
-
forward:
(地址栏不变)跳过视图解析器, 不进行拼接进行转发, 例如:
return "forward:/home"
相当于:
request.getRequestDispatcher("url").forward(request,response);
转发是一次请求,一次响应;
转发后地址栏地址没有发生变化(还是访问原来的地址);
转发前后的request和response对象也是同一个。
-
redirect:`(地址栏发生变化)
进行重定向, 例如:
return "redirect:/home";
相当于:
response.sendRedirect(url);
重定向是两次请求,两次响应;
重定向后地址栏地址发生了变化(变为转发后的地址);
并且在重定向前后,request和response对象不是同一个。
当然如果你不嫌麻烦, 可以获取request对象使用servlet的方式进行转发和重定向
通过属性传值
特点:
- 变量名必须和表单组件中的name值相同
- 可以实现类型转化
- 在转换类型的时候可能出现异常
http//localhost:8080/mvc/testParam01?name=张飞&age=28&addr=河北
@RequestMapping("/testParam01")
public String testParam01(String name, Integer age, String addr) {
System.out.println(name);
System.out.println(age);
System.out.println(addr);
return "home";
}
属性传值注解
@RequestParam("param")
特点:
- 表单组件的name属性值和变量名不相同时需要使用
@RequestParam("param")
辅助完成赋值 - param表示表单组件的name属性值
- 400错误: 如果
@RequestParam("param")
中的param在页面不存在,会产生400错误
@RequestMapping("testParam02")
public String testParam03(
@RequestParam("name") String username,
@RequestParam("age") Integer age,
@RequestParam("addr") String address) {
System.out.println(username);
System.out.println(age);
System.out.println(address);
return "home";
}
http//localhost:8080/mvc/testParam02?name=张飞&age=28&addr=河北
通过request传值
特点:
- 直接, 但是不能自动类型转换
http//localhost:8080/mvc/testParam03?name=张飞&age=28&addr=河北
@RequestMapping("testParam03")
public String testParam02(HttpServletRequest request) {
String name = request.getParameter("name");
Integer age = Integer.parseInt(request.getParameter("age"));
String addr = request.getParameter("addr");
System.out.println(name);
System.out.println(age);
System.out.println(addr);
return "home";
}
bean对象传值
特点:
- 表表单组件的name属性值封装到bean类中
- 方法的番薯传递封装类类型的对象即可
- 如果前端提交数据较多,建议使用此种方式
User实体类
public class User {
private String name;
private Integer age;
private String addr;
// getter, setter, toString, 有参无参构造
}
http//localhost:8080/mvc/testParam04?name=张飞&age=28&addr=河北
@RequestMapping("/testParam04")
public String testParam04(User user){
System.out.println(user);
return "home";
}
日期类型参数绑定
@Controller /* 这个注解表示当前类是属于控制层 */
public class HelloController {
/* 3、测试springmvc的日期类型参数绑定
* ../testParam3?date=2020-4-10 16:40:39 报400错误,表示参数类型不匹配
* ../testParam3?date=2020/4/10 16:40:39
* 由于springmVc底层在接收日期类型的参数时,默认是以/ (斜杠)作为分隔符
因此,如果提交斜杠(/ )分隔的日期参数, springmVc可以接收日期参数的值
如果提交以横杠(- )分隔的日期参数, springmvc识别不了,就会报400错误!
解决方法1:如果是springmvc接收参数,以后再向服务器提交日期参数时,日期使用斜杠分隔
解决方法2:也可以将springmvc默认接收日期参数的格式改为以横杠(- )分隔日期
这种方法改完后,springmvc只能识别横杠分隔的日期,不能识别斜杠分隔的日期!
*/
@RequestMapping("/testParam3")
public String testParam3(Date date) {
System.out.println( "date="+date );
return "home";
}
}
解决方案:添加一个日期转换器
在springmvc中,提供了@InitBinder注解,用于指定自定义的日期转换格式,因此,我们只需要在Controller类中添加下面的代码即可,在接受日期类型的参数时,会自动按照自定义的日期格式进行转换。
/* 自定义日期格式转换器
* 将springmvc默认以斜杠(/)分隔日期改为以横杠分隔(-)
*/
@InitBinder
public void InitBinder (ServletRequestDataBinder binder){
binder.registerCustomEditor(java.util.Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)
);
}
request和session对象
获得request和session的对象
@RequestMapping("/testParam05")
public String testParam05(HttpServletRequest request,HttpSession session){
request.setAttribute("name", "admin");
session.setAttribute("age", 18);
return "home";
}
使用ModelAndView传值
也是SpringMVC底层的传值方式
特点:
- ModelAndView构造方法中可以设置一个Map对象
- Map对象经过框架处理后. 会把key-value设置到request对象中
- 返回的是一个对象
@RequestMapping("/testParam06")
public ModelAndView testParam06(){
Map<String, Object> map = new HashMap<String, Object>();
map.put("message", "控制器向页面传值");
ModelAndView mv = new ModelAndView("home",map);
return mv;
}
ModelMap传值
特点:
- ModelMap是框架提供的map集合
- ModelMap同样被框架设置到request对象中
@RequestMapping("/testParam07")
public String testParam07(ModelMap map){
//设置属性值
map.addAttribute("error", "登录失败!");
return "home";
}
Model的使用
当请求发起访问Controller中的方法时,可以通过参数声明,在方法内使用Model。返回的是一个地址
@RequestMapping("/doorList")
public String doorList(Model model){}
Model对象实际上是一个Map集合,例如:往model中添加一个属性
model.addAttribute(String name, Object value);
其中,addAttribute方法会将属性保存到request域中,再通过转发将属性数据带到相应的JSP中,通过${}取出并显示。
示例,往Model中添加属性:
@RequestMapping("/testModel")
public String testModel(Model model){
/* 往Model添加属性 */
model.addAttribute("name", "马云");
model.addAttribute("age", 20);
return "home";
}
在home.jsp中取出属性并显示:
<body>
<h1>hello springmvc~~~</h1>
${ name } <br/>
${ age }
</body>
乱码处理
在前面的Servlet学习中,我们学习了GET和POST请求参数乱码如何解决。
springmvc也提供了解决请求参数乱码的方案,就是在web.xml中加入如下代码(配置请求参数乱码过滤器),可以解决POST提交的中文参数乱码问题!
<!-- 配置过滤器,解决POST提交的中文参数乱码问题 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Servlet中,两种请求方式乱码解决方案回顾:
(1)如果请求方式为POST提交,必然会出现乱码,解决方式是在任何获取参数的代码之前,添加如下代码:
request.setCharacterEncoding("utf-8");
(2)如果请求方式为GET提交,tomcat8及之后的版本已经解决了GET提交的中文参数乱码问题,因此不需要处理;在 tomcat7 及之前的版本中,获取GET提交的中文参数仍有乱码,解决方法是:只需要在[tomcat]/conf/server.xml中添加如下配置也可以解决乱码问题。
<Connector port=" 8080" protocol="HTTP/1.1"
connecti onTi meout= ="2 0000"
redi rectPort= =18443 "
URIEncoding="UTF-8" / >