怎么用 servlet 打開(kāi)非 HTML 格式的文檔
發(fā)表時(shí)間:2023-07-31 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]如何用 servlet 打開(kāi)非 HTML 格式的文檔一種向 Web 客戶端發(fā)送非 HTML 格式文檔的簡(jiǎn)單方法摘要Java Servlet 編程可以很方便地將 HTML 文件發(fā)送到客戶端 Web 瀏...
如何用 servlet 打開(kāi)非 HTML 格式的文檔
一種向 Web 客戶端發(fā)送非 HTML 格式文檔的簡(jiǎn)單方法
摘要
Java Servlet 編程可以很方便地將 HTML 文件發(fā)送到客戶端 Web 瀏覽器。然而許多站點(diǎn)還允許訪問(wèn)非 HTML 格式的文檔,包括 Adobe PDF、Microsoft Word 和 Micorsoft Excel 等。事實(shí)上這些非 HTML 格式只要能用 MIME 類型表示,就可以利用 servlet 來(lái)發(fā)送。本文將以 PDF 和 Microsoft Word 文件為例,向你介紹如何使用 servlet 傳送非 HTML 格式文件,以及與防火墻交互的方法。
你只要將文件寫到 servlet 的輸出流中,就可以利用 servlet 在瀏覽器中打開(kāi)一個(gè)文件。盡管這看起來(lái)非常簡(jiǎn)單,在打開(kāi)非 HTML 格式文檔(比如二進(jìn)制數(shù)據(jù)或多媒體文件)的時(shí)候,仍要注意一些要點(diǎn)。
首先從獲得 servlet 的輸出流開(kāi)始:
ServletOutputStream out = res.getOutputStream();
互聯(lián)網(wǎng)上使用 MIME (multipurpos Internet mail extension 多目的互聯(lián)網(wǎng)郵件擴(kuò)展協(xié)議)來(lái)傳送混合格式、多媒體和二進(jìn)制數(shù)據(jù)文件。如果要在 servlet 的 response 對(duì)象中打開(kāi)某個(gè)文檔,就必須設(shè)置該文檔的 MIME 類型。下面這個(gè)例子中我們將打開(kāi) PDF 文檔。
MIME 類型
Web 瀏覽器使用 MIME 類型來(lái)識(shí)別非 HTML 文檔,并決定如何顯示該文檔內(nèi)的數(shù)據(jù)。將插件 (plug-in) 與 MIME 類型結(jié)合使用,則當(dāng) Web 瀏覽器下載 MIME 類型指示的文檔時(shí),就能夠啟動(dòng)相應(yīng)插件處理此文檔。某些 MIME 類型還可以與外部程序結(jié)合使用,瀏覽器下載文檔后會(huì)啟動(dòng)相應(yīng)的外部程序。
MIME 類型非常有用。它們?cè)试S Web 瀏覽器處理不同格式的文檔,卻不需要事先嵌入相關(guān)知識(shí)。Java Servlets 可以使用 MIME 類型來(lái)向?yàn)g覽器傳送非 HTML 文件,比如 Adobe PDF 和 Micorsoft Word。使用正確的 MIME 類型能夠保證這些非 HTML 文件被正確的插件或外部程序顯示。本文末的資料部分提供了一些網(wǎng)址,指向一些已定義 MIME 類型列表和關(guān)于 MIME 類型的文章。
PDF 文件的 MIME 類型是 "application/pdf"。要用 servlet 來(lái)打開(kāi)一個(gè) PDF 文檔,需要將 response 對(duì)象中 header 的 content 類型設(shè)置成 "application/pdf":
// MIME type for pdf doc
res.setContentType( "application/pdf" );
若要打開(kāi)一個(gè) Microsoft Word 文檔,你就要將 response 對(duì)象的 content 類型設(shè)置成 "application/msword":
// MIME type for MSWord doc
res.setContentType( "application/msword" );
如果是一個(gè) Excel 文檔,則使用 MIME 類型 "application/vnd.ms-excel"。其中 vnd 表示該應(yīng)用程序的制造者,必須將它包含在 MIME 類型里才能夠打開(kāi)該類型文檔。
有時(shí)候?yàn)g覽器不能識(shí)別文檔的 MIME 類型。通常這是由于沒(méi)有安裝這些文檔需要的插件而導(dǎo)致的。這種情況下,瀏覽器會(huì)彈出一個(gè)對(duì)話框,詢問(wèn)用戶是否需要打開(kāi)該文件或是將它保存到本地磁盤上。
Content disposition
一種叫做 content-disposition 的 HTTP response header 允許 servlet 指定文檔表示的信息。使用這種 header ,你就可以將文檔指定成單獨(dú)打開(kāi)(而不是在瀏覽器中打開(kāi)),還可以根據(jù)用戶的操作來(lái)顯示。如果用戶要保存文檔,你還可以為該文檔建議一個(gè)文件名。這個(gè)建議名稱會(huì)出現(xiàn)在 Save As 對(duì)話框的“文件名”欄中。如果沒(méi)有指定,則對(duì)話框中就會(huì)出現(xiàn) servlet 的名字。更多關(guān)于 content-disposition header 的信息,可以參閱資料。
在 servlet 中,你需要將 header 設(shè)置成下面這樣:
res.setHeader("Content-disposition",
"attachment; filename=" +
"Example.pdf" );
// attachment - since we don't want to open
// it in the browser, but
// with Adobe Acrobat, and set the
// default file name to use.
如果你要打開(kāi)的是 Microsoft Word 文件,你可以設(shè)成:
res.setHeader("Content-disposition",
"attachment; filename" +
"Example.doc" );
封裝非 HTML 文檔
完成上述工作后,剩下的就非常簡(jiǎn)單了。你需要根據(jù)待傳送文件的名字,創(chuàng)建一個(gè) java.net.URL 對(duì)象。交給 URL 構(gòu)造器的字符串必須是指向該文件的一個(gè)有效 URL 地址。在這個(gè)例子中,我要打開(kāi) Adobe employment 格式的文檔:
String fileURL =
"http://www.adobe.com/aboutadobe/careeropp/pdfs/adobeapp.pdf;"
你的 URL 字符串也可以類似于 http://www.gr.com/pub/somefile.doc 或 http://www.gr.com/pub/somefile.xls。但必須確保待傳送文件類型與先前在 HTTP response 對(duì)象中設(shè)置的 MIME 類型一致。
URL url = new URL ( fileURL );
防火墻
如果需要通過(guò)防火墻,最后一件要考慮的事情就是你的 URL 鏈接。首先應(yīng)當(dāng)搜集所用代理服務(wù)器的相關(guān)信息,例如主機(jī)名稱和端口號(hào)等。更多關(guān)于如何通過(guò)防火墻建立鏈接的信息,可以參看下面的資料部分。
如果使用的是 Java 2,你應(yīng)該從 URL 對(duì)象類中創(chuàng)建一個(gè) URLConnection 對(duì)象,并設(shè)置下列系統(tǒng)屬性:
URLConnection conn = url.openConnection();
// Use the username and password you use to
// connect to the outside world
// if your proxy server requires authentication.
String authentication = "Basic " + new
sun.misc.BASE64Encoder().encode("username:password".getBytes());
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", PROXY_HOST); // your proxy host
System.getProperties().put("proxyPort", PROXY_PORT); // your proxy port
conn.setRequestProperty("Proxy-Authorization", authentication);
如果你使用的是 JDK 1.1,則不能設(shè)置這些系統(tǒng)屬性。這種情況下,你可以根據(jù)所用代理服務(wù)器的信息創(chuàng)建 java.net.URL 對(duì)象:
url = new URL("http", PROXY_HOST,
Integer.parseInt(PROXY_PORT),
fileURL );
// assumes authentication is not required
深入工作
開(kāi)始閱讀你傳送的文檔之前,首先要從 URLConnection (或 URL) 對(duì)象中獲得輸入流 InputStream。在這個(gè)例子中,用 BufferedInputStream 將 InputStream 封裝起來(lái)。
如果你采用 URLConnection,可以嘗試如下代碼:
BufferedInputStream bis = new
BufferedInputStream(conn.getInputStream());
如果你使用 URL,則可用下列代碼:
BufferedInputStream bis = new
BufferedInputStream(url.openStream());
一旦你完成上述操作,就只要簡(jiǎn)單地將 InputStream 中的字節(jié),寫入到 servlet 的輸出流 OutputStream 中:
BufferedOutputStream bos = new
BufferedOutputStream(out);
byte[] buff = new byte[2048];
int bytesRead;
// Simple read/write loop.
while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
在最后的代碼塊中,關(guān)閉這些流。
這個(gè)例子是利用 doPost 來(lái)實(shí)現(xiàn)的(doPost 是 HttpServlet 子類的一個(gè)方法):
public void doPost(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
ServletOutputStream out =
res.getOutputStream ();
//---------------------------------------------------------------
// Set the output data's mime type
//---------------------------------------------------------------
res.setContentType( "application/pdf" ); // MIME type for pdf doc
//---------------------------------------------------------------
// create an input stream from fileURL
//---------------------------------------------------------------
String fileURL =
"http://www.adobe.com/aboutadobe/careeropp/pdfs/adobeapp.pdf";
//------------------------------------------------------------
// Content-disposition header - don't open in browser and
// set the "Save As..." filename.
// *There is reportedly a bug in IE4.0 which ignores this...
//------------------------------------------------------------
res.setHeader("Content-disposition",
"attachment; filename=" +=
"Example.pdf" );
//-----------------------------------------------------------------
// PROXY_HOST and PROXY_PORT should be your proxy host and port
// that will let you go through the firewall without authentication.
// Otherwise set the system properties and use URLConnection.getInputStream().
//-----------------------------------------------------------------
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
URL url = new URL( "http", PROXY_HOST,
Integer.parseInt(PROXY_PORT), fileURL );
// Use Buffered Stream for reading/writing.
bis = new BufferedInputStream(url.openStream());
bos = new BufferedOutputStream(out);
byte[] buff = new byte[2048];
int bytesRead;
// Simple read/write loop.
while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch(final MalformedURLException e) {
System.out.println ( "MalformedURLException." );
throw e;
} catch(final IOException e) {
System.out.println ( "IOException." );
throw e;
} finally {
if (bis != null)
bis.close();
if (bos != null)
bos.close();
}
}
結(jié)論
正如你所讀到的,用 servlet 來(lái)打開(kāi)非 html 文檔相當(dāng)簡(jiǎn)單。即使是要通過(guò)防火墻也是如此。只要設(shè)置了正確的 MIME 類型,就可以使用同樣的代碼來(lái)打開(kāi)圖片或其他多媒體文件。當(dāng)今的互聯(lián)網(wǎng)上包含了大量信息,其中許多數(shù)據(jù)被存儲(chǔ)為非 HTML 格式。使用 servlet 能夠克服 HTML 的限制,簡(jiǎn)單方便地向用戶傳送這些非 HTML 格式的信息。