问题:
目前我们浏览器发起请求给服务器的时候,一般我们常用的请求方式有两个,get 和post方式。不管get还是post方式,请求数据的格式都是键值对格式,get方式请求数据是在请求地址上以问号隔开的形式,拼接在请求地址后,post请求呢,是有专门的请求实体的,例如:
get方式请求:
localhost:8080/project/aa?uname=zhangsan&age=18
post方式请求:
地址:localhost:8080/project/aa
请求数据:
- uname=zhangsan
- age=18
要求我们后台获取请求数据的代码,必须按照指定的键名来获取请求数据。键名就是请求数据的键名。这样造成,一旦请求数据的键名发生变更,造成后台的逻辑代码也需要进行变更。前台的请求数据的键名和后台的逻辑代码之间的耦合性过高,造成前台和后台的开发过程中相互依赖性过高。怎么办?
解决:
让前台和后台代码之间进行解耦。也就说不再让请求数据的键名造成前后台代码之间耦合性高。前台请求数据的键名发生变更,不影响后台逻辑代码的正常执行
实现:
请求数据不再以键值对的形式发送给后台使用。直接发送数据本身给后台即可。既然请求数据不再使用键值对,请求数据必须按照指定的格式来进行发送。使用restful格式。
restful格式:
- 传统的get方式请求格式:
localhost:8080/project/aa?uname=zhangsan&age18
- restful请求格式:
localhost:8080/project/aa/zhangsan/18
注意:
restful格式要求请求数据作为请求地址的一部分发送给后台使用。
2. restful格式请求后台获取请求数据
问题:
按照以前键值对格式的请求数据,我们在后台直接使用req.getParameter方法根据键名获取请求数据即可。但是在restful请求格式中,请求数据是作为请求地址的一部分来进行发送的,那么在后台我们如何获取restful格式的请求数据呢?
解决:
从服务器的角度,服务器在接收到请求后,会根据请求地址调用对应的Servlet来处理请求。
①传统请求格式的流程:
localhost:8080/project/aa?uname=zhangsan&age=18
服务器在接收到此请求后,会调用别名为aa的单元方法来处理请求
②restful格式请求的流程:
localhost:8080/project/aa/zhangsan/18服务器在接收到此请求后,调DispatcherServlet,DispatcherServlet底层根据请求的URL地址信息,调用对应的单元方法来处理请求。而DispatcherServlet认为请求地址中项目名后的信息为要调用的单元方法的别名,也就是说DispatcherServlet会调用一个别名为”aa/zhangsan/18”的单元方法来处理请求。我们通过比较传统方式和restful方式,发现DispathcerServlet不会识别请求地址中的数据的,它会认为该数据为要请求的单元方法的地址的一部分。DispatcherServlet底层只识别正常的键值对的请求数据的。如果将请求数据放到请求地址中携带,不同的用户发起的请求地址就会不同,因为数据是变化的。总不能每个请求都声明对应的单元方法来处理吧,并且我们也无法提前预知请求地址信息,也就是无法提前声明对应的单元方法。是不是考虑在单元方法的@RequestMapping注解中使用模糊匹配的方式来匹配请求地址呢?答案是可以的,也就说声明一个单元方法,可以处理N个请求。
实现:
SpringMVC单元方法中处理restful格式的请求
3. SpringMVC使用占位{字符}声明公共单元方法
/**
4. 单元方法中获取restful请求地址中的请求数据
示例代码:
/**
五、SpringMVC的编码过滤器配置
1. 目前请求编码格式设置
使用代码解决:
get请求:
- request.setCharacterEncoding(”utf-8“);
- 在tomcat的server.xml文件中进行编码格式的配置
post请求:
request.setCharacterEncoding(”utf-8“);
使用过滤器:
因为每次都在Servlet中设置编码格式,过于麻烦,所以在过滤器中进行统一的编码格式设置。
2.SpringMVC的编码过滤器配置
在项目的web.xml文件中配置SpringMVC官方提供的编码过滤器即可。
<!--配置编码过滤器-->
六、 SpringMVC的静态资源放行
1. SpringMVC的Dispatcher的拦截范围问题
问题:
按照SpringMVC的使用流程,需要在web.xml文件中配置DispatcherServlet的拦截范围,而我们配置的拦截范围为”/”,表示拦截除jsp请求以外的所有请求。这样造成,请求是js,css,图片等静态资源的请求,也会被DispatcherServlet拦截,调用对应的单元方法来处理请求。但是,我们呢是一个静态资源的请求,不应该按照普通单元方法请求的流程来处理,而是将对应的静态资源响应给浏览器使用。怎么办?
前台代码示例:
后台代码示例:
运行结果:
解决:
- 将DispatcherServlet的底层逻辑进行变更,静态资源的请求就不要作为单元方法请求处理,而是查找对应的资源响应给浏览器。
- 在SpringMVC的配置文件中配置静态资源的放行,告诉DispatcherServlet哪些资源静态资源需要放行,将静态资源响应给了浏览器。
2. SpringMVC的静态资源放行配置
配置示例
<?xml version="1.0" encoding="UTF-8"?>
注意
浏览器发起静态资源请求,DispatcherServlet会先按照正常的单元方法逻辑进行处理,如果找不到对应的单元方法,则根据SpringMVC的配置文件的静态资源,判定此次请求是否为静态资源请求,如果是则将资源响应给浏览器,如果不是,则响应404.也就说,不要设置某个单元方法的路径和静态资源的路径是一致,这样就算配置了静态资源放行,也会导致静态资源无法访问的问题。