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

原创 2003年06月17日 11:18:00

1、摘要 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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 " + 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你可以不用建立系统属性。你应该用你的代理服务器信息创建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文档是一件容易,方便的方式来提供给你的用户更多的信息。

 

HTML from 表单提交请求到servlet 实例

HTML源码展示: div#container{width:100%;} div#menu {background-color:#e2e6ee;height:500px;width:50%...
  • zhouzhiwengang
  • zhouzhiwengang
  • 2014年03月19日 12:36
  • 1916

html页面提交数据,利用servlet接收数据并写进xml中

需求如下: * 需求 * 完成用户注册效果。 具体要求: 1)用户输入信息:用户名,密码,确认密码,性别,出生日期,电子邮箱,地址 。 2)用户输入信息后,调用相关的XML操作类,把数据保...
  • starjuly
  • starjuly
  • 2016年07月20日 00:46
  • 4522

Servlet流操作——在浏览器中打开或者下载PDF文件

在Servlet与客户的请求应答的过程中,底层是通过输入/输出流来实现的。Servlet支持两种格式的输入/输出流。一个是字符输入/输出流。ServletResponse的getWriter()方法返...
  • yanglun1
  • yanglun1
  • 2015年06月14日 13:12
  • 6040

servlet 读取相对路径 读取本地文件

比如要读取“index”文件夹下的文件,那么这个文件夹需要放在webroot目录下,如图所示: 这个目录是Myeclipse的工作目录。只有将此文件夹放在这里,该文件才能被读到t...
  • dudfur
  • dudfur
  • 2013年03月29日 11:05
  • 1245

servlet+jdbc+html+jquery+Mysql数据库(基于MVC的简单查询系统)

一个servlect,jdbc完成后台查询前台展示
  • lyc971705
  • lyc971705
  • 2017年08月02日 10:03
  • 287

html中调用本地exe程序 打开文件或文件夹

和刚发的右键新建html文章一样,这个都是以前搞的。最近为自己做个单页应用,跟浏览器书签一样的,网址+描述,保存到数据库。然后想将一些自己常用的其他文件和文件夹放过来,能快速打开。 这就是我的需求。起...
  • ruanjiayou123
  • ruanjiayou123
  • 2016年04月30日 00:27
  • 3489

解决java动态生成html文档为乱码的问题

在eclipse中用java动态生成html文件,出现了乱码的情况。如下图所示:       进行问题的排查,我进行了一下步骤:    1、查看一下我所在工程的编码格式:           打开Pr...
  • xixiruyiruyi
  • xixiruyiruyi
  • 2016年12月05日 14:47
  • 2589

html页面打开另一个html页面

1、传统ifream方式 Iframe标记的使用格式是: src:文件的路径,既可是HTML文件,也可以是文本、ASP等;   width、height:"...
  • nvzizhou
  • nvzizhou
  • 2016年04月18日 15:16
  • 3291

Linux文件编程

linux中文件编程
  • shuyingcanyueye
  • shuyingcanyueye
  • 2017年02月10日 22:38
  • 97

超详细servlet+jdbc+html+css实现后台管理登陆

servlet+jdbc+html+css实现后台管理登陆咱们这篇文章继续上篇文章的完善。先给大家看看效果图吧! 这个简介的界面,大家可以自己去加以修改完善。 好了,开始步入正题。 这个we...
  • qq_21004057
  • qq_21004057
  • 2016年05月01日 14:34
  • 10987
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java技巧:怎样从servlet打开一个非html文件
举报原因:
原因补充:

(最多只允许输入30个字)