SpringMVC参数绑定( 传参 )
转发和重定向
SpringMVC使用comtroller类中, return的时候, 就会调用视图解析器进行拼接前缀和后缀, 然后进行转发. 所以实际上return就是转发
-
forward:
(地址栏不变)跳过视图解析器, 不拼接进行转发, 例如:
return "forward:/home"
-
redirect:
(地址栏发生变化)进行重定向, 例如:
return "redirect:/home";
当然如果你不嫌麻烦, 可以获取request对象使用servlet的方式进行转发和重定向
参数传值
通过属性传值
特点:
- 变量名必须和表单组件中的name值相同
- 可以实现类型转化
- 在转换类型的时候可能出现异常 (浏览器400状态码)
- 如果一个属性有多个值, 使用对应类型的数组即可
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错误
http//localhost:8080/mvc/testParam02?name=张飞&age=28&addr=河北
@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";
}
通过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类中
- bean中的属性名和类型要和参数一致, 顺序可以不同
- 如果前端提交数据较多,建议使用此种方式
- 封装到bean使用的是bean中的set方法, 例如url中参数名是name, 那么就调用bean中的setName()方法
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";
}
request和session对象
获得request和session的对象
@RequestMapping("/testParam05")
public String testParam05(HttpServletRequest request,HttpSession session){
request.setAttribute("name", "admin");
session.setAttribute("age", 18);
return "home";
}
使用Model传值(重点)
特点:
- 可以调用多次setAttribute传入键值对
- 常用来把数据发送到JSP页面
是SpringMVC常用的方式, 把数据进项转发或发送到JSP页面,
JSP使用EL或JSTL表达式即可获取到数据
@RequestMapping("/testParam06")
public ModelAndView testParam06(Model model){
model.setAttribute("msg", "用户名或密码错误!");
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";
}
日期类型传值注意
@RequestMapping("/testParam04")
public String testParam04(Date date) {
System.out.println(date);
return "test";
}
例如我们有两个如期的请求:
/testParam04?date=2020/06/23 1:51:39
(正常接收)
/testParam04?date=2020-06-23 1:51:39
(浏览器400状态码)
一种是以斜杠分割, 一种是以横杠分割, springMVC默认是以斜杠/
分割的, 所以使用横杠会抛出参数类型不匹配异常
解决方案
-
解决方法1: 如果是springmvc接收日期参数, 以后再向服务器提交日期参数时, 日期使用斜杠分割
-
解决方法2: 也可以将springmvc默认接收日期参数的格式改为以横杠
-
分割, 需要注意的是, 这种方法改完后, springMVC只能识别横杠分割的日期, 不能识别斜杠分割的日期/** * springMVC日期格式转换器 */ // org.springframework.web.bind.annotation.InitBinder @InitBinder public void InitBinder (ServletRequestDataBinder binder){ binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true) ); }
POST提交乱码问题
当使用POST提交时中文会出现乱码
GET提交再tomcat8.0及后续版本乱码问题已解决
POST乱码问题需要手动解决
解决方案: 使用过滤器
编码过滤器
web.xml中进行配置
<!-- 配置SpringMVC的乱码过滤器: 可以处理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>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样就完美解决了POST提交乱码的问题
扩展:通用访问JSP
例如我们要访问某一个WEB-INF下的jsp文件时, 只能通过controller转发才能访问, 如toIndex()
, toLogin()
方法等, 当JSP页面比较多的时候, 代码写起来就比较多, 所以springMVC提供了WEB-INF/下jsp文件的通用访问方式:
@RequestMapping("/{pageName}")
public String toPage(@PathVariable String pageName) {
return pageName;
}
其中pageName变量名不是固定的, 只要上面三个地方名字一样即可
这样, 如果我们WEB-INF下有jsp:index.jsp
, login.jsp
, list.jsp
等多个jsp时, 有这一个controller就可以实现所有jsp的访问, 如:localhost:8080/应用名/index
, localhost:8080/应用名/login
, localhost:8080/应用名/list
就可以访问对应的jsp, 就是根据浏览器端输入的url, 自动寻找对应的JSP
执行过程:
浏览器输入: localhost:8080/应用名/index, 当浏览器访问controller方法上的路径为"/index", 那么/{}中pageName的值为"index", 再将/{}中pageName的值传递给toPage方法上的形参pageName, 那么将形参pageName直接返回, 因此, 若访问路径为/index, 最后则跳转到index.jsp, 若访问路径为_top, 最后跳转到_top.jsp