正在编一个网站,在本地编好以后打包成war远程部署到tomcat。在本地一切正常,可是一传到服务器上去就不行了。
我这个网站程序会访问一个网页,去那个网页上爬取点东西,要想爬取就必须须要data.txt提供令牌。
初步锁定bug所在区间,编一个小程序测试一下java
@RequestMapping("haha") @ResponseBody String debug() { try { return Util.debug("SY1606604", "xxxxxx", HttpClients.createDefault()); } catch (IOException e) { e.printStackTrace(); } return "error"; }
出错的那段代码原来是Util.login(username,password,client)
我把出错的那段代码重写,写成一个函数叫作Util.debug(),让这个函数返回尽可能多的信息
结果
怎么会这样呢?我写了ResponseBody了呀,返回不得是个字符串吗?不会跳到“error”页面的呀。
那我就多返回一点数据:小程序
@RequestMapping("haha") @ResponseBody String debug() { StringBuilder builder = new StringBuilder(); try { builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault())); } catch (IOException e) { builder.append(e.getMessage()); builder.append(e.getCause().toString()); builder.append(e.toString()); builder.append("不可能出错呀"); } return "error"; }
访问haha页面,结果发现仍是上面那种状况,一点都没变啊!
为何呀?
原来是错中有错,在catch中再次抛出了异常!我又没写finally,结果这个Servlet就向容器抛出异常,结果就跳转到error页面去了!
还有,若是是运行时异常,catch IOException好像不会接住吧,因此改为接一切异常!再加上一个finallytomcat
StringBuilder builder = new StringBuilder(); try { builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault())); } catch (Exception e) { builder.append(e.getMessage()); builder.append(e.getCause().toString()); builder.append(e.toString()); builder.append("不可能出错呀"); } finally { return builder.toString(); }
结果页面中一个字都没有,ctrl+u查看网页源代码,也是空空如也。这tm都是咋回事啊?
要知道上面每一次试错都须要进行服务器
每次至少两分钟。
我怒了,我打印了这么多东西为啥一个字都没有?
重定向,接受一切打印!!!!!!!!app
@RequestMapping("haha") @ResponseBody String debug() { StringBuilder builder = new StringBuilder(); builder.append("百思不得其解"); ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(out); try { System.setErr(stream); System.setOut(stream); builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault())); } catch (Exception e) { e.printStackTrace(); } finally { builder.append(out.toString()); return builder.toString(); } }
终于:
终于看到了日志,求之不得的日志,终于知道本身错在哪里?当我看到找不到data.txt文件这句话时,我差点哭出来,好艰难。
珍惜日志,哪有那么多条件去让你调试、跟踪,根本不可能。连部署都是这么艰难,就像ACM题同样,只告诉你对错bool值,不告诉你错在哪里,这是最使人疯狂的。
仿佛有一个声音不停地在耳边呼喊:“你不行的”,我一直追问:“为何不行?我哪里不行?”这个声音仿佛在嘲笑:“你为何不行,我不说”。这就像是完全的否认。
不断地向别人展现别人没法更改的错误,是一种邪恶。它只是为了指出错误而指出错误,只是无理由的告诉你你不行。这让人如堕深渊。
别人有错误,若是以让其改正为目的,则是善意;若是只是一次简单的评判,则是中意;若是是指出别人错误彰显本身的明智或者羞辱别人,那这就是恶意。maven
回到上文,这里的错误是找不到data.txt,代码中是这么写的:函数
OutputStream cout = Files.newOutputStream(Paths.get("src/main/resources/checkcode.jpg"));
路径有问题,由于一旦部署到服务器,就没有这种路径了!应该去掉src/main/resources/这个前缀,由于在maven打包时自动把resources目录下的东西打包到classpath路径中了。更好的解决方法是:使用classPath而不要使用操做系统的文件路径测试
回头观望,我发现了一种调试程序的手段。
定义一个拦截器,在进行处理请求以前,重定向输出流、错误流或者日志到一个内存流,在请求处理的最后,若是发现错误,则打印这个流。这样就能清楚知道本身错在哪里了。网站