使用Ant脚本构建异常处理(乱码&找不到符号)
使用Ant构建Web项目异常处理
编译异常显示乱码&request.getServletContext()找不到符号
序:
先说说我们项目的场景,项目是普通的web项目没有使用maven,所有jar都在lib下,另外我们的项目jar加入了Taomcat8.0的运行jar,EAR等。用于编译的ant脚本上次转测编译完全正常。
本地环境tomcat运行正常,再来看看ant脚本。其他copy、常量定义就不看了,直接看看编译的关键位置。
注意encoding设置加了的。
下面再看看编译报错:
乱码:
找不到符号(已经解决乱码后才知道是找不到符号):
1、 乱码处理
最开始一直怀疑是ant脚本的编码问题,检查几遍,文件编码、javac里的encoding指定、关联的脚本编码等,结果发现都是正确的。百度也没百度到,丢到公司开发群问。感谢同事亮仔,以前遇到过这个问题,过来跟我看了,秒解。下面说说操作步骤,如图:
光标放在脚本上,点反键……
原先我是UTF-8的,这里改成gbk,重新run,提示变中文,正常了。据同事亮仔补充,这里如果设置不对,有可能run什么反应都没有。
亲爱的大家get到没?
2、 request.getServletContext()编译报找不到符号
这种编译过程中报错的问题,如果本地环境正常,一般就是编译缺jar包的问题。
用原servlet-api.jar编译,结果:
上次转测正常,这次不报错,结合报错分析,怀疑肯定是jar的问题。然后查看方法getServletContext()属于的jar,肯定就是servlet-api.jar的问题。度娘说是servlet-api.jar的版本低了,因为使用了3.0才支持的方法,于是更换使用3.0.1版本编译,结果:
同样是找不到符号,但是对象由request换成了ReadListener,到这里我就怀疑jar版本有差异了,于是请出反编译利器gui,查看2个版本jar的反编译,如图:
3.0.1 原版本
request的找不到符号变成了ReadListener,然后结合上图反编译的jar,你是不是已经找到了什么呢?没错就是矛盾,3.0.1支持了request.getServletContext()但是没有ReadListener,原版有ReadListener但是不支持request.getServletContext(),于是在maven仓库看3.x版本是否可以兼容2个方法,于是找到了3.1.0
找到这我就有点郁闷,这大版本变更怎么一会有一会没有这个ReadListener呢?看来大佬们的版本控制也……
到这里本可以结束的,但是这个要换ant编译的扩展jar包,虽然不麻烦,但是还是有点不爽,于是想request.getServletContext()可以换种当前servlet-api.jar支持的写法吗?继续查看反编译的jar,最后发现:
于是将request.getServletContext()改成request.getSession().getServletContext(),如图:
结果本地编译不报错,ant编译也不报错,编译结果:
久违的SUCCESSFUL,这就是整个过程。
下面补充java中各种取上下文路径的小结(来源度娘):
一、获得都是当前运行文件在服务器上的绝对路径
在servlet里用:
this.getServletContext().getRealPath();
在struts用:
this.getServlet().getServletContext().getRealPath();
在Action里用:
ServletActionContext.getRequest().getRealPath();
以上三个获得都是当前运行文件在服务器上的绝对路径
其实:
request.getRealPath("url"); // 虚拟目录映射为实际目录
request.getRealPath() 这个方法已经不推荐使用了,代替方法是:
request.getSession().getServletContext().getRealPath();
二、request获取各种路径总结
request.getRealPath("url"); // 虚拟目录映射为实际目录
request.getRealPath("./"); // 网页所在的目录
request.getRealPath("../"); // 网页所在目录的上一层目录
request.getContextPath(); // 应用的web目录的名称
如http://localhost:7001/bookStore/
/bookStore/ => [contextPath] (request.getContextPath())
获取Web项目的全路径
String strDirPath=request.getSession().getServletContext().getRealPath("/");
以工程名为news为例: http://localhost:8080/news/main/list.jsp
(1) 得到包含工程名的当前页面全路径:request.getRequestURI()
结果:/news/main/list.jsp
(2) 得到工程名:request.getContextPath()
结果:/news
(3) 得到当前页面所在目录下全名称:request.getServletPath()
结果:如果页面在jsp目录下 /main/list.jsp
(4) 得到IE地址栏地址:request.getRequestURL()
结果:http://localhost:8080/news/main/list.jsp
(5) 得到相对地址:request.getRequestURI()
结果:/news/main/list.jsp
(6) 得到页面所在服务器的全路径:application.getRealPath("页面.jsp")
结果:D:\resin\webapps\news\main\list.jsp
(7) 得到页面所在服务器的绝对路径:absPath=new java.io.File(application.getRealPath(request.getRequestURI())).getParent();
结果:D:\resin\webapps\news
三、在类中取得路径
(1) 类的绝对路径:Class.class.getClass().getResource("/").getPath()
结果:/D:/TEST/WebRoot/WEB-INF/classes/pack/
例如:
String path=this.getClass().getResource("/").getPath();//得到d:/tomcat/webapps/工程名WEB-INF/classes/路径
path=path.substring(1,path.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
(2) 得到工程的路径:System.getProperty("user.dir")
结果:D:\TEST
四、在Servlet中取得路径
(1) 得到工程目录:request.getSession().getServletContext().getRealPath("") 参数可具体到包名。
结果:E:\Tomcat\webapps\news
importjava.io.File;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
System.out.println(Test.class.getClassLoader().getResource(""));
System.out.println(ClassLoader.getSystemResource(""));
System.out.println(Test.class.getResource(""));
System.out.println(Test.class.getResource("/")); //Class文件所在路径
System.out.println(new File("/").getAbsolutePath());
System.out.println(System.getProperty("user.dir"));
}
}