Java路径问题(本文主要针对web路径问题)
最近的研究发现Java的路径是一个很纠结的问题,在网上找了些资料,经过研究汇总如下:
在路径问题中有一个很关键的概念:斜杠“/”与反斜杠“\”
斜杠主要用来表示除法、分隔。在windows系统中,通常用来分隔命令行参数,表示选项等,不能用作文件名。
反斜杠在windows系统中表示目录
在Unix系统中斜杠表示目录,由于web遵循了Unix命名,所以在网址中用斜杠表示目录,所以URL地址都是使用斜杠。文件路径都是使用反斜杠。
简单的说在web中一般使用斜杠,在文件系统中一般使用反斜杠。
1.基本概念:
绝对路径:绝对路径就是你的文件在硬盘上的真正路径(UEL和物理路径)例如:
D:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.20代表物理路径
http://www.sun.com/index.htm代表一个URL绝对路径
相对路径:相对某个基准目录的路径。包含web的相对路径.例如:
Servlet中斜杠“/”代表web应用的跟目录,“./表示当前目录、 ../表示上级目录”,注
意:相对路径的基准目录通常是对自身定位,如自身的上级、下级目录。
2.关于JSP/servlet中的相对路径和绝对路径。
2.1 服务器端的地址
服务器端的相对地址指的是相对于你的web应用的地址,这个地址是在服务器端解析的(不同于html和JavaScript中的相对地址,他们是有客户端浏览器解析的),也就是说这时候jsp和servlet中的相对地址的基准目录是你的项目在web容器中的路径。
通过上面的图可以清楚的看到,实际上所有的jsp页面都是保存在容器路径下的webapps文件夹中的项目文件夹下,也就是我们在写项目的时候所看到的web文件夹,下面有两个文件夹,META-INF和WEB-INF,通常来说我们会把对外放开访问的页面放在根目录下,而那些只允许内部访问的页面通常放在WEB-INF下面,因为这个文件夹中的页面不能通过URL访问,这样就提高了安全性
2.2. 客户端的地址
所有页面中的相对地址都是相对于服务器根目录(http://192.168.0.1/)的,而不是根目录下的该web应用的目录即webapps文件夹的。
小结:在所有的新建jsp页面顶部都有这样一段代码,它的作用就是
request.getSchema()可以返回当前页面使用的协议
request.getServerName()可以返回当前页面所在的服务器的名字
request.getServerPort()可以返回当前页面所在的服务器使用的端口
request.getContextPath()可以返回当前页面所在的应用的名字
这四个方法得到的值拼装起来就变成了
http://localhost:8080/myWeb
是用来表明当前页面的相对路径所使用的根路径的,也就是将上面所获得的路径默认配置在页面中,这样,这个jsp页面内的所有相对路径都自动加上了http://localhost:8080/myWeb将相对路径变为了绝对路径。
3. JSP/Servlet中获得当前应用的相对路径和绝对路径
3.1 JSP中获得当前应用的相对路径和绝对路径
根目录所对应的绝对路径:request.getRequestURI();
文件的绝对路径:application.getRealPath(request.getRequestURI());
当前web应用的绝对路径:application.getRealPath(“/”);
取得请求文件的上层目录:new File(application.getRealPath(request.getRequestURI())).getParent();
3.2 Servlet中获得当前应用的相对路径和绝对路径:
跟目录所对应的绝对路径:request.getServletPath(); 文件的绝对路径:request.getSerssion().getServletContext().getRealPath(request.getRequestURI())
当前web应用的绝对路径:servletConfig.getServletContext().getRealPath(“/”);
serbletContext对象获得的几种方式:
javax.servlet.http.HttpSession.getServletContext()
javax.servlet.jsp.PageContext.getServletContext()
javax.servlet.ServletConfig.getServletContext()
一.问题
1)采用相对路径遇到的问题
相对路径固然比较灵活,但如果想复制页面内的代码却变得比较困难,因为不同的页面具有不同的相对路径,复制后必须修改每一个连接的路径。
如果页面被多于一个的页面所包含,那么被包含页面中的相对路径将是不正确的。
如果采用Struts的Action返回页面,那么由于页面路径与Action路径不同,使得浏览器无法正确解释页面中的路径,如页面为/pages /cust/cust.jsp,图片所有目录为/images/title.gif,这时在/pages/cust/cust.jsp中的所用的路径 为”../../images/title.gif”,但是如果某一个Action的Forward指向这个JSP文件,而这个Action的路径为 /cust/manage.do,那么页面内容中”../../images/title.gif”就不再指向正确的路径了。
解决以上问题似乎只有使用绝对路径了。
2)采用绝对路径遇到的问题
随着不同的Web应用发布方式,绝对路径的值也不同。如Web应用发布为MyApp,则路径”/MyApp/images/title.gif”是正确 的,但发布为另一应用时如MyApp2,这个路径就不对了,也许这个情况比较少,但以default方式发布Web应用时以上绝对路径也不 同:”/images/title.gif”。
二.解决方案
1)采用绝对路径,但为了解决不同部署方式的差别,在所有非struts标签的路径前 加${pageContext.request.contextPath},如原路径为:
”/images/title.gif”,改为
“${pageContext.request.contextPath}/images/title.gif”。
代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。
缺点:
操作不便,其他工具无法正确解释${pageContext.request.contextPath}
2) 采用相对路径,在每个JSP文件中加入base标签,如:
这样所有的路径都可以使用相对路径。
缺点:
对于被包含的文件依然无效。
真正使用时需要灵活应用1)和2),写出更加健壮的代码。
在使用的时候可以使用${pageContext.request.contextPath},也同时可以使 用达到同样的效果,同时,也可以 将${pageContext.request.contextPath},放入一个JSP文件中,将用C:set放入一个变量中,然后在用的时候用EL 表达式取出来。
2. Servlet中正确的路径表示
o 转发请求时:"/"表示“http://服务器IP:8080/Web应用名”,例如:
String forward = "/dir1/c.jsp";
RequestDispatcher rd = request.getQRequestDispatcher(forward);
o 重定向时:“/” 表示“http://机器IP:8080”,而通过request.getContextPath()得到的是:“http://机器IP:8080 /Web应用名”,例如:
String str = request.getContextPath();
response.sendRedirect(str + "/dir1/c.jsp");
3. 配置文件web.xml中
url-mapping中,"/"表示“http://IP地址:8080/Web应用名”
××总结××
• 在浏览器端:“/”表示的是一台WEB服务器,“http://机器IP:8080”
• 在服务器端(请求转发):“/”表示的是一个WEB服务器端的应用,“http://机器IP:8080/Web应用”
在服务器端(重定向):“/”表示的是一个WEB服务器,“http://机器IP:8080”
最近的研究发现Java的路径是一个很纠结的问题,在网上找了些资料,经过研究汇总如下:
在路径问题中有一个很关键的概念:斜杠“/”与反斜杠“\”
斜杠主要用来表示除法、分隔。在windows系统中,通常用来分隔命令行参数,表示选项等,不能用作文件名。
反斜杠在windows系统中表示目录
在Unix系统中斜杠表示目录,由于web遵循了Unix命名,所以在网址中用斜杠表示目录,所以URL地址都是使用斜杠。文件路径都是使用反斜杠。
简单的说在web中一般使用斜杠,在文件系统中一般使用反斜杠。
1.基本概念:
绝对路径:绝对路径就是你的文件在硬盘上的真正路径(UEL和物理路径)例如:
D:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.20代表物理路径
http://www.sun.com/index.htm代表一个URL绝对路径
相对路径:相对某个基准目录的路径。包含web的相对路径.例如:
Servlet中斜杠“/”代表web应用的跟目录,“./表示当前目录、 ../表示上级目录”,注
意:相对路径的基准目录通常是对自身定位,如自身的上级、下级目录。
2.关于JSP/servlet中的相对路径和绝对路径。
2.1 服务器端的地址
服务器端的相对地址指的是相对于你的web应用的地址,这个地址是在服务器端解析的(不同于html和JavaScript中的相对地址,他们是有客户端浏览器解析的),也就是说这时候jsp和servlet中的相对地址的基准目录是你的项目在web容器中的路径。
通过上面的图可以清楚的看到,实际上所有的jsp页面都是保存在容器路径下的webapps文件夹中的项目文件夹下,也就是我们在写项目的时候所看到的web文件夹,下面有两个文件夹,META-INF和WEB-INF,通常来说我们会把对外放开访问的页面放在根目录下,而那些只允许内部访问的页面通常放在WEB-INF下面,因为这个文件夹中的页面不能通过URL访问,这样就提高了安全性
2.2. 客户端的地址
所有页面中的相对地址都是相对于服务器根目录(http://192.168.0.1/)的,而不是根目录下的该web应用的目录即webapps文件夹的。
小结:在所有的新建jsp页面顶部都有这样一段代码,它的作用就是
request.getSchema()可以返回当前页面使用的协议
request.getServerName()可以返回当前页面所在的服务器的名字
request.getServerPort()可以返回当前页面所在的服务器使用的端口
request.getContextPath()可以返回当前页面所在的应用的名字
这四个方法得到的值拼装起来就变成了
http://localhost:8080/myWeb
是用来表明当前页面的相对路径所使用的根路径的,也就是将上面所获得的路径默认配置在页面中,这样,这个jsp页面内的所有相对路径都自动加上了http://localhost:8080/myWeb将相对路径变为了绝对路径。
3. JSP/Servlet中获得当前应用的相对路径和绝对路径
3.1 JSP中获得当前应用的相对路径和绝对路径
根目录所对应的绝对路径:request.getRequestURI();
文件的绝对路径:application.getRealPath(request.getRequestURI());
当前web应用的绝对路径:application.getRealPath(“/”);
取得请求文件的上层目录:new File(application.getRealPath(request.getRequestURI())).getParent();
3.2 Servlet中获得当前应用的相对路径和绝对路径:
跟目录所对应的绝对路径:request.getServletPath(); 文件的绝对路径:request.getSerssion().getServletContext().getRealPath(request.getRequestURI())
当前web应用的绝对路径:servletConfig.getServletContext().getRealPath(“/”);
serbletContext对象获得的几种方式:
javax.servlet.http.HttpSession.getServletContext()
javax.servlet.jsp.PageContext.getServletContext()
javax.servlet.ServletConfig.getServletContext()
一.问题
1)采用相对路径遇到的问题
相对路径固然比较灵活,但如果想复制页面内的代码却变得比较困难,因为不同的页面具有不同的相对路径,复制后必须修改每一个连接的路径。
如果页面被多于一个的页面所包含,那么被包含页面中的相对路径将是不正确的。
如果采用Struts的Action返回页面,那么由于页面路径与Action路径不同,使得浏览器无法正确解释页面中的路径,如页面为/pages /cust/cust.jsp,图片所有目录为/images/title.gif,这时在/pages/cust/cust.jsp中的所用的路径 为”../../images/title.gif”,但是如果某一个Action的Forward指向这个JSP文件,而这个Action的路径为 /cust/manage.do,那么页面内容中”../../images/title.gif”就不再指向正确的路径了。
解决以上问题似乎只有使用绝对路径了。
2)采用绝对路径遇到的问题
随着不同的Web应用发布方式,绝对路径的值也不同。如Web应用发布为MyApp,则路径”/MyApp/images/title.gif”是正确 的,但发布为另一应用时如MyApp2,这个路径就不对了,也许这个情况比较少,但以default方式发布Web应用时以上绝对路径也不 同:”/images/title.gif”。
二.解决方案
1)采用绝对路径,但为了解决不同部署方式的差别,在所有非struts标签的路径前 加${pageContext.request.contextPath},如原路径为:
”/images/title.gif”,改为
“${pageContext.request.contextPath}/images/title.gif”。
代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。
缺点:
操作不便,其他工具无法正确解释${pageContext.request.contextPath}
2) 采用相对路径,在每个JSP文件中加入base标签,如:
这样所有的路径都可以使用相对路径。
缺点:
对于被包含的文件依然无效。
真正使用时需要灵活应用1)和2),写出更加健壮的代码。
在使用的时候可以使用${pageContext.request.contextPath},也同时可以使 用达到同样的效果,同时,也可以 将${pageContext.request.contextPath},放入一个JSP文件中,将用C:set放入一个变量中,然后在用的时候用EL 表达式取出来。
2. Servlet中正确的路径表示
o 转发请求时:"/"表示“http://服务器IP:8080/Web应用名”,例如:
String forward = "/dir1/c.jsp";
RequestDispatcher rd = request.getQRequestDispatcher(forward);
o 重定向时:“/” 表示“http://机器IP:8080”,而通过request.getContextPath()得到的是:“http://机器IP:8080 /Web应用名”,例如:
String str = request.getContextPath();
response.sendRedirect(str + "/dir1/c.jsp");
3. 配置文件web.xml中
url-mapping中,"/"表示“http://IP地址:8080/Web应用名”
××总结××
• 在浏览器端:“/”表示的是一台WEB服务器,“http://机器IP:8080”
• 在服务器端(请求转发):“/”表示的是一个WEB服务器端的应用,“http://机器IP:8080/Web应用”
在服务器端(重定向):“/”表示的是一个WEB服务器,“http://机器IP:8080”