原文链接:http://season-jy.iteye.com/blog/2272578
1、问题的出现:
一个web项目,有webcontent目录存放jsp文件、css、js、image等文件,有servlet的目录存放servlet类文件、dao类文件、common类文件、action类文件等等。在我们开发的过程中,经常需要各种跳转,由于文件众多,初始时没有考滤的很周全,各种相对路径、绝对路径一起上,导致越写到后面,出现的问题也越多,页面跳不了、js/css/图片文件找不到等等,然后又要调试一番,效率低下浪费了许多时间。
2、对于以上问题我们如何解决呢?
首先,我们要统一路径的写法。虽然相对路径写起来代码少,比较快,但是有时候目录的深度太高,导致../../这样的相对路径的寻址也不是很好管理,所以统一用绝对路径为好。但是用统一的路径的话,就必须弄一个变量,存放项目的根目录,这样我们写各种链接或跳转地址时,就直接用起这个变量就ok啦,看起来简洁许多。
3、具体实现:
我们都知道,在web中,地址是这样的->协议://主机名或ip地址:端口号/文件路径,这个文件路径就是从我们项目的根目录开始的,所以的到这一个url的方法我们用以下代码实现:
public static String getPath(HttpServletRequest request){
String scheme=request.getScheme();//获取协议类型名称
String name=request.getServerName();//获取web服务器名字
int port=request.getServerPort();//获取使用的端口号
String path=request.getContextPath();//获取当前项目的跟路径
String url=scheme+"://"+name+":"+port+path;//得到到项目根目录的绝对路径
//System.out.println(url);
return url;
}
我们获取各种关于服务器的信息可以用request对象里面的方法:
1)request.getScheme()方法不用多说,获取协议的名称,如http、https、ftp等等
2)request.getServerName()方法获取服务器名称,若是本地服务器就是localhost,这个也不用多说。
3)request.getServerPort()方法获取协议使用的端口号,这里本项目用了8080端口号。
4)request.getContextPath()获取当前项目的根路径,这个就要多说一点了。
当我们用的是tomcat服务器时,项目一般部署在tomcat下的webapps目录下面,但是部署有两种。
一种是直接把项目文件复制到webapps的ROOT目录下(当然,用eclipse开发时应该不是这样子,而是第二种方法),这样访问的时候在浏览器中直接用服务器名就可以访问到web内容,这样子用request.getContextPath()获取得到的是一个空字符"",注意不是null。
一种是在webapps下面建立一个以项目名称的目录,并将项目拷到这个目录。这样子用request.getContextPath()方法获得的是一个"/项目名称"的字符串。
本java web项目是第二种方法。
最后我们用->(协议://主机名或ip地址:端口号/文件路径即项目根目录)的形式生成了一个访问到项目跟目录的绝对路径。这就是我们要的url。
4、使用方法
既然我们有了得到根目录的绝对地址的方法,开始时我们将其封装到GLOBALS类中,然后在jsp页面中导入这个类,直接调用它的方法返回一个url来使用,在各种地方用在"<%="和"%>"之间插入url变量来使用。
如:
<link rel="stylesheet" href="<%=URL%>/css/admin/AdminIndex.css">
这样子的形式,这样当产生静态的页面是,即html页面返回给浏览器时,<%=URL%>就变成了实际的地址,不再是变量。
5、还有问题。
我们在jsp的指令标签和动作标签里面不能再用<%=URL%>这样子的形式嵌入了。除了这个<%=%>方法,我们还有一种和这个是等效的方法就是el表达式,语法结构:${expression}
详解:http://www.cnblogs.com/cyjch/archive/2012/02/08/2342387.html
jsp的动作标签里面是可以用${expression},即el表达式的。这样也就解决了页面所有的地址问题。
<jsp:include page="${URL}/admin/view/AdminRight.jsp"/>
6、还可以优化一下
我们在每个页面都设置了调用了那个方法,来获取url,可是感觉是没必要每次都运行那个方法,重复运行。后面想了想,如何在所有页面上弄一个全局的变量,哪里都可以获取。那就是session,可以用session来存,这样在每个页面只要通过session获取就可以了,没必要每次都要运行那个方法。
所以我们在用户首次访问时,就直接设置了session:
String url=GLOBALS.getPath(request);
session.setAttribute("url", url);
然后在需要这个url的地方获取:
<%String URL=session.getAttribute("url").toString(); %>