一、web.xml 中的注意事项
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Tips:
在配置 springmvc
的 servlet-mapping
时,对 URL
的拦截方式有三种分别为:
-
*.do
*.action
等特定后缀配置这种方式的
url-pattern
时,springmvc
会只拦截特定后缀的URL
使用简单方便,易于理解。 -
/
配置这种方式的
url-pattern
时,springmvc
会对除了以.jsp
结尾的请求之外的所有URL
请求,都进行拦截。 -
/*
配置这种方式的
url-pattern
时,springmvc
会对所有的URL
请求进行拦截,包括以.jsp
结尾的请求。
二、Spring MVC 请求处理流程
流程说明:
- 用户发送请求至前端控制器
DispatcherServlet
- 前端控制器通过处理器映射器
HandlerMapping
查找可以处理本次请求的处理器 - 返回可以处理本次请求的处理器执行链,之所以是执行链是因为在处理器执行时可能会存在拦截器
- 前端控制器
DispatcherServlet
调⽤HandlerAdapter
处理器适配器去执行Handler
- 执行处理器
Handler
Handler
执⾏完成后将结果数据和页面跳转信息封装进ModelAndView
对象,并将其返回至处理器适配器HandlerAdapter
- 处理器适配将
Handler
执行结果ModelAndView
返回至前端控制器 - 前端控制器调用视图解析器
ViewResolver
去进⾏视图解析,根据逻辑视图名来解析出真正的视图 - 视图解析器向前端控制器返回跳转的视图
- 前端控制器对拿到的视图进行渲染,就是
ModelAndView
中存储的数据放入视图中,实现页面数据的绑定 - 前端控制器向⽤户响应结果
三、静态资源被拦截问题的处理
由于我们在 web.xml
文件中配置的 springmvc
的 url-pattern
为: /
,所以案例中所有的静态资源都会被 Spring MVC
所拦截。对于这个问题,有两个解决方案。
-
在
Spring
配置文件中添加<mvc:default-servlet-handler/>
标签处理。原理:添加该标签配置之后,会在
SpringMVC
上下文中定义一个DefaultServletHttpRequestHandler
对象,这对象对进入DispatcherServlet
的URL
请求进行类型筛查,如果发现是一个静态资源请求,那么会把请求转至web
应用服务器(tomcat
)中默认的DefaultServlet
来处理,如果不是静态资源请求,则继续由SpringMVC
框架处理。局限:这种配置方式只能将 webapp 目录下的静态资源返回给浏览器。如果静态资源被放置在了其他位置(如:
WEB-INF
)则失效。 -
在
Spring
配置文件中添加<mvc:resources>
标签处理。(即:交由Spring MVC
自己处理)applicationContext.xml(部分代码)
<!-- 测试地址:http://localhost:8081/frontEnd/hi.html --> <mvc:resources location="classpath:/html/" mapping="/frontEnd/*.html"/> <!-- 测试地址:http://localhost:8081/A.jpeg --> <mvc:resources location="WEB-INF/image/" mapping="*.jpeg"/>
说明:这种配置方式是将静态资源的处理方式交给了
Spring MVC
自己处理。标签中mapping
属性,约定了静态资源的URL
请求规则。location
属性指定了静态资源存放的位置。注意:
location
属性的所指向的文件夹,必须以/
结尾。
四、请求参数绑定
Tips:
-
当前请求参数名称不同于后台接收参数名时,可通过
@RequestParam
指定请求参数名与后台形参的关系。 -
如果请求参数的值为基本数据类型,后台在接收该参数时应使用包装类,以避免因请求值为
null
时导致的系统异常。 -
如果请求参数类型为
Boolean
类型时,应注意该参数的值只能为:false
、true
、0
、1
这四种情况。 -
为
POJO
对象赋值时,请求参数名必须与POJO
属性名相同。如果发生POJO
的嵌套,则通过.
对被嵌套对象进行赋值。需要注意的是:.
的前面为被嵌套对象在接收对象中的属性名,后面为想要赋值的被嵌套对象的属性名。 -
在进行日期类型传输时,由于前端请求的参数值是无法直接直接转换成
Date
类型对后台形参赋值的,所以就需要我们自定义时间类型转换器,对其进行处理。首先,需要编写类型转换器处理类。
DateConvert
import org.springframework.core.convert.converter.Converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Supreme_Sir * @version 1.0 * @className DateConvert * @description 自定义时间类型转换器 * @date 2020/10/28 21:54 **/ public class DateConvert implements Converter<String, Date> { @Override public Date convert(String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { return simpleDateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return null; } }
然后,将自定义时间转换工具类注册进
Spring IoC
容器中,并将其添加至mvc:annotation-driven
标签中。applicationContext.xml
<!--自定义时间类型转换器--> <bean id="dateConversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.idol.util.DateConvert"></bean> </set> </property> </bean> <!--自动注册处理器适配器、处理器适配器--> <mvc:annotation-driven conversion-service="dateConversionServiceBean"/>
五、RESTful 风格请求
一句话定义:REST
是一种 URL
请求的风格,不是一种协议,所以没有强制性。
在 REST
中认为,所有的互联网内容都是一种资源,所以每一个资源都应该对应唯一的 URL
,而对资源的操作方式,则根据请求方式的不同而不同。
请求方式 | 操作类型 |
---|---|
GET | 查询资源 |
POST | 添加资源 |
PUT | 更新资源 |
DELETE | 删除资源 |
(1) 参数传递方式
RESTful
风格请求同时支持 URL
和普通 POST
请求传参。
HTML
<form method="post" action="/rest/post/2">
<input type="text" name="name" value="李铁锤"/>
<input type="submit" value="RESTful 风格请求 POST 方法测试"/>
</form>
这个表单通过 POST
方式向后台传递了两个参数,一个是 action
属性中的 2
,一个是表单中的 李铁锤
。
Java
@RequestMapping(value = "post/{id}", method = RequestMethod.POST)
public String post(@PathVariable("id") Integer id, String name) {
System.out.println("REST 添加数据:" + id + "__" + name);
return "success";
}
后台通过 {id}
和 @PathVariable
注解的组合接收到了 id
的值,而 name
的值则通过 Spring MVC
框架进行常规方式的注入。
注意:由于前端传递至后台的数据中包含中文,为了防止乱码,需在 web.xml
文件中配置编码过滤器。
web.xml
<!--Spring MVC 针对 POST 请求提供的编码过滤器-->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Tips:
如果 GET
请求中存在中文且发生了乱码,则需要修改 tomcat
下 server.xml
的配置。
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>
(2) POST 表单模拟 PUT、DELETE 请求
由于使用表单进行数据提交时 action
属性的值只有两种:GET
、POST
,所以为了模拟出 PUT
、DELETE
请求,就必须通过 POST
请求表单加隐藏表单域 _method
的形式完成。
为了实现 POST
表单模拟 PUT
、DELETE
请求,需要在 web.xml
中配置过滤器。
web.xml
<!--配置 Spring 请求方式转换过滤器。该过滤器会检查请求中是否含有 _method 参数,如果有就按照指定的请求方式进行转换-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
index.jsp
<form method="post" action="/rest/put/3">
<input type="hidden" name="_method" value="put"/>
<input type="submit" value="RESTful 风格请求 PUT 方法测试"/>
</form>
<a href="/rest/put/3?_method=put">GET 模拟 RESTful 风格请求 PUT 方法测试(错误演示)</a><br/>
<form method="post" action="/rest/delete/4">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="RESTful 风格请求 DELETE 方法测试"/>
</form>
Tips:
模拟 PUT
、DELETE
只能通过 POST
请求模拟,不可通过 GET
方式模拟。
源码
------------------------ 努力让自己发光,对的人才会迎着光而来。 ------------------------