java学习day38-三大框架-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" / >