Java技巧:怎样从servlet打开一个非html文件

    技术2022-05-11  60

    1、摘要

    Java Servlet 程序提供了一个简单的方式发送HTML文件到客户端浏览器。但是,现在一些站点提供了一些非HTML的存取文件,例如Adobe PDFMicrosoft Word, Microsoft Excel 文件等。这篇文章以使用PDFWORD为例子讲解怎样从SERVLET发送一个非HTML文件到客户端浏览器。事实上,通过本文,你可以通过MIME类型发送任何的格式的文件。同时,也能了解到通过SERVLET怎样与防火墙进行交互。

          通过一个SERVLET在浏览器中打开一个文件,你只需简单的把这个文件加入到SERVLET的输出流中。尽管这么做看起来很简单,但是当你打开一个非HTML文件时你必须需要一些事情,例如二进制文件和多个文件的问题。

          你可以通过一下方式得到SERVLET输出流:

    ServletOutputStream out = res.getOutputStream();

    互联网通过MIME(多用途网络邮件扩展)协议发送多部分,多媒体和二进制文件。在SERVLET的RESPONSE对象中,设置你想打开的文件的MIME类型是非常重要的。

    2、MIME类型

        客户端浏览器通过MIME类型来识别非HTML文件和决定用什么包容器来呈现这个数据文件。插件能够通过MIME类型来决定用什么方式来打开这些文件,当我们下载这些文件以后,我们通过浏览器就可以浏览这些文件了。

        MIME类型很有用,他们允许浏览器通过内置技术处理不同的文件类型。

        MIME类型对于一个PDF文件是"application/pdf"。当在SERVLET打开一个PDF文件时,你必须在RESPONSE最前面设置"application/pdf"

    // MIME type for pdf doc    res.setContentType( "application/pdf" ); 

    打开一个WORD文档,你应该设置成"application/msword":

    // MIME type for MSWord doc    res.setContentType( "application/msword" );

    对于EXCEL文档,使用MIME类型是"application/vnd.ms-excel"。如果需要的插件系统没有没有安装,浏览器会出现一个提示框,询问用户是否在当前位置打开还是保存到磁盘上。

    3、内容部署

          部署内容的HTTP response 头允许servlet指定文件类型的信息。使用这个头说明,你可以制定特定的方式来打开这个文件(不仅仅在浏览器中),而且它不应该自动的显示。你可以设置要保存的文件名。这个文件应该是对话框中显示的文件名。如果你不想指定文件名,你得到的是你的servlet同名的文件名称。

          SERVLET中你可以象下面的代码一样来设置头

    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.

    如果你想打开一个WORD文件,应该如下做:

    res.setHeader("Content-disposition",                  "attachment; filename" +                  "Example.doc" );

    4、封装

           剩下的工作就很简单了。你需要基于你想打开的文件的名字创建一个java.net.URL对象。这个字符串应该完整的指出这个文件的位置。举例说明:

    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这个样子。

        但是你必须确认你所打开的文件与你MIME类型中指定的文件类型一定要一致。

    URL url = new URL ( fileURL );

    5、防火墙

        如果你的浏览器需要通过防火墙,最后的一件事情就是你需要担心的就是你的URL连接了。你需要找出一些你的代理服务器的一些信息,例如主机名称和端口号去与防火墙建立连接。如果你使用JAVA 2,你应该创建一个URL连接对象,设置以下的系统属性:

    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 " + newsun.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你可以不用建立系统属性。你应该用你的代理服务器信息创建JAVA.NET.URL对象。

    url = new URL("http", PROXY_HOST,                  Integer.parseInt(PROXY_PORT),                  fileURL );    // assumes authentication is not required

    6、实现

        在开始读取你得文件的时候,你需要从URLConnection (or URL)对象中包含InputStream。   

           在以下的例子中,你用一个BufferedInputStream来限制这个InputStream。

        如果你正在使用这个URLConnection,以下就是这样的代码:

    BufferedInputStream  bis = new BufferedInputStream(conn.getInputStream());

    如果你正在使用URL,那就象以下的代码:

    BufferedInputStream  bis = new BufferedInputStream(url.openStream());

    一旦做完以上工作,你只需简单的从输入流写出每一个字节到servlet的输出流中

    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);    }

    最后,在最后的模块中关闭这个流。

    这个例子通过使用一个servlet的doPost方法来实现这个功能。

    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();    }}

    7、总结

        正如你所看到的,在一个servlet中打开一个非HTML是很简单的,甚至在一个防火墙之外。你可以使用同样的代码打开图像文件或者其他类型的多媒体文件,只要正确设置MIME类型。今天,在互联网上更多的信息都变得有效了,并且其中大量的信息是以非HTML类型存储的。相比之下,开发一个servlet来呈现非HTML文档是一件容易,方便的方式来提供给你的用户更多的信息。

     


    最新回复(0)