六、xml文件生成與zip打包
在這一步,包含三個步驟:首先查詢數據庫,取得所有相關數據;其次調用xml的API構造一個xml文檔並輸出;最後將xml的輸出流打包到一個zip文件中。
- xml操作API
這裏撇開DOM和SAX兩種xml解析方式的異同不談,我們使用的是dom4j工具包[7]。它能方便地構造一個xml文檔(文檔根/節點/屬性等),並且能夠輸出到一個用戶指定的輸出流中。
Document doc = DocumentHelper.createDocument();
Element SSTR = doc.addElement("SSTR");
...
- 輸出xml文檔
public OutputStream writeXmlFile(OutputStream os, Document doc) {
try {
// 定製美化格式或緊湊格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 必須用OutputStreamWriter加字符集的方式,否則用OutputStream直接寫入會產生亂碼!!!
// java默認用utf-8的方式寫入字節流
OutputStreamWriter osw = new OutputStreamWriter(os, "gb18030");
XMLWriter output = new XMLWriter(osw, format);
format.setEncoding("gb18030"); // 聲明字符集
// 文件輸出並關閉輸出流
output.write(doc);
output.close();
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
return os;
}
注意:寫xml文檔是要用Writer即字符流的方式,否則用OutputStream字節流的輸出方式,中文字符會亂碼!!!(折騰一個下午才搞定)
- zip文件打包
因爲要將xml打包到zip文件中,所以採用了java.io.zip包(如果被打包文件是中文名可能會亂碼,那麼就用apache上提供的zip包)。
// 目前規定:一個zip文件中包含一個xml文件,os一般爲一個ServletOutputStream(作爲附件下載)
public void outputZipFile(OutputStream os) {
try {
ZipOutputStream zipOS = new ZipOutputStream(os, "gb18030"); // zip輸出流,解決中文輸出問題
// 將xml文件添加到zip壓縮項中
zipOS.putNextEntry(new ZipEntry(xmlFileName));
writeXmlFile(zipOS, xmlDocument); // 寫xml文件到ZipOutputStream中
zipOS.closeEntry();
// 關閉輸入輸出流
zipOS.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
- 獲取response對象並寫zip文件到ServletOutputStream對象中
HttpServletResponse response = (HttpServletResponse) FacesContext
.getCurrentInstance().getExternalContext().getResponse();
// 填充輸出流
ServletOutputStream sos = response.getOutputStream();
gen.outputZipFile(sos);
sos.flush();