SpringMVC---彻底解决/和/*的问题!到底该用哪一个?
出处: https://blog.csdn.net/sinat_33921105/article/details/81951156
在web开发中我们经常会遇到/和/*的问题,有的时候稍不注意就容易忘了两者的区别,从而导致一些小错误,所以是时候彻底弄懂他们两个的区别了!
小白:让我先想想在实际的开发中哪些地方会遇到这个问题,嗯。。。哦,知道了。在SpringMVC的开发中用到这块,也就是那个DispatcherServlet,对,就是它
<!--前端控制器-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
这是在SpringMVC中非常重要的一个前端控制器,当有请求过来,会经由此servlet分配控制器,也就是说这个前端控制器会对我们的请求进行拦截,而如何拦截,以及拦截什么样的请求就在这个中配置
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
这里说的/和/*也就是在这个url-pattern中配置。
不过,我记得我一般就是像上面的代码一样,直接写成/* 了,让我突然去说/和/* 的区别,还真一时间有点懵呢!
庆哥:可以啊,看来你对SpringMVC掌握的不错啊,说到这两个问题,你立马就想到了SpringMVC中的前端控制器,确实,一般对于这个问题,我们最常使用的也就是在这个前端控制器了,因为使用SprinfMVC比较多,所以自然也就会遇到这个问题,不过,也许有大多人和你一样,在平常的开发中就知道这样使用,但是如果突然问他/和/*有啥区别,就会很容易大脑一片空白!
小白: 我记得这个url-pattern是讲的关于匹配规则的,就是具体的请求到底会匹配到哪一个servlet去处理就看这个url-pattern的配置,那咱们今天是要说匹配规则这块吗?
庆哥: 你说的很对,这个url-pattern,是关乎匹配规则的,但是今天并不是要讲匹配规则,而就是单纯的说一下/和/*的区别。
小白: 那我的记忆中这两个好像都是可以代表所有的意思吧,就是所有的请求都会被这个servlet处理!
庆哥: 这就是今天我们要讨论的问题了,其实两者是有区别的,只有一个才是真正意义上的所有!
庆哥透漏:其实上面谈话中涉及的一个知识点是有错误的,你发现了吗?继续看下去,你就知道了!
小白: 那么,到底哪一个才是代表真正意义上的拦截所有请求呢?
/ *是拦截所有请求吗?
庆哥: 接下来我们就实际操作一下看看,首先搭建SpringMVC环境,导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
</dependency>
搭建SpringMVC的开发环境,我们只需要导入以上jar包,由于maven会自动导入相关依赖jar包,所以当我们引入spring-webmvc的依赖时,maven就会帮我们导入其他相关的jar包。
然后再来写SpringMVC的核心也就是前端控制器
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
注意我们这里的url-pattern可是/*啊,配置好前端控制器之后就需要再来一个SpringMVC的配置文件,这个我们在配置前端控制器的时候加上了初始化参数指定SpringMVC的配置文件,也就是这些
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
然后我们在我们的类路径下新建一个springmvc.xml文件即可!
小白: 对了,庆哥,这里SpringMVC的配置文件是不是还有一种以《servlet-name》-servlet.xml的方式,放在WEB-INF目录下
庆哥: 对的,如果你不指定SpringMVC的配置文件,就会默认去加载WEB-INF目录下的《servlet-name》-servlet.xml,这是一种默认的方式
小白: 嗯嗯,知道了,那么接下来是不是就该编写控制了,我知道,控制器可以这样写
public class Hello implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv1 = new ModelAndView();
mv1.setViewName("/WEB-INF/views/hello.jsp");
return mv1;
}
}
庆哥: 对的,我们这里是为了说明/和/*的问题,所以就不使用注解以及视图解析器了,就是怎么简单怎么来,就按照你写的这个控制器来,接下来需要做的就是,将具体的请求和控制器关联起来,在SpringMVC的配置文件中写上这么一句
<bean id="/hello" class="com.ithuanqging.test.controller.Hello"/>
也就是说,当你输入http://localhost:8080/hello 的时候,这个请求会被DispatcherServlet拦截然后交由Hello这个控制器处理,然后我们访问一下试试
这里写图片描述
首先看到的就是这个
小白: 这是怎么回事啊,我记得一般都是会显示一个默认的页面,好像就是index.jsp吧,这里怎么404,是不是哪里出错了
庆哥: 不着急,我们输入http://localhost:8080/hello 看看
这里写图片描述
小白: 不对吧,怎么都是404啊,是不是程序出错了啊,可是我看程序也没有错啊
庆哥: 这里我们需要知道这么一点就是当你输入http://localhost:8080 的时候是不是就相当于输入http://localhost:8080/index.jsp
小白: 是的,这有啥关系
庆哥: 那么当你输入http://localhost:8080/hello的时候实际的请求路径是什么呢?
小白: 这个嘛,让我看看,我们的控制器是这样写的
public class Hello implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv1 = new ModelAndView();
mv1.setViewName("/WEB-INF/views/hello.jsp");
return mv1;
}
}
那么我们输入http://localhost:8080/hello的话,这个请求被DispatcherServlet拦截交给这个控制器处理,这个控制器返回给我们一个页面,那么最终的请求应该就是http://localhost:8080/WEB-INF/views/hello.jsp
庆哥: 分析的非常对,那么这个时候你有没有发现http://localhost:8080/index.jsp 和http://localhost:8080/WEB-INF/views/hello.jsp是不是都是一个请求,而且请求的都是一个jsp页面,但是这个页面却没有找到,那是什么原因呢?
小白: 哦哦,我知道了,这两个请求jsp页面的请求也被DispatcherServlet给拦截了,所以导致404!
庆哥: 正解!
小白: 原来是这样啊,那这个又能说明什么呢?
/会拦截所有请求吗?
庆哥: 别着急,我们改成/来看看,也就是这样
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
然后再次访问发现
这里写图片描述
这里写图片描述
这下全部访问成功,也就是得到jsp页面了,那么,你能得到什么结论呢?
小白: 这么一对比,我倒是明白了,/不拦截jsp的页面请求,而/*的话会拦截,这么说这个/就不可能是真正意义上的拦截所有请求了!
庆哥: 对的,这么一个例子可以得出,/并不会拦截所有请求,对于JSP的页面请求就不会拦截,而/*则会拦截,那么由此,结论就出来了
/并不是真正意义上的拦截所有请求,它不会拦截jsp的页面请求,其他的请求则会拦截
/*才是真正意义上的拦截所有请求
那么你说我们在SpringMVC开发中应该使用哪个比较好?
小白: 这么来说的话,当然是使用/比较好,因为我们要经常性的返回一些JSP页面。
庆哥: 对的,在SpringMVC中配置前端控制器,一般就这样
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
使用/来拦截请求,不拦截我们的jsp页面请求,那你知道什么时候经常使用/*吗?
小白:这个。。。一时间想不起来!
庆哥: 那么你们呢?
SpringMVC---彻底解决/和/*的问题!到底该用哪一个?的更多相关文章
- [转帖]超能课堂(207) SD卡标准错综复杂,到底该认哪一个?
超能课堂(207)SD卡标准错综复杂,到底该认哪一个? https://www.expreview.com/71505.html 开始的地方 SD容量等级 SD标准(SDSC) SDHC SDXC S ...
- SpringMVC 完美解决PUT请求参数绑定问题(普通表单和文件表单)
一 解决方案 修改web.xml配置文件 将下面配置拷贝进去(在原有的web-app节点里面配置 其它配置不变) <!-- 处理PUT提交参数(只对基础表单生效) --> <filt ...
- SpringMvc框架 解决在RESTFUL接口后加任意 “.xxx” 绕过权限的问题
问题描述: 框架使用的是SpringMVC.SpringSecurity,在做权限拦截的时候发现一个问题,假设对请求路径/user/detail进行了权限拦截,在访问/user/detail.abc的 ...
- springmvc对同名参数处理-我们到底能走多远系列(44)
springmvc对同名参数处理 扯淡: 中断发博客几个月,其实蛮不爽的,可能最近太忙太劳累了些,很多总结也没时间写,今天刚好遇到个小问题,就阅读下源码找找乐.因为考虑到网上大多是提供解决问题的方案, ...
- maven Spring 4.2+SpringMVC+dubbo解决TypeProxyInvocationHandler.invoke(SerializableTypeWrapper.java:239)
java.lang.NullPointerException org.springframework.core.SerializableTypeWrapper$TypeProxyInvocationH ...
- SpringMVC中的@Controller和@RequestMapping到底什么鬼?
1.1 @Controller是什么 首先看个例子: @Controller @RequestMapping("/blog") public class BlogControlle ...
- 异常-----springmvc + ajaxfileupload解决ajax不能异步上传图片的问题。java.lang.ClassCastException: org.apache.catalina.connector.RequestFacade cannot be cast to org.springframework.web.multipart.
说明这个问题产生的原因主要是form表单上传图片的时候必须是Content-Type:"multipart/form-data,这种格式的,但是ajax在页面不刷新的情况下去加载的时候只会把 ...
- SpringMVC中 解决@ResponseBody注解返回中文乱码
问题:在前端通过get请求服务端返回String类型的服务时,会出现中文乱码问题 原因:由于spring默认对String类型的返回的编码采用的是 StringHttpMessageConverter ...
- SpringMVC如何解决POST请求中文乱码问题,GET的又如何处理呢?
在web.xml中 <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-c ...
随机推荐
- 101334E Exploring Pyramids
传送门 题目大意 看样例,懂题意 分析 实际就是个区间dp,我开始居然不会...详见代码(代码用的记忆化搜索) 代码 #include<iostream> #include<cstd ...
- 505C Mr. Kitayuta, the Treasure Hunter
传送门 题目大意 一共有30000个位置,从第0个位置开始走,第一次走k步,对于每一次走步,可以走上一次的ki+1 ,ki ,ki-1步数(必须大于等于1),每个岛上有value,求最大能得到的val ...
- eclipse打包第三方jar的超简便方法
原帖地址 http://wenku.baidu.com/link?url=0kCBUc-7g4pGgXUrBA2jdCRkrSQmQzaDgGT59TyECAundF8c6R9yxy4EaBN3L8c ...
- 红帽企业版RHEL7.1在研域工控板上,开机没有登陆窗口 -- 编写xorg.conf 简单三行解决Ubuntu分辩率不可调的问题
红帽企业版RHEL7.1在研域工控板上,开机没有登陆窗口 没有登陆窗口 的原因分析: 没有登陆窗口的原因是因为有多个屏幕在工作,其中一个就是build-in 屏幕(内置的虚拟屏幕)和外接的显示器,并且 ...
- MySQL的索引单表优化案例分析
建表 建立本次优化案例中所需的数据库及数据表 CREATE DATABASE db0206; USE db0206; CREATE TABLE `db0206`.`article`( `id` INT ...
- Appium的常用定位方法
使用uiautomatorviewer.bat工具来找到属性定位元素,在SDK的tools目录下找到该工具,双击打开.左边框内展示app的界面元素,右上角框内展示元素的层级关系,右下角框内展示元素的属 ...
- 洛谷P3724 [AH2017/HNOI2017]大佬(决策单调性)
传送门 这个思路很妙诶->这里 以下为了方便,我把自信说成血量好了 虽然表面上看起来每一天有很多种选择,然而我们首先要保证的是不死,然后考虑不死的情况下最多能拿出多少天来进行其他操作.不死可以d ...
- Q的进阶用法
Q的实例化用法 #q1 里面的条件都是or的关系 q1=Q() q1.connector = 'OR' q1.children.append(('id',1)) q1.children.append( ...
- 屏幕字段不允许直接输入,只能通过SearchHelp(F4)
---恢复内容开始--- REPORT z_barry_test NO STANDARD PAGE HEADING . PARAMETERS: p_date TYPE sy-datum , ...
- javascript拖拽事件
<!DOCTYPE html> <html> <head> <title></title> <style type="tex ...