继上一篇博客--javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)
通過動態(tài)分配地址來提升javaweb文件下載接口的其兼容性和可擴(kuò)展性:
(上篇博文地址:https://blog.csdn.net/weixin_37766296/article/details/80044000)
log4j.properties?文件:
log4j.rootLogger = debug,stdout,D,Elog4j.logger.java.sql.ResultSet=INFOlog4j.logger.java.sql.apache=INFOlog4j.logger.java.sql.Connnection=DEGUGlog4j.logger.java.sql.Statement=DEGUGlog4j.logger.java.sql.PreparedStatement=DEGUGlog4j.appender.D = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.D.File = log4j.appender.D.Append = truelog4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayoutlog4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%nlog4j.appender.E = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.E.File = log4j.appender.E.Append = truelog4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayoutlog4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n你會發(fā)現(xiàn):
log4j.appender.D.File =
這里是空的,不急,容我慢慢解釋。
上面是日志文件的配置。下面是web.xml文件的配置:
<!-- log4j文件的配置 (千萬要注意的是下面的classes記得加上去,雖然工程目錄可能沒有,但是實(shí)際目錄可能是有的)--> <servlet> <servlet-name>lo4jInit</servlet-name> ()<servlet-class>com.fx.init.Lo4jInit</servlet-class> (這里要慎重,servlet類名:由package+class名組成)<init-param> <param-name>log4j_init_path</param-name> (這里是用來初始化的一些參數(shù),在init()方法中通過getInitParameter()方法獲得)<param-value>WEB-INF\classes\log4j.properties</param-value> (跟上面一個(gè)參數(shù)匹配,類似于一對鍵值對) </init-param> <load-on-startup>0</load-on-startup> </servlet>web容器啟動時(shí)是先 初始化web.xml文件,然后在根據(jù)web.xml中的配置進(jìn)行部署
接下來就是init()方法的實(shí)現(xiàn)了。。
最后附上download接口的實(shí)現(xiàn):(在之前一篇博文我有詳細(xì)介紹,這里就不詳細(xì)介紹了)
@Controller public class FilesController {@RequestMapping(value = "/download")public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {String zipBasePath = request.getSession().getServletContext().getRealPath("/logs");System.out.println("starting download...");/* 判斷文件夾是否有文件,遍歷文件夾中的文件。。。 */String path = zipBasePath;Vector<String> vecFile = new Vector<String>();recursion(path, vecFile);System.out.println("文件路徑分別是:");for (String fileName : vecFile) {System.out.println(fileName);}/* 設(shè)置下載文件的名稱 */String fileName = "logs.zip";response.setContentType("text/html; charset=UTF-8"); // 設(shè)置編碼字符response.setContentType("application/x-msdownload"); // 設(shè)置內(nèi)容類型為下載類型response.setHeader("Content-disposition", "attachment;filename=" + fileName);// 設(shè)置下載的文件名稱OutputStream out = response.getOutputStream(); // 創(chuàng)建頁返回方式為輸出流,會自動彈出下載框/* 創(chuàng)建壓縮文件需要的空的zip包 ,這里是自動生成的,不用我們自己去生成 */String zipFilePath = zipBasePath + "temp.zip";System.out.println("create the empty zip file successfully...");/* 根據(jù)臨時(shí)的zip壓縮包路徑,創(chuàng)建zip文件 */File zip = new File(zipFilePath);if (!zip.exists()) {zip.createNewFile();}System.out.println("create the zip file successfully...");/* 創(chuàng)建zip文件輸出流 */FileOutputStream fos = new FileOutputStream(zip);ZipOutputStream zos = new ZipOutputStream(fos);System.out.println("create the empty zip stream successfully....");/* 循環(huán)讀取文件路徑集合,獲取每一個(gè)文件的路徑(將文件一個(gè)一個(gè)進(jìn)行壓縮) */for (String fp : vecFile) {File f = new File(fp); // 根據(jù)文件路徑創(chuàng)建文件zipFile(f, zos); // 將每一個(gè)文件寫入zip文件包內(nèi),即進(jìn)行打包}zos.close();System.out.println("files zipped over, starting to download");/* 將打包后的文件寫到客戶端,有兩種方法可以實(shí)現(xiàn)(下面會進(jìn)行介紹),這里使用緩沖流輸出 */InputStream fis = new BufferedInputStream(new FileInputStream(zipFilePath));byte[] buff = new byte[4096];int size = 0;while ((size = fis.read(buff)) != -1) {out.write(buff, 0, size);}System.out.println("package is download successfully");// 釋放和關(guān)閉輸入輸出流out.flush();out.close();fis.close();}public void zipFile(File inputFile, ZipOutputStream zipoutputStream) {try {if (inputFile.exists()) { // 判斷文件是否存在if (inputFile.isFile()) { // 判斷是否屬于文件,還是文件夾// 創(chuàng)建輸入流讀取文件FileInputStream fis = new FileInputStream(inputFile);BufferedInputStream bis = new BufferedInputStream(fis);// 將文件寫入zip內(nèi),即將文件進(jìn)行打包ZipEntry ze = new ZipEntry(inputFile.getName()); // 獲取文件名zipoutputStream.putNextEntry(ze);// 寫入文件的方法,同上byte[] b = new byte[1024];long l = 0;while (l < inputFile.length()) {int j = bis.read(b, 0, 1024);l += j;zipoutputStream.write(b, 0, j);}// 關(guān)閉輸入輸出流bis.close();fis.close();} else { // 如果是文件夾,則使用窮舉的方法獲取文件,寫入ziptry {File[] files = inputFile.listFiles();for (int i = 0; i < files.length; i++) {zipFile(files[i], zipoutputStream);}} catch (Exception e) {e.printStackTrace();}}}} catch (Exception e) {e.printStackTrace();}}public void recursion(String root, Vector<String> vecFile) {String path = root;File file = new File(root);if (file.exists()) {System.out.println("this file is exit!");File[] subFile = file.listFiles();for (int i = 0; i < subFile.length; i++) {if (subFile[i].isDirectory()) {recursion(subFile[i].getAbsolutePath(), vecFile);} else {String filename = subFile[i].getName();vecFile.add(path + File.separator + filename);}}} else {System.out.println("this file is not exit!");}}}最后總結(jié)一下編程過程中遇到一些困難以及解決方法:
1. 在編寫Spring的applicationContext.xml文件時(shí),無緣無故出現(xiàn)了:
cvc-complex-type.2.3: Element 'beans' cannot have character [children], because the type's content type is element-only.錯(cuò)誤。
錯(cuò)誤原因:Spring在初始化的時(shí)候無法識別applicationContext.xml中的元素。
可能產(chǎn)生該錯(cuò)誤的原因:網(wǎng)上復(fù)制的代碼直接粘貼到了xml文件中,而網(wǎng)上的代碼可能不符合xml規(guī)范
解決辦法:1.去掉xml文件中的中文注解,因?yàn)閺?fù)制的有些注解Spring不能識別。?
? ? ? ? ? ? ? ? ? 2.若仍然有錯(cuò),則嘗試修改多余的空格,因?yàn)橹形目崭馭pring有可能識別錯(cuò)誤。
? ? ? ? ? ? ? ? ? 3.最后的絕招:重新手動抄寫一遍文件內(nèi)容,保存。
參考博文:https://blog.csdn.net/mafan121/article/details/43266733
2.?在配置web.xml?文件中對配置的元素不是很熟悉:
????????可以看到,在配置Servlet時(shí),有兩個(gè)地方需要配置,一個(gè)是<servlet>,另一個(gè)是<servlet-Mapping>,這兩個(gè)一個(gè)是配置Servlet,一個(gè)是配置其映射信息,其中<servlet>中的<servlet-name>可以隨意指定,但要有一定的意義,一般取為類的名稱,例如我的類名為ServletDemo,這里取名為ServletDemo,下面的<servlet-class>是類的全路徑,package+classname,一定要是全路徑!
????????<servlet-Mapping>是映射信息,它也有一個(gè)<servlet-name>,里面的名字是對應(yīng)的Servlet名,也就是我們上面配置的Servlet名字,這里是ServletDemo,下面的是映射路徑,也就是訪問Servlet的名稱,這里也是以方便和有意義為前提的,是我們在訪問Servlet在瀏覽器地址欄后面輸入的那個(gè)信息,例如我的映射路徑命名為/servlet,在地址欄中輸入http://localhost:8080/servlet
注意:這里的映射路徑一定不能丟掉/,否則就會出錯(cuò)了,一定要寫成/servlet,不能是servlet。
參考博文:https://blog.csdn.net/m0_37630602/article/details/65443660
3.?
eclipse項(xiàng)目一直顯示有錯(cuò),但是一直找不到錯(cuò)誤在哪里
這天在寫項(xiàng)目的時(shí)候碰到了這么個(gè)問題,項(xiàng)目上一直提示著紅叉,但不管是文件里還是java buildpath里都找不到報(bào)錯(cuò),然后我就郁悶了。
后來給我找到一個(gè)解決方案,能查看當(dāng)前錯(cuò)誤是什么:?
eclipse–>Window–>show View–>Markers,出現(xiàn)一個(gè)面板,然后在這個(gè)面板里就能查看到底是什么在出錯(cuò)啦。
參考博文:https://blog.csdn.net/zhagzheguo/article/details/51660908
4.?
參考博文:http://lpcjrflsa.iteye.com/blog/1101796(Log4j日志文件輸出為相對路徑的解決方法)總結(jié)
以上是生活随笔為你收集整理的继上一篇博客--javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言死锁算法实验报告,死锁实验报告
- 下一篇: spring源码分析第五天------s