2019-05-10 EasyWeb打包成Jar运行遇到的问题
1.使用Eclipse的Maven命令打包,老是出错,没法打包成jar
解决方法:在项目根目录下使用命令行 mvn clean install 进行打包
优化方法:项目根目录下创建一个bat文件,文件内容为 mvn clean install;这样每次需要打包点击一下即可
2.打包成jar后运行报表,获取报表模板文件失败,原因是jar里面没有文档路径,所以通过路径方式获得输入流无效,以下列举几种获得路径的代码
1 /* 方式1取模板文件 打包成jar失效 jasperPath=classpath:xxx */ 2 String path = URLDecoder.decode(ResourceUtils.getURL(jasperPath).getPath(),"UTF-8"); 3 File file = new File(path); 4 FileInputStream inputStream = new FileInputStream(file);
1 /* 方式2取模板文件 打包成jar失效 jasperPath=classpath:xxx */ 2 File file = ResourceUtils.getFile(jasperPath); 3 FileInputStream inputStream = new FileInputStream(file);
1 /* 方式3取模板文件 jasperPath=classpath:xxx */ 2 Resource res = new ClassPathResource(jasperPath.replace("classpath:", "")); 3 InputStream inputStream = res.getInputStream();
1 /* 方式4取模板文件 jasperPath=classpath:xxx */ 2 InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(jasperPath.replace("classpath:", ""));
1 /* 方式5取模板文件 jasperPath=classpath:xxx */ 2 InputStream inputStream = JasperReportUtils.class.getClass().getResourceAsStream(jasperPath.replace("classpath:", "/"));
目前我只测试了方式1、2不能访问,方式3是可以的,其他的还没测
3.jasperreport报表主从报表,主报表里面需要设置从报表的路径,原来的是设置的固定的,所以会找不到从报表模板
①通过java代码设置参数值parameters.put("SUBREPORT_DIR", "主报表模板的上级路径");
②检查主报表内是否含有SUBREPORT_DIR参数,如果没有就自己加上(据说增加subreport组件时候会加上,但是我找了下没有,所以自己加上)
③设置subreport的subreportExpression
1 <subreportExpression><![CDATA[ $P{SUBREPORT_DIR} + "order-detail.jasper"]]></subreportExpression>
4.由于第2个问题说了不能在jar包中获得路径,所以也就没办法在第3个问题中设置主报表上级路径了;只能把报表模板放到jar包外,我这里是与jar包同级
通过模板生成报表的代码如下:
1 /** 2 * 使用JavaBean填充打印PDF到Html中 3 * @param request 4 * @param response 5 * @param jasperPath 例如:classpath:jasper/report2.jasper 6 * @param list JavaBean数据 7 * @param parameters 8 * @throws Exception 9 */ 10 public static void printPdf2HtmlByJavaBean(HttpServletRequest request, HttpServletResponse response,String jasperPath,Map<String, Object> parameters,List<?> list) throws Exception{ 11 12 ServletOutputStream outputStream = response.getOutputStream(); 13 14 15 //获取报表的编译文件,后面要将对其进行填充数据 16 InputStream inputStream = null; 17 try {// 如果不在jar包内,就能找到文件 18 String path = URLDecoder.decode(ResourceUtils.getURL(jasperPath).getPath(),"UTF-8"); 19 File file = new File(path); 20 inputStream = new FileInputStream(file); 21 parameters.put("SUBREPORT_DIR", file.getPath().replace(file.getName(), "")); 22 }catch(Exception e) {// 否则需要去jar包外找 23 String dirPath = FileCopyUtils.getCurrentDirPath()+File.separator; 24 String path = dirPath +jasperPath.replace("classpath:", ""); 25 try { 26 File file = new File(path); 27 inputStream = new FileInputStream(file); 28 parameters.put("SUBREPORT_DIR", file.getPath().replace(file.getName(), "")); 29 }catch(Exception e1) { 30 throw new RuntimeException(path+"不存在", e1); 31 } 32 } 33 34 35 //由于没有数据,故这里使用空参数和空数据源,该方法需要抛出JRException异常 36 JasperRunManager.runReportToPdfStream(inputStream, outputStream, parameters , new JRBeanCollectionDataSource(list)); 37 38 // 输出PDF 39 response.setContentType("application/pdf"); 40 41 // 关闭资源 42 outputStream.flush(); 43 outputStream.close(); 44 inputStream.close(); 45 46 }
15-32行代码是通过是否获取不到文件来判断是不是代码位于jar包内,如果在jar包内,则去同级目录查找资源,否则就去resource下查找,都查找不到就抛出异常提醒
获得jar包同级路径的代码如下:
1 /** 2 * 获取项目所在文件夹的绝对路径 3 * @return 4 */ 5 public static String getCurrentDirPath() { 6 URL url = FileCopyUtils.class.getProtectionDomain().getCodeSource().getLocation(); 7 String path = url.getPath(); 8 if(path.startsWith("file:")) { 9 path = path.replace("file:", ""); 10 } 11 if(path.contains(".jar!/")) { 12 path = path.substring(0, path.indexOf(".jar!/")+4); 13 } 14 15 File file = new File(path); 16 path = file.getParentFile().getAbsolutePath(); 17 return path; 18 }
5.更改数据库配置为生产服务器配置后,本地打包会报错;这是由于启动了测试代码,通过pom配置跳过测试即可
1 <properties> 2 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 3 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 4 <java.version>1.8</java.version> 5 <skipTests>true</skipTests> 6 </properties>
6.方便启动项目,在jar包同级目录下增加startup.bat并放置命令
1 java -jar XXX.jar
以后可以把jre环境也一起放置进去,然后增加命令行,这样就不要安装JDK,配置环境变量了