Spring MVC 传递参数 (熟悉)
1、使用Model对象(常用)
(1)使用model对象往前台传递数据 attribute
(2)在jsp中接收从后台传递过来的参数
2、使用HttpServletRequest对象
(1)使用HttpServletRequest对象往前台传递数据
2)jsp中接收,同上!!!
3、使用Map对象
把Model改成Map即可。
Spring MVC 重定向和转发(熟悉)
请求转发(Forward)
请求转发是一种在服务器内部的资源跳转方式,简单来说,当客户浏览器发送http请求到web服务器中,web服务器接受请求后调用内部servlet方法完成请求处理和转发资源给同一个web容器下的另一资源做处理,最后将目标资源response给客户
工作原理及特点
比如图中web容器(Tomcat)有两个资源(A和B),若浏览器请求资源A的时候,资源A处理了一部分,然后跳转到资源B,让资源B接着处理,资源B处理完成后做出响应到客户端。资源A跳转到资源B的这个过程就叫转发。
实现代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求转发器对象,调用forward()方法,请求转发 RequestDispatcher requestDispatcher = request.getRequestDispatcher("跳转资源的路径").forward(requset,response); }
RequestDispatcher requestDispatcher = request.getRequestDispatcher("跳转资源的路径").forward(requset,response);
特点
1. 请求转发资源间共享数据,图中资源A处理了一部分数据后把其他数据转交给资源B处理,所以在这过程中资源之间数据是共享的。
2. 浏览器地址栏路径不发生变化,只能转发到当前服务器的内部资源,浏览器只做了一次请求。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
Response完成重定向(Redirect)
重定向(Redirect)是一种资源跳转的方式,一般用来解决登录进入主页、跨域访问、系统维护等等都使用重定向技术,比如当系统进行维护时,用户若发起请求,系统将会告诉浏览器重定向访问指定的url。
简单来说,当浏览器发起请求给资源A时,资源A发现浏览器发起的请求自身处理不了,但是知道资源B可以处理,这时候资源A就会告诉浏览器说这次请求处理不了,请找资源B处理并且告诉资源B的访问路径,浏览器会自动去请求资源B。
工作原理及特点
客户浏览器发送http请求后,web服务器中资源A接受请求后无法处理,资源A将会发送302状态码响应及对应新的location(资源B)给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址。
实现代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //旧方法 //response.setStatus(302); //response.setHeader("location","资源B的路径"); //其中资源B的路径需要添加虚拟目录 response.sendRedirect("资源B的路径"); }
response.sendRedirect("资源B的路径");
特点
1. 浏览器地址栏路径发生变化
2. 可以重定向到任意位置的资源(服务器内部、外部均可)
3. 浏览器发起两次请求,不能在多个资源使用request共享资源
重定向和请求转发的区别
转发和重定向是两种不同的请求处理方式,转发是服务器行为,重定向是客户端行为。
请求转发过程中,数据在同一个web服务器中得到共享,因为浏览器只做了一次访问请求,浏览器地址栏路径不发生变化,为同一个request域;而重定向中,浏览器做了两次请求,浏览器地址栏路径发生变化,请求并不是同一个request域。
Spring MVC怎么样设定重定向和转发的?
一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理。如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和redirect: 当成指示符,其后的字符串作为 URL 来处理。
(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
@RequestMapping("/springMvc") @Controller public class handler { //测试转发 @RequestMapping("/testRedirect") public String testRedirect(){ System.out.println("testRedirect"); return "forward:/index.jsp"; } }
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
@RequestMapping("/springMvc") @Controller public class handler { //测试重定向 @RequestMapping("/testRedirect") public String testRedirect(){ System.out.println("testRedirect"); return "redirect:/index.jsp"; } }
*@ModelAttribute 注解 (熟悉)
好文参考:https://www.cnblogs.com/bigdatalearn/p/6c1cabd5c64bf43d8dcc303e07d1fe8b.html
好文参考:https://blog.csdn.net/weixin_45007916/article/details/107880908
Spring MVC 类型转换器(了解)
为什么仅仅通过一些注解,控制器方法就能够得到各种类型的参数,其实这都要归功于 Spring MVC 的类型转换机制。
Spring 提供了一种 Converter(类型转换器)的类型转换工具。在 Spring MVC 中,它的作用是在控制器方法对请求进行处理前,先获取到请求发送过来的参数,并将其转换为控制器方法指定的数据类型,然后再将转换后的参数值传递给控制器方法的形参,这样后台的控制器方法就可以正确地获取请求中携带的参数了。
内置的类型转换器
Spring MVC 框架默认提供了许多内置的类型转换器,主要包括以下几种类型。
1)标量转换器
2)集合、数组相关转换器
Spring MVC 对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换。因此,通常情况下 Spring MVC 提供的这些类型转换器可以满足开发人员大多数的类型转换需求的。
注意:在使用内置类型转换器时,请求参数输入值需要与接收参数类型相兼容,否则会报 400 错误。
Spring MVC 数据格式化(了解)
在实际的项目开发中,经常会涉及到一些需要进行格式化的数据,例如金额、日期等。以金额为例,当金额为 10 万元时,在比较正式的场合往往要写成 ¥100000;而日期也可以被写作多种格式,例如 yyyy-MM-dd、yyyy-MM-dd hh:ss:mm 等。这些数据都要经过一定的格式化处理才能够正常使用。
Formatter 接口
Spring 提供了一个 Formatter<T> 接口, T 表示目标数据类型,它被称为格式化转换器。
Formatter 的作用与 Converter(类型转换器)相似,都是可以将一种数据类型转换成另一种数据类型。但不同的是,Formatter 的源类型必须是 String 类型,而 Converter 的源类型可以是任意数据类型。
内置格式化转换器
Spring MVC 默认提供了多个内置的格式化器,通过它们,我们可以轻松地实现对日期(Date)类型和数值(Number)类型数据的格式化工作,具体如下。
虽然 Formatter 与 Converter 存在一定的差异,但格式化转换本质上还是属于“类型转换”的范畴,因此在 Spring MVC 中 Formatter(格式化转换器)实际上是委托给 Converter 机制实现的。
Spring 的格式化模块中定义了一个 FormattingConversionService 类,它是 ConversionService 接口(类型转换器的服务接口)的实现类。它与其他的类型转换器实现类不同,它不仅具有类型转换功能,还具有格式化转换功能。
Spring MVC 还专门为 FormattingConversionService 提供了一个名为 FormattingConversionServiceFactroyBean 的工厂类,它主要作用就是在 Spring 上下文中构造 FormattingConversionService 的实例。
除此之外,FormattingConversionServiceFactroyBean 还为以下 2 个格式化注解提供了支持,使得我们可以更加方便地使用 Spring MVC 内置的格式化器,对数据进行格式化转换。
格式化注解 |
说明 |
@DateTimeFormat 注解 |
使用该注解,能够实现对日期类型数据的格式化 |
@NumberFormat 注解 |
使用该注解,能够实现对数值类型数据的格式化 |
我们知道,只要 Spring MVC 的配置文件中配置一个 <mvc:annotation-driven> 标签,Spring MVC 在启动时就会自动初始化一个 FormattingConversionServiceFactoryBean 类型的实例:ConversionService。
也就是说,我们只要在 Spring MVC 配置文件中配置了 <mvc:annotation-driven> 标签,就可以直接在 Spring MVC 项目中使用 @NumberFormat 注解和 @DateTimeFormat 注解,对 Number 类型和 Date 类型数据进行格式化转换。
日期格式化
@DateTimeFormat 注解可对 java.util.Date、java.util.Calendar、java.long.Long 等时间类型的数据进行标注,以实现对日期类型的数据进行格式化处理。
@DateTimeFormat 注解主要包含以下 3 个属性。
数值格式化
@NumberFormat 注解可以用来格式化任何数字基本类型(如 int、long 等)或 java.lang.Number 类型的实例(如 BigDecimal、Integer 等)。
@NumberFormat 注解拥有两个互斥的属性,如下表。
代码演示:http://c.biancheng.net/spring_mvc/9678.html
Spring MVC 表单标签库(了解)
我们在进行 Spring MVC 项目开发时,一般会使用 EL 表达式和 JSTL 标签来完成页面视图的开发。其实 Spring 也有自己的一套表单标签库,通过 Spring 表单标签,可以很容易地将模型数据中的命令对象绑定到 HTML 表单元素
在使用 SpringMVC 的时候我们可以使用 Spring 封装的一系列表单标签,这些标签都可以访问到 ModelMap 中的内容。我们需要先在 JSP 中声明使用的标签,具体做法是在 JSP 文件的顶部加入以下指令:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
表单标签<form:form />
使用 Spring MVC 的 form 标签主要有两个作用,第一是它会自动的绑定来自 Model 中的一个属性值到当前form对应的实体对象,默认是 command 属性,这样我们就可以在 form 表单体里面方便的使用该对象的属性了。第二是它支持我们在提交表单的时候使用除 GET 和 POST 之外的其他方法进行提交,包括 DELETE 和 PUT 等。
<form:form action="formTag/form.do" method="post"> <table> <tr> <td>Name:</td><td><form:input path="name"/></td> </tr> <tr> <td>Age:</td><td><form:input path="age"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form:form>
文本框<form:input />
使用<form:input path="name" />标签来渲染一个 HTML 文本框,等同于:
<input id="name" name="name" type="input" value=""/>
密码框<form:password />
使用 <form:password path="password" /> 标签来渲染一个 HTML 密码框,等同于:
<input id="password" name="password" type="password" value=""/>
文本域<form:textarea />
使用<form:textarea path="address" rows="5" cols="30" />标签来渲染一个 HTML 文本域,等同于:
<textarea id="address" name="address" rows="5" cols="30">
复选框<form:checkbox />
使用 <form:checkbox path="receivePaper" /> 标签来渲染一个 HTML 复选框,等同于:
<input id="receivePaper1" name="receivePaper" type="checkbox" value="true"/> <input type="hidden" name="_receivePaper" value="on"/>
单选按钮<form:radiobutton />
使用 <form:radiobutton /> 标签来渲染一个 HTML 单选按钮,等同于:
<form:radiobutton path="gender" value="M" label="男" /> <form:radiobutton path="gender" value="F" label="女" />
单选按钮(多选)<form:radiobuttons />
使用 <form:radiobuttons path="favoriteNumber" items="${numbersList}" /> 标签来渲染一个 HTML 多项单选按钮,等同于:
<span> <input id="favoriteNumber1" name="favoriteNumber" type="radio" value="1"/> <label for="favoriteNumber1">1</label> </span> <span> <input id="favoriteNumber2" name="favoriteNumber" type="radio" value="2"/> <label for="favoriteNumber2">2</label> </span> <span> <input id="favoriteNumber3" name="favoriteNumber" type="radio" value="3"/> <label for="favoriteNumber3">3</label> </span> <span> <input id="favoriteNumber4" name="favoriteNumber" type="radio" value="4"/> <label for="favoriteNumber4">4</label> </span>
下拉列表
使用 <form:select />, <form:option />,<form:options /> 标签来渲染一个 HTML 下拉列表,等同于:
<form:select path="country"> <form:option value="NONE" label="Select"/> <form:options items="${countryList}" /> </form:select>
<select id="country" name="country"> <option value="NONE">请选择...</option> <option value="US">United States</option> <option value="CH">China</option> <option value="MY">Malaysia</option> <option value="SG">Singapore</option> </select>
下拉列表(多选)
使用 <form:select /> 标签及其属性 multiple=true 来渲染一个 HTML 多选下拉列表,等同于:
<form:select path="skills" items="${skillsList}" multiple="true" />
<select id="skills" name="skills" multiple="multiple"> <option value="Struts">Struts</option> <option value="Hibernate">Hibernate</option> <option value="Apache Wicket">Apache Hadoop</option> <option value="Spring">Spring</option> </select> <input type="hidden" name="_skills" value="1"/>
隐藏字段域<form:hidden />
使用 <form:hidden path="id" value="1000"/> 标签来渲染一个 HTML 隐藏字段域,等同于:
<input id="id" name="id" type="hidden" value="1000"/>
通过观察可以发现path其实就是原来的name,然后这个用的少,其实就是对原来的input写法封装,然后简化,方便使用