前言:
jsp作为javaweb开发中常见的视图技术,我们平时在开发项目使用的过程中,经常会导入一些静态资源,比如css\js\jpg、png等图片格式的文件,这些文件的路径成了问题,经常会出现索引不到的情况发生,本篇博客就来探究一下jsp中的路径问题。
本篇博客目录:
一:基本常识
首先告诉几个常识:
1:我们常用的web项目是运行在tomcat中,而tomcat容器不会识别包中的src文件,它识别的是编译后的class类,所以按照Eclispe的结构Project-Src-WebRoot/WebContent,它只会识别下层路径,也就是类路径.所以实际编程中的路径不要出现WebRoot/WebContent.
2:静态资源不要放在WEB-INF目录下,否则会出现无法访问的情况(即时你的资源路径是对的)因为WEB-INF下有一个特殊的机制是:对文件起到一个保护作用,起到安全保护的作用,防止外部直接输入链接访问其文件
3:/:表示当前目录 ../:表示当前目录的上一层目录 ~/ 表示文件的根目录
二:引入静态资源
2.1:我们先来看一下jsp中几个非常重要的方法,利用他们我们可以得到一些路径相关的地址
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/";
这两个方法是标准的jsp头方法,一般利用myeclipse等IDE创建的空jsp都会预先给出两句代码,我们来分别看一下表示的含义:
request.getContextPath(); / /得到的是 项目的名称
request.getSheme();//得到的结果是http 表示请求的具体协议,常见的如下:http/https/ftp
request.getServerPort://得到的是请求头的端口
request.getServername();//得到的是请求头的IP地址,关于这个方法会存在一些代理商的问题,下面会讲到
2.2:具体的示例
假如我们有一个请求是 http://192.168.0.1:8083/Project/ask ,这是一个标准的http请求,那么当浏览器将这个请求发送给服务器的时候,jsp得到的是:
request.getContextPath(); Project
request.getSheme(); http
request.getServerPort(); 8083
request.getServername(); 192.168.0.1
basePath的值就是:http://192.168.0.1:8080/Project/
2.4:request.getServername()方法存在的问题
request.getServername:当使用代理的时候,注意这里需要解析请求头中的。‘X-FORWARDED-HOST,拿到它真实的请求。关于这里的使用场景是:当你的服务部署在一个内网地址上,再经过nginx的反向代理映射到一个外部网络中,那么用户在使用外网的时候,就会出现访问不到资源的情况,这是因为此时资源请求的是内部网络地址,而一般用户是访问不到内网的,此时就需要转换,用以下代码:
String serverName = request.getHeader("X-FORWARDED-HOST"); if (serverName == null || serverName.length() < 1) { serverName = request.getServerName() + (request.getServerPort() == 80 ? "" : (":" + request.getServerPort())); } else if (serverName.conains(",")) { serverName = serverName.substring(0, serverName.indexOf(",")).trim(); }
2.4:引入css和js等静态资源
2.4.1常见的比如在jsp中导入一个css文件,这时候的路径为:
<link rel="stylesheet" type="text/css" href="<%=basePath%>/assets/css/reset.css" />
这里引入basePath就是告诉浏览器去访问当前项目的路径,最终它获取的css路径为:http://192.168.0.1:8080/Project/assets/css/reset.css
这样的写法是没有问题的,如果你的项目下存在asses/css/reset.css这个文件的话 是一定可以索引到的
2.4.2:我们来换种写法:
<link rel="stylesheet" type="text/css" href="/assets/css/reset.css" />
这样的写法最终浏览器会解析成下面这种url:
http://192.168.0.1:8080/assets/css/reset.css
很明显这种写法是有问题的,因为浏览器并不会给你自动加上项目名,它只是获取了当前请求的ip和port,然后直接引用这个路径
2.4.3:还有第三种写法:
<link rel="stylesheet" type="text/css" href="assets/css/reset.css" />
这个写法浏览器会默许你的是相对路径,然后它会自动解析成下面这个样子:
http://192.168.0.1:8080/Project/assets/css/reset.css
这个写法是对的,并且也可以成功索引到具体的文件,它比起basePath看起来更加清爽简洁
2.4.5:第4中写法:
<link rel="stylesheet" type="text/css" href="<%=path%>/assets/css/reset.css" />
这种写法经过测试也是没有问题的,它经过浏览器解析最后返回的url是:
http://192.168.0.1:8080/Project/assets/css/reset.css
三:获取当前的类路径
3.1:获取当前class对应的路径
public class Test { public static void main(String[] args) { String path = Test.class.getResource("/").getPath(); File file = new File(path); System.out.println(file.getPath());//E:\TravelAgency_TestVersion\Project\WebRoot\WEB-INF\classes String path2 = file.getParentFile().getParentFile().getPath(); System.out.println(path2);//E:\TravelAgency_TestVersion\Project\WebRoot } }
很明显可以看出这个方法是获取的硬盘上的路径,主要采用的方法是获取当前类的class然后调用getResource方法,再调用getPath()方法获取。这里常见的应用场景是动态获取当前的项目路径,索引一些字体、图片等的时候,路径都不能写死,采用这个方法比较灵活。
四:总结
本篇博客探究了jsp中的路径问题,因为在平时的项目中经常会出现某个静态文件找不到的情况发生,借此前的项目中出现的问题,我把此总结一下,防止以后再次发生这样的情况。关于路径的写法会有各种不同,以后如果遇到了不同的写法会及时更新本篇博客,未完-待后续。