Java--SpringMVC之url-pattern,静态资源;URL相对路径,绝对路径
Posted MinggeQingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java--SpringMVC之url-pattern,静态资源;URL相对路径,绝对路径相关的知识,希望对你有一定的参考价值。
url-pattern
url-pattern 拦截匹配规则的 url 请求,进入SpringMVC框架处理, SpringMVC就会去找能够处理这个url 的 handler去执行业务逻辑
可使用两种值
(1)使用扩展名方式,语法 *.xx , xx是自定义的扩展名,
常用的方式 *.do, *.action, *.mvc等等,不能使用 *.jsp,如下:
http://localhost:8080/myweb/some.do
http://localhost:8080/myweb/other.do
(2)使用斜杠 "/"
当项目中使用了 "/",它会替代 tomcat中的default 导致所有的静态资源都交给DispatcherServlet处理
一、静态资源
(1)index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
</head>
<body>
<p>SpringMVC项目</p>
<p>url-patten路径</p>
<form action="dosome" method="post">
姓名:<input type="text" name="name"> <br/>
年龄:<input type="text" name="age"> <br/>
<input type="submit" value="提交参数">
</form>
<br/>
<img src="images/image-1.jpeg" alt="我是images/下的静态资源图片,不能显示">
<br/>
<img src="static/images/image-2.jpeg" alt="我是static/images/下的静态资源图片,不能显示">
</body>
</html>
(2)web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>myweb</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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<!-- url-pattern 拦截匹配规则的 url 请求,进入springmvc 框架处理,
springmvc 就会去找能够处理这个url 的 handler去执行业务逻辑
可使用两种值
(1)使用扩展名方式,语法 *.xx , xx是自定义的扩展名,
常用的方式 *.do, *.action, *.mvc等等
不能使用 *.jsp
http://localhost:8080/myweb/some.do
http://localhost:8080/myweb/other.do
(2)使用斜杠 "/"
当项目中使用了 "/",它会替代 tomcat中的default
导致所有的静态资源都交给DispatcherServlet处理, 默认情况下DispatcherServlet没有处理静态资源的能力
没有控制器对象能处理静态资源的访问,因此静态资源(html,js,图片,css)都是404
动态资源some.do是可以访问,因为我们程序中有MyController控制器对象,能处理some.do请求。
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
(3)处理器MyController
@Controller
public class MyController
@RequestMapping(value = "/dosome")
public ModelAndView doSome(HttpServletRequest request , String name, Integer age)
System.out.println("doSome name="+name+" age="+age);
ModelAndView mv = new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("show");
// RequestDispatcher rd =request.getRequestDispatcher("/show.jsp");
// rd.forward(request,null);
// request.getRequestDispatcher("/show.jsp").forward(request,null);
return mv;
我们在 <url-pattern>中设置访问路径 改为 "/",此时访问静态资源(html,js,图片,css)都是404
默认情况下DispatcherServlet没有处理静态资源的能力。没有控制器对象能处理静态资源的访问,因此静态资源(html,js,图片,css)都是404
动态资源some.do是可以访问,因为我们程序中有MyController控制器对象,能处理some.do请求
此时,我们可以打开安装Tomcat的安装路径下的 conf 目录,打开 web.xml文件,看源码
<!-- The default servlet for all web applications, that serves static -->
<!-- resources. It processes all requests that are not mapped to other -->
<!-- servlets with servlet mappings (defined either here or in your own -->
<!-- web.xml file). This servlet supports the following initialization -->
<!-- parameters (default values are in square brackets): -->
......
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
DefaultServlet作用:
【1】处理静态资源
【2】处理未映射到其它servlet的请求
对于静态资源的访问,我们有两种处理方式
(1)加入<mvc:default-servlet-handler>标签
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 声明组件扫描器 -->
<context:component-scan base-package="com.mycompany.controller" />
<!-- 声明SpringMVC框架中的视图解析器,设置视图文件的路径:InternalResourceViewResolver
注:处理器方法返回String,表示完整视图路径,此时不能配置视图解析器
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀:视图文件的路径 -->
<property name="prefix" value="/WEB-INF/view/" />
<!-- 后缀:视图文件的扩展名 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 第一种处理静态资源方式:
在SpringMVC配置文件中加入 <mvc:default-servlet-handler>
原理:加入<mvc:default-servlet-handler>标签后,SpringMVC框架会创建控制器对象DefaultServletHttpRequestHandler(类似我们自己创建的MyController)
DefaultServletHttpRequestHandler这个对象可以把接收的请求转发给 Tomcat 的DefaultServlet
The default servlet for all web applications, that serves static resources.
It processes all requests that are not mapped to other servlets with servlet mappings
(defined either here or in your own web.xml file).
这时 静态资源就可以加载出来,但是发起请求就报错 404;
需要加入<mvc:annotation-driven>标签;<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<mvc:default-servlet-handler />
<!-- 注解驱动
http://www.springframework.org/schema/mvc
<mvc:annotation-driven> 注解驱动实现的功能:完成Java对象到json,xml,text,二进制等数据格式的转换
<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<mvc:annotation-driven />
</beans>
(2) 加入<mvc:resources>标签
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 声明组件扫描器 -->
<context:component-scan base-package="com.mycompany.controller" />
<!-- 声明SpringMVC框架中的视图解析器,设置视图文件的路径:InternalResourceViewResolver
注:处理器方法返回String,表示完整视图路径,此时不能配置视图解析器
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀:视图文件的路径 -->
<property name="prefix" value="/WEB-INF/view/" />
<!-- 后缀:视图文件的扩展名 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 第二种处理静态资源方式:
<mvc:resources>:加入<mvc:resources>标签后SpringMVC框架会创建ResourceHttpRequestHandler处理器对象
这个对象处理井田资源的访问,不依赖Tomcat服务器
mapping:访问静态资源的 URI 地址,使用通配符 **
location:静态资源在项目中的目录位置(/webapp 目录下)
images/**:表示 images/image-1.jpeg , images/user/logo.gif , images/order/good/list.png
这时 静态资源就可以加载出来,但是发起请求就报错 404;
需要加入<mvc:annotation-driven>标签;<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<!--<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />-->
<!-- 如果静态资源文件目录过多,可以将其统一放在一个static目录下;使用一个通配语句,指定所有静态资源文件访问 -->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- 注解驱动
http://www.springframework.org/schema/mvc
<mvc:annotation-driven> 注解驱动实现的功能:完成Java对象到json,xml,text,二进制等数据格式的转换
<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<mvc:annotation-driven />
</beans>
不管上述哪种方式,我们同事访问动态资源和静态资源时,会导致冲突
因此需要 在 springmvc.xml 配置文件中加入 <mvc:annotation-driven /> 注解驱动
<!-- 注解驱动
http://www.springframework.org/schema/mvc
<mvc:annotation-driven> 注解驱动实现的功能:完成Java对象到json,xml,text,二进制等数据格式的转换
<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<mvc:annotation-driven />
二、路径
我们启动Tomcat服务之后,发现在浏览器中输入项目中输入 IP、端口、项目名之后就可以访问页面,这里就存在一个访问路径问题,在 index.jsp 页面中 发现带 斜杠"/" 和不带斜杠 "/" 区别很大
首先先说一下访问路径问题
访问地址分类:
1、绝对地址
带有协议名称的是绝对地址;如: http://www.baidu.com ;ftp://10.122.6.1
2、相对地址
没有协议开头的, 例如 menu/some.do,/menu/some.do
相对地址不能独立使用,必须有一个参考地址;通过参考地址+相对地址本身才能指定资源。
在jsp , html中使用的地址, 都是在前端页面中的地址,都是相对地址
我们有如下 index.jsp 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>SpringMVC项目</p>
<p> <a href="menu/some.do">发起menu/some.do请求</a> </p>
<br/>
<p> <a href="/menu/some.do">发起/menu/some.do请求</a> </p>
<br/>
<p> <a href="springmvc-6-path/menu/some.do">发起springmvc-6-path/menu/some.do请求</a> </p>
<br/>
<p> <a href="/springmvc-6-path/menu/some.do">发起/springmvc-6-path/menu/some.do请求</a> </p>
</body>
</html>
处理器方法MyController方法如下
@Controller
@RequestMapping("/menu")
public class MyController
@RequestMapping(value = "/some.do")
public ModelAndView dSome()
//处理some.do请求了。 相当于service调用处理完成了。
ModelAndView mv = new ModelAndView();
mv.addObject("msg","欢迎使用springmvc做web开发");
mv.addObject("fun","执行的是doSome方法");
mv.setViewName("/index.jsp");
return mv;
带 斜杠"/" 和不带斜杠 "/",带项目名和不带项目名区别如下
1、"menu/some.do" 不带斜杠 "/"
http://localhost:8081/springmvc-6-path/menu/some.do(正确)
访问地址: http://localhost:8081/springmvc-6-path/index.jsp
路径: http://localhost:8081/springmvc-6-path/;资源: index.jsp
在index.jsp发起 menu/some.do请求
访问地址变为http://localhost:8081/springmvc-6-path/menu/some.do
当地址中 不带斜杠 "/"开头,例如 menu/some.do , 当点击链接时, 访问地址是当前页面的地址 + 链接的地址
http://localhost:8081/springmvc-6-path/ + menu/some.do
2、"/menu/some.do" 带斜杠 "/"
HTTP状态 404 - 未找到
http://localhost:8081/menu/some.do
访问的是: http://localhost:8081/springmvc-6-path/menu/index.jsp
路径: http://localhost:8081/springmvc-6-path/;资源: index.jsp
点击 /menu/some.do,访问地址变为 http://localhost:8081/menu/some.do
参考地址是 服务器地址, 也就是 http://localhost:8081
3、"springmvc-6-path/menu/some.do" 带项目名,不带斜杠 "/"
HTTP状态 404 - 未找到
http://localhost:8081/springmvc-6-path/springmvc-6-path/menu/some.do
4、"/springmvc-6-path/menu/some.do" 带项目名,带斜杠 "/"
http://localhost:8081/springmvc-6-path/menu/some.do(正确)
5、"$pageContext.request.contextPath/menu/some.do"
在 jsp 视图上显示 "/springmvc-6-path/menu/some.do"
http://localhost:8081/springmvc-6-path/menu/some.do(正确)
针对上述访问路径问题,有两种解决方案
1、加入$pageContext.request.contextPath
<%-- 如果资源不能访问: 加入$pageContext.request.contextPath--%>
<a href="$pageContext.request.contextPath/menu/some.do">发起$pageContext.request.contextPath/menu/some.do请求</a>
2、加入一个base标签(html语言中的标签); 表示当前页面中访问地址的基地址
页面中所有 没有 斜杠 “/” 开头的地址,都是以base标签中的地址为参考地址
使用base中的地址 + menu/some.do 组成访问地址
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--base标签, 是html语言中的标签;表示当前页面中访问地址的基地址--%>
<%--页面中所有没有 "/" 开头的地址,都是以base标签中的地址为参考地址--%>
<%--使用base中的地址 + menu/some.do 组成访问地址--%>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" +
request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>Title</title>
<base href="<%=basePath%>" />
</head>
这时再看index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--base标签, 是html语言中的标签;表示当前页面中访问地址的基地址--%>
<%--页面中所有没有 "/" 开头的地址,都是以base标签中的地址为参考地址--%>
<%--使用base中的地址 + menu/some.do 组成访问地址--%>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" +
request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>Title</title>
<base href="<%=basePath%>" />
</head>
<body>
<p>SpringMVC项目</p>
<p> <a href="menu/some.do">发起menu/some.do请求</a> </p>
<br/>
<p> <a href="/menu/some.do">发起/menu/some.do请求</a> </p>
<br/>
<p> <a href="springmvc-6-path/menu/some.do">发起springmvc-6-path/menu/some.do请求</a> </p>
<br/>
<p> <a href="/springmvc-6-path/menu/some.do">发起/springmvc-6-path/menu/some.do请求</a> </p>
<br/>
<%-- 如果资源不能访问: 加入$pageContext.request.contextPath--%>
<a href="$pageContext.request.contextPath/menu/some.do">发起$pageContext.request.contextPath/menu/some.do请求</a>
</body>
</html>
以上是关于Java--SpringMVC之url-pattern,静态资源;URL相对路径,绝对路径的主要内容,如果未能解决你的问题,请参考以下文章
[Java]SpringMVC工作原理之二:HandlerMapping和HandlerAdapter
[Java] SpringMVC工作原理之二:HandlerMapping和HandlerAdapter