- 浏览: 175276 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (157)
- j2se (6)
- 网络安全 (11)
- java (28)
- spring (0)
- Struts2 (2)
- hibernate (1)
- Dwr (0)
- ajax (3)
- flash (0)
- 文学&&小说 (1)
- 火车头 (1)
- 小软件 (13)
- 数据挖掘 (1)
- 搜索 (4)
- Java开源项目 (9)
- javaweb 服务器 (0)
- 经典教程 (12)
- php (1)
- web roller (4)
- Lucene (1)
- 普索网 (1)
- Javascript (2)
- 普索网【Vim】 (0)
- Ftp (0)
- log4j (1)
- j2se【pusuo】 (1)
- fdsfdsfsadfasfsa (0)
- b (0)
- c (0)
- f (0)
- cc (0)
- ddd (1)
最新评论
这些说起来是入门级的东西,但没有几个人真的知道.
要输出一个excel,内容当然是你自己的逻辑,但MIME要非常熟悉.
<%@page contentType="application/msexcel"%>
<%
response.setHeader("Content-disposition", "inline;filename=test.xls");
%>
inline是内联方式,也就是在当前文档中打开.如果是IE就是在IE窗口中打开这个文档,如果是email就是内嵌在邮件中而不是作为附件.
如果要下载,则描述符为:attachment,邮件中就是附件,IE中就是下载
TestFileDownload.JSP页面的例子:
<%
// 得到文件名字和路径
String filename = ”MengxianhuiDocTest.doc”;
String filepath = ”D:\\”;
// 设置响应头和下载保存的文件名
response.setContentType(”APPLICATION/OCTET-STREAM”);
response.setHeader(”Content-Disposition”,
”attachment; filename=\”” + filename + ”\””);
// 打开指定文件的流信息
java.io.FileInputStream fileInputStream =
new java.io.FileInputStream(filepath + filename);
// 写出流信息
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
out.close();
%>;
值得注意的是:在你要下载的文件内容里,除了文件的内容之外,不应该再附加有其它任何的字符,包括空格和回车换行符。我们有时在编写代码的时候,为了使代码清晰可读,往往会添加一些空格、制表符或者回车换行符,这样虽然看起来比较清晰,但有时可能会得不到正确的结果。比如:
<%@ page import=”java.io.*”
%>; <jsp:useBean id=”MyBeanFromMengxianhui” scope=”page”
class=”com.Mengxianhui.DownloadBean” />;
应该写成这样:
<%@ page import=”java.io.*”
%>;<jsp:useBean id=”MyBeanFromMengxianhui” scope=”page”
class=”com.Mengxianhui.DownloadBean” />;
--------------------------------------------------------------------------------
eclipse 回复于:2002-10-18 12:13:21
请注意:APPLICATION/OCTET-STREAM是设置下载类型
要改成你实际的类型,如excel要写成:application/vnd.ms-excel
--------------------------------------------------------------------------------
eclipse 回复于:2002-10-18 12:17:39
如果不用jspsmart,你就需要了解浏览器端的编码方式,在传到服务器端时你才能解码。也才可以得到上传文件的相关信息。看下面的代码。
package mshtang.fileUpload;
import java.io.*;
/**一个存放文件信息的类,包括文件的名称(String),
**字段名(String), Content-Type(String)和内容(byte[])
**还提供了一个直接将文件内容保存到一个文件的函数 void saveTo(File f)
**可以调用 类{@link ContentFactory}中的适当方法,生成该类的实例。
** @see ContentFactory
** @see ContentFactory#getFileParameter
** @see ContentFactory#getFileParameterValues
**/
public class FileHolder
{
String contentType;
byte[] buffer;
String fileName;
String parameterName;
FileHolder(byte[] buffer, String contentType, String fileName, String parameterName)
{
this.buffer = buffer;
this.contentType = contentType;
this.fileName = fileName;
this.parameterName = parameterName;
}
/**把文件的内容存到指定的文件中,
**<b>;这个方法不会检查这个文件是否可写、是否已经存在。</b>;
**@param file 目的文件
**@throws 在 I/O 操作中被抛出的 IOException
**/
public void saveTo(File file) throws IOException
{
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
out.write(buffer);
out.close();
}
/**把文件的内容存到指定的文件中,
**<b>;这个方法不会检查这个文件是否可写、是否已经存在。</b>;
**@param name 目的文件名
**@throws 在 I/O 操作中被抛出的 IOException
**/
public void saveTo(String name) throws IOException
{
saveTo(new File(name));
}
/**
**返回一个文件内容的字节数组
**@return 一个代表文件内容的字节数组
**/
public byte[] getBytes()
{
return buffer;
}
/**
**返回该文件在文件上载前在客户端的名称
**@return 该文件在文件上载前在客户端的名称
**/
public String getFileName()
{
return fileName;
}
/**
**返回该文件的 Content-Type
**@return 该文件的 Content-Type
**/
public String getContentType()
{
return contentType;
}
/**
**返回上载该文件时,Html 页面窗体中 file 控件的 name 属性
**@return 返回上载该文件时,Html 页面窗体中 file 控件的 name 属性
**/
public String getParameterName()
{
return parameterName;
}
}
package mshtang.fileUpload;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
/**存放报文内容的类,提供类似于 ServletRequest 中的部分 get 方法
*你必须在 html 页面的窗体(form)中指定 enctype="multipart/form-data"。
*才可以正确的使用这个类。
**/
public class ContentFactory
{
private Hashtable values; //存放name=value,其中value存放在另一个类中
private Hashtable files; //存放文件内容的。
private ContentFactory(Hashtable values, Hashtable files)
{
this.values=values;
this.files=files;
}
public String getParameter(String name)
{
Vector v = (Vector)values.get(name);
if( v != null)
{
return (String)v.elementAt(0);
}
return null;
}
public Enumeration getParameterNames()
{
return values.keys();
}
public String[] getParameterValues(String name)
{
Vector v = (Vector)values.get(name);
if(v != null)
{
String[] result = new String[v.size()];
v.toArray(result);
return result;
}
return new String[0];
}
/**
*返回一个 FileHolder 实例,该实例包含了通过字段名为name的file控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择上载的文件,则返回 null。
* <p>;如果 Html 页面中存在不止一个字段名为name的file控件,
* 返回值等于{@link #getFileParameterValues}中的第一个元素。
*
* @param name:一个<code>;String</code>;,对应于Html页面窗体中file控件
*的name 属性。
*
* @return返回:一个 FileHolder 实例,该实例包含了通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面是,没有选择上载的文件,则返回 null。
*
* @see #getFileParameterValues
*
*/
public FileHolder getFileParameter(String name)
{
Vector v = (Vector)files.get(name);
if(v != null)
{
return (FileHolder)v.elementAt(0);
}
return null;
}
/**
* 返回一个 由 String 对象构成的 Enumeration ,包含了 Html 页面
*窗体中所有 file 控件的 name 属性。
*如果窗体中没有 file 控件,则返回一个空的 Enumeration
* @return 返回一个 由 String 对象构成的 Enumeration ,包含了 Html 页面
*窗体中所有 file 控件的 name 属性。
*如果窗体中没有 file 控件,则返回一个空的 Enumeration
*/
public Enumeration getFileParameterNames()
{
return files.keys();
}
/**
*返回一个 FileHolder 数组,该数组包含了所有通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择任何上载的文件,则返回一个 零元素的数组(不是 null )。
* @param name 一个 <code>;String</code>; ,对应于 Html 页面窗体中 file 控件
*的name 属性。
*
* @return 返回一个 FileHolder 数组,该数组包含了所有通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择任何上载的文件,则返回一个 零元素的数组(不是 null )。
*
* @see #getFileParameter
*/
public FileHolder[] getFileParameterValues(String name)
{
Vector v=(Vector)files.get(name);
if(v!=null)
{
FileHolder[] result=new FileHolder[v.size()];
v.toArray(result);
return result;
}
return new FileHolder[0];
}
//------------->;Factory 部分
/**
**返回根据当前请求生成的一个 ContentFactory 实例
**@param request 提交的请求
**@return 返回根据当前请求生成的一个 ContentFactory 实例,如果 request
数据包的内容不是以 mutilpart/form-data 型编码,则返回 null。
**@throws ContentFactoryException 当提交的数据和文件太大时抛出,
**根据 Content-Length 判断,默认的许可值为 1024* 1024。
**/
public static ContentFactory getContentFactory(HttpServletRequest request) throws ContentFactoryException,IOException
{
// default maxLength is 1MB.
return getContentFactory(request, 1024*1024);
}
/**
**返回根据当前请求生成的一个 ContentFactory 实例
**@param request 提交的请求
**@param maxLength 数据包的最大长度,默认为1024*1024
**@return 返回根据当前请求生成的一个 ContentFactory 实例,如果 request
数据包的内容不是以 mutilpart/form-data 型编码,则返回 null。
**@throws ContentFactoryException 当提交的数据和文件太大时抛出,
**根据 Content-Length 判断,默认的许可值为 1024* 1024。
**/
public static ContentFactory getContentFactory(HttpServletRequest request, int maxLength) throws ContentFactoryException, IOException
{
Hashtable values = new Hashtable();
Hashtable files = new Hashtable();
String contentType = request.getContentType();
int contentLength = request.getContentLength();
if (contentLength >; maxLength)
{
ContentFactoryException e=new ContentFactoryException("上传数据太多,请不要选择太大的文件");
throw e;
}
if(contentType == null || !contentType.startsWith("multipart/form-data"))
{
return null;
}
//get out the boudary from content-type
int start = contentType.indexOf("boundary=");
//这里应该
int boundaryLen = new String("boundary=").length();
String boundary = contentType.substring(start + boundaryLen);
boundary = "--" + boundary;
//用字节表示,以免 String 和 byte 数组的长度不一致
boundaryLen = bytesLen(boundary);
//把request 中的数据读入一个byte数组
byte buffer[] = new byte[contentLength];
int once = 0;
int total = 0;
DataInputStream in = new DataInputStream(request.getInputStream());
while((total < contentLength) && (once >;= 0))
{
once = in.read(buffer, total, contentLength);
total += once;
}
//对buffer中的数据进行拆分
int pos1 = 0; //pos1 记录 在buffer 中下一个 boundary 的位置
//pos0,pos1 用于 subBytes 的两个参数
int pos0 = byteIndexOf(buffer, boundary, 0);//pos0 记录 boundary 的第一个字节在buffer 中的位置
do
{
pos0 += boundaryLen; //记录boundary后面第一个字节的下标
pos1 = byteIndexOf(buffer, boundary, pos0);
if(pos1==-1)
{
break;
}//
pos0 += 2;//考虑到boundary后面的 \r\n
parse(subBytes(buffer, pos0, pos1-2), values, files); //考虑到boundary后面的\r\n
pos0=pos1;
}while(true);
return new ContentFactory(values,files);
}
private static void parse(byte[] buffer, Hashtable values, Hashtable files)
{
/* this is a smiple to parse
[boundary]
Content-Disposition: form-data; name="file3"; filename="C:\Autoexec.bat"
Content-Type: application/octet-stream
@echo off
prompt $d $t [ $p ]$_$$
[boundary]
Content-Disposition: form-data; name="Submit"
Submit
[boundary]
*/
String[] tokens={"name=\"","\"; filename=\"", "\"\r\n","Content-Type: ","\r\n\r\n"};
// 0 1 2 3 4
int[] position=new int[tokens.length];
for (int i=0;i<tokens.length ;i++ )
{
position=byteIndexOf(buffer,tokens,0);
}
if (position[1]>;0 && position[1]<position[2])
{
//包含tokens 中的第二个元素,说明是个文件数据段
//1.得到字段名
String name =subBytesString(buffer,position[0]+bytesLen(tokens[0]),position[1]);
//2.得到文件名
String file= subBytesString(buffer,position[1]+bytesLen(tokens[1]),position[2]);
if (file.equals("")) return;
file=new File(file).getName(); //this is the way to get the name from a path string
//3.得到 Content-Type
String contentType=subBytesString(buffer,position[3]+bytesLen(tokens[3]),position[4]);
//4.得到文件内容
byte[] b=subBytes(buffer,position[4]+bytesLen(tokens[4]),buffer.length);
FileHolder f=new FileHolder(b,contentType,file,name);
Vector v=(Vector)files.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(f))
{
v.add(f);
}
files.put(name,v);
//同时将 name 属性和 file 属性作为普通字段,存入values;
v=(Vector)values.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(file))
{
v.add(file);
}
values.put(name,v);
}else
{
// String[] tokens={"name=\"","\"; filename=\"", "\"\r\n","Content-Type: ","\r\n\r\n"}
// index 0 1 2 3 4
//不包含tokens 中的第二个元素,说明是个 name/value 型的数据段
//所以没有tokens[1]和 tokens[3]
//name 在 tokens[0] 和 tokens[2] 之间
//value 在 tokens[4]之后
//1.得到name
String name =subBytesString(buffer,position[0]+bytesLen(tokens[0]),position[2]);
String value= subBytesString(buffer,position[4]+bytesLen(tokens[4]),buffer.length);
Vector v=(Vector)values.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(value))
{
v.add(value);
}
values.put(name,v);
}
}
/**字节数组中的 indexof 函数,与 String 类中的 indexOf类似
**@para source 源字节数组
**@para search 目标字符串
**@para start 搜索的起始点
**@return 如果找到,返回search的第一个字节在buffer中的下标,没有则返回-1
**/
private static int byteIndexOf (byte[] source,String search,int start)
{
return byteIndexOf(source,search.getBytes(),start);
}
/**字节数组中的 indexof 函数,与 String 类中的 indexOf类似
**@para source 源字节数组
**@para search 目标字节数组
**@para start 搜索的起始点
**@return 如果找到,返回search的第一个字节在buffer中的下标,没有则返回-1
**/
private static int byteIndexOf (byte[] source,byte[] search,int start)
{
int i;
if (search.length==0)
{
return 0;
}
int max=source.length-search.length;
if (max<0)
return -1;
if (start>;max)
return -1;
if (start<0)
start=0;
// 在source中找到search的第一个元素
searchForFirst:
for (i=start;i<=max ; i++)
{
if (source==search[0])
{
//找到了search中的第一个元素后,比较剩余的部分是否相等
int k=1;
while(k<search.length)
{
if (source[k+i]!=search[k])
{
continue searchForFirst;
}
k++;
}
return i;
}
}
return -1;
}
/**
**用于从一个字节数组中提取一个字节数组
**类似于 String 类的substring()
**/
private static byte[] subBytes(byte[] source,int from,int end)
{
byte[] result=new byte[end-from];
System.arraycopy(source,from,result,0,end-from);
return result;
}
/**
**用于从一个字节数组中提取一个字符串
**类似于 String 类的substring()
**/
private static String subBytesString(byte[] source,int from,int end)
{
return new String(subBytes(source,from,end));
}
/**
**返回字符串S转换为字节数组后的长度
**/
private static int bytesLen(String s)
{
return s.getBytes().length;
}
}
请问那位大侠知道JSP查询结果导出为excle表格,为什么只能导出14条的吗?急!! 这14条是数据库里的最后14条纪录。如果输入的数据大于14,则随机输出小于14的纪录? 这是为什么啊???请各位大侠帮忙!!!!
代码如下:
<%
String pagesize=request.getParameter("page");
int pageSize=(int)Integer.parseInt(pagesize);
System.out.println("总共导出数据是:"+pageSize+"条");
String quanxian = (String)session.getAttribute("quanxian");
//System.out.println("quanxian="+quanxian);
String searchType = request.getParameter("searchType");
String keyWord = request.getParameter("keyWord");
String strCurterPage=request.getParameter("page");//获取当前页数
if (keyWord==null){
keyWord = "";
}else{
keyWord = keyWord.replaceAll("'","");
keyWord = keyWord.replaceAll("'","''");
keyWord = new String(keyWord.getBytes("ISO8859-1"), "GB2312").trim();
}
if (searchType == null){
searchType = "";
}else{
searchType = new String(searchType.getBytes("ISO8859-1"), "GB2312").trim();
}
int curterPage;
if(strCurterPage == null){
curterPage = 1;
}else{
curterPage = java.lang.Integer.parseInt(strCurterPage);
if(curterPage<1) curterPage = 1;
}
//int pageSize = 15;
ArrayList list = log.getAllLog(pageSize,curterPage,searchType,keyWord);
int countRow = log.getCountRow();//总的行数
int countPage = log.getCountPage();//总的页数
curterPage = curterPage<countPage?curterPage:countPage;
%>
<html>
<head>
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}
function check(){
if(document.form1.searchType.value!=""){
if( document.form1.keyWord.value==""){
alert("请输入关键词");
document.form1.keyWord.focus();
return false;
}
return true;
}
}
function delItem(ID,page){
if (window.confirm("是否确定删除?")){
window.location.href="delrizhi.jsp?id="+ID+"&page="+page;
}
}
function change(){
if(document.form1.searchType.value==""){
document.form1.keyWord.value="";
}
}
//-->
</script>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<title></title>
<link href="../../css/pt9.css" rel="stylesheet" type="text/css">
<script language="javascript" src="../../js/page.js"></script>
</head>
<body>
<table width="90%" border="1" cellpadding="3" cellspacing="0" class="pt9" bordercolorlight="#000000" bordercolordark="#FFFFFF">
<tr bgcolor="#39B4D7">
<td bgcolor="#3FBCF1" >
<div align="center">序号</div></td>
<td bgcolor="#3FBCF1">
<div align="center">用户</div></td>
<td bgcolor="#3FBCF1">
<div align="center">操作内容</div></td>
<td bgcolor="#3FBCF1">
<div align="center">操作时间</div></td>
<td bgcolor="#3FBCF1">
<div align="center">IP</div></td>
</tr>
<%
for(int i=0;i<list.size();i++){
LogForm info = (LogForm)list.get(i);
%>
<tr>
<td>
<div align="center"><%=((curterPage-1)*pageSize+i+1)%></div></td>
<td>
<div align="center"><%=info.getRealName()%></div></td>
<td>
<div align="center"><%=info.getActionName()%></div></td>
<td>
<div align="center"><%=info.getActionTime()%></div></td>
<td>
<div align="center"><%=info.getUserIP()%></div></td>
</tr>
<% }%>
</table>
</form>
<%
String target=request.getParameter("target");
System.out.println(target);
if(target==null)
target="";
if(!target.equals(""))
{
response.setContentType("application/vnd.ms-excel; charset=GBK");
response.setHeader("Content-Disposition","attachment; filename=\"AQEExport.xls\"");
}
else
{
response.setContentType("text/html; charset=GBK");
}
%>
</body>
</html>
1,首先,新建一个Tapestry工程文件,命名为upload,在向导里面有三个步骤,我基本是打入工程名就直接按回车了。新建好工程后,你可以看到一个典型的web目录,在 WEB-INF自动生成4个文件:
upload.appliaction tapestry的应用程序文件。
Home.html tapestry的模版文件
Home.page tapestry的定义的摸版的配置文件
web.xml
2.接着,再新建两个Tapestry page文件,各命名为Upload ,Download.(注意:要确认Generate an assiated HTML File,Ceate a new class被选定,对于要生成的.java我还是用Upload,Download来命名!);
对于生产.page和.jwc文件spindle提供了一个比较有用的向导,省了我好多工夫,呵呵。
3,现在就可以写代码了。
(1)Home.html
代码如下:
<html jwcid="@Shell" title="欢迎学习Tapestry!">
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<body> <p><a href="#" jwcid="@PageLink" page="Upload">上传文件</a></p> <p><a href="#" jwcid="@PageLink" page="Dowload">下载文件</a></p>
</body></html>
(2) Upload.html
<html jwcid="@Shell" title="上传文件">
<body>
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<P><FORM jwcid="@Form" listener="ognl:listeners.submit">
请选择你要上传的文件<input jwcid="@Upload" file="ognl:fileName" type="file"></input><INPUT type="submit" value="上传"/>
</FORM>
</body>
</html>
(3)Dowload.html
<html jwcid="@Shell" title="上传文件">
<body>
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<a href="#" jwcid="@DirectLink" listener="ognl:listeners.dowload">点击下载</a>
</body>
</html>
4.到此,三个简单的html文件已经写好,接下来就实现java文件。
(1).,Upload.java
package wenone;
import org.apache.tapestry.IRequestCycle;import java.io.*;
import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.request.IUploadFile;
public abstract class Upload extends BasePage
{
public abstract IUploadFile getFile();
public void formSubmit(IRequestCycle cycle)
{
IUploadFile file = getFile();
if (file == null)
return;
File newFile=new File(file.getFileName());
file.write(newFile);//存到当前工作区
cycle.activate("Home");
}
}
5.Dowload.java
package wenone;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.html.BasePage;
import java.io.*;
public abstract class Download extends BasePage{
public void download(IRequestCycle cycle)
{
File file=new File("file.zip");
try
{
HttpServletResponse response =
cycle.getRequestContext().getResponse();
byte[] data = new byte[1024];
FileInputStream in = document.getFileInputstream();
response.setHeader("Content-disposition",
"inline; filename=" +
document.getFileName());
response.setContentType(file.getMimeType());
response.setContentLength(new Long(file.getSize()).intValue());
ServletOutputStream out = response.getOutputStream();
while (in.read(data) > -1)
{
out.write(data);
}
in.close();
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
如果只是下在某个文件的话,直接用超连接就可以搞定但是用超链不安全,谁都可以访问,用程序当然好,可是把WEB不能访问的目录的文件下载给经过认证的访问者.
前面我写过一个把图片从数据库取出来推向页面的例子.
你只要把从数据库取的数据源改成从一个文件读到的数据源,然后把文档头
"image/gif"
改成"application/x-msdownload"就可以把一个向浏览器输出一个文件了.
File t_file = new java.io.File(sourceFilePathName);
long l = t_file.length(); //文件长度
InputStream in = new FileInputStream (t_file);
if(in != null)
{
String fs = t_file.getName();
response.reset();
response.setContentType("application/x-msdownload"); //
String s = "attachment; filename="+fs; //
response.setHeader("Content-Disposition", s); //以上输出文件元信息
response.setContentLength((int)l); //设置输入文件长度
byte[] b = new byte[2048];
int len = 0;
while({len=in.read(b)) >0);
{
response.getOutputStream().write(b,0,len); //向浏览器输出
}
in.close(); //关闭文件输入流
}
有人经常会问这样一个问题:“服务器端程序如何向客户端输出一个文件,然后让浏览器
打开一个保存文件的对话框,来保存这个文件。” 当然了,一个很简单的做法,就是做一个
连接,指向要输出的文件,比如 <a href="a.rar">下载a.rar</a>,这样,当用户点击
连接的时候就会弹出IE的保存文件对话框,然后下载。
不过,这样做有两方面的缺陷:
一是,浏览器有时候会自作聪明,对于一些常见的文件类型会调用相关的应用程序打开,
比如,下载一个word文档.doc文件, 有时候浏览器会默认用word程序打开它。
二是,就是防止盗链的问题。一个用户可以直接通过url地址来随意的引用这个文件,造成
文件的盗用。
现在,在jsp中就可以直接通过文件流的方式向客户端写数据,类似于我们在asp中用到
的adodb.stream对象。这样,我们就可以把我们需要保护的文件放到Web根目录以外的地方,
比如web根目录在F:\tomcat\webapps\ROOT,而我们可以把文件放到f:\software\目录
下,这样别人就没有办法通过调用url来下载文件了。
好了,下面我们就来看看代码如何编写。
首先,设置一下response对象的contenttype为 APPLICATION/OCTET-STREAM;
接着,设置response对象的http header属性 Content-Disposition 为一个文件名,
比如: attachment; filename="a.rar" ,其中的filename是“另存为”对话框出现的
文件名。
最后,就要用 FileInputStream 对象从文件中读取数据,然后输出。
具体例子为:
<%
String filename = "JavaFlash.rar";
String filepath = "f:\\";
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition","attachment; filename=\"a.rar\"");
java.io.FileInputStream fileInputStream =new java.io.FileInputStream(filepath+filename);
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i); }
fileInputStream.close();
out.close();
%>
特别值得注意的一点就是: 这种方法是直接从文件中读取数据,然后输出到客户端。 所以在整个文件中,不能再
向客户端输出任何信息,因为通过别的方式输出的信息也会保存在文件中,这样就破坏了文件的结构了。比如,
<%符号前面出现的哪怕一个空格,一个回车都不可以,所以千万要小心。
要输出一个excel,内容当然是你自己的逻辑,但MIME要非常熟悉.
<%@page contentType="application/msexcel"%>
<%
response.setHeader("Content-disposition", "inline;filename=test.xls");
%>
inline是内联方式,也就是在当前文档中打开.如果是IE就是在IE窗口中打开这个文档,如果是email就是内嵌在邮件中而不是作为附件.
如果要下载,则描述符为:attachment,邮件中就是附件,IE中就是下载
TestFileDownload.JSP页面的例子:
<%
// 得到文件名字和路径
String filename = ”MengxianhuiDocTest.doc”;
String filepath = ”D:\\”;
// 设置响应头和下载保存的文件名
response.setContentType(”APPLICATION/OCTET-STREAM”);
response.setHeader(”Content-Disposition”,
”attachment; filename=\”” + filename + ”\””);
// 打开指定文件的流信息
java.io.FileInputStream fileInputStream =
new java.io.FileInputStream(filepath + filename);
// 写出流信息
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
out.close();
%>;
值得注意的是:在你要下载的文件内容里,除了文件的内容之外,不应该再附加有其它任何的字符,包括空格和回车换行符。我们有时在编写代码的时候,为了使代码清晰可读,往往会添加一些空格、制表符或者回车换行符,这样虽然看起来比较清晰,但有时可能会得不到正确的结果。比如:
<%@ page import=”java.io.*”
%>; <jsp:useBean id=”MyBeanFromMengxianhui” scope=”page”
class=”com.Mengxianhui.DownloadBean” />;
应该写成这样:
<%@ page import=”java.io.*”
%>;<jsp:useBean id=”MyBeanFromMengxianhui” scope=”page”
class=”com.Mengxianhui.DownloadBean” />;
--------------------------------------------------------------------------------
eclipse 回复于:2002-10-18 12:13:21
请注意:APPLICATION/OCTET-STREAM是设置下载类型
要改成你实际的类型,如excel要写成:application/vnd.ms-excel
--------------------------------------------------------------------------------
eclipse 回复于:2002-10-18 12:17:39
如果不用jspsmart,你就需要了解浏览器端的编码方式,在传到服务器端时你才能解码。也才可以得到上传文件的相关信息。看下面的代码。
package mshtang.fileUpload;
import java.io.*;
/**一个存放文件信息的类,包括文件的名称(String),
**字段名(String), Content-Type(String)和内容(byte[])
**还提供了一个直接将文件内容保存到一个文件的函数 void saveTo(File f)
**可以调用 类{@link ContentFactory}中的适当方法,生成该类的实例。
** @see ContentFactory
** @see ContentFactory#getFileParameter
** @see ContentFactory#getFileParameterValues
**/
public class FileHolder
{
String contentType;
byte[] buffer;
String fileName;
String parameterName;
FileHolder(byte[] buffer, String contentType, String fileName, String parameterName)
{
this.buffer = buffer;
this.contentType = contentType;
this.fileName = fileName;
this.parameterName = parameterName;
}
/**把文件的内容存到指定的文件中,
**<b>;这个方法不会检查这个文件是否可写、是否已经存在。</b>;
**@param file 目的文件
**@throws 在 I/O 操作中被抛出的 IOException
**/
public void saveTo(File file) throws IOException
{
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
out.write(buffer);
out.close();
}
/**把文件的内容存到指定的文件中,
**<b>;这个方法不会检查这个文件是否可写、是否已经存在。</b>;
**@param name 目的文件名
**@throws 在 I/O 操作中被抛出的 IOException
**/
public void saveTo(String name) throws IOException
{
saveTo(new File(name));
}
/**
**返回一个文件内容的字节数组
**@return 一个代表文件内容的字节数组
**/
public byte[] getBytes()
{
return buffer;
}
/**
**返回该文件在文件上载前在客户端的名称
**@return 该文件在文件上载前在客户端的名称
**/
public String getFileName()
{
return fileName;
}
/**
**返回该文件的 Content-Type
**@return 该文件的 Content-Type
**/
public String getContentType()
{
return contentType;
}
/**
**返回上载该文件时,Html 页面窗体中 file 控件的 name 属性
**@return 返回上载该文件时,Html 页面窗体中 file 控件的 name 属性
**/
public String getParameterName()
{
return parameterName;
}
}
package mshtang.fileUpload;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
/**存放报文内容的类,提供类似于 ServletRequest 中的部分 get 方法
*你必须在 html 页面的窗体(form)中指定 enctype="multipart/form-data"。
*才可以正确的使用这个类。
**/
public class ContentFactory
{
private Hashtable values; //存放name=value,其中value存放在另一个类中
private Hashtable files; //存放文件内容的。
private ContentFactory(Hashtable values, Hashtable files)
{
this.values=values;
this.files=files;
}
public String getParameter(String name)
{
Vector v = (Vector)values.get(name);
if( v != null)
{
return (String)v.elementAt(0);
}
return null;
}
public Enumeration getParameterNames()
{
return values.keys();
}
public String[] getParameterValues(String name)
{
Vector v = (Vector)values.get(name);
if(v != null)
{
String[] result = new String[v.size()];
v.toArray(result);
return result;
}
return new String[0];
}
/**
*返回一个 FileHolder 实例,该实例包含了通过字段名为name的file控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择上载的文件,则返回 null。
* <p>;如果 Html 页面中存在不止一个字段名为name的file控件,
* 返回值等于{@link #getFileParameterValues}中的第一个元素。
*
* @param name:一个<code>;String</code>;,对应于Html页面窗体中file控件
*的name 属性。
*
* @return返回:一个 FileHolder 实例,该实例包含了通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面是,没有选择上载的文件,则返回 null。
*
* @see #getFileParameterValues
*
*/
public FileHolder getFileParameter(String name)
{
Vector v = (Vector)files.get(name);
if(v != null)
{
return (FileHolder)v.elementAt(0);
}
return null;
}
/**
* 返回一个 由 String 对象构成的 Enumeration ,包含了 Html 页面
*窗体中所有 file 控件的 name 属性。
*如果窗体中没有 file 控件,则返回一个空的 Enumeration
* @return 返回一个 由 String 对象构成的 Enumeration ,包含了 Html 页面
*窗体中所有 file 控件的 name 属性。
*如果窗体中没有 file 控件,则返回一个空的 Enumeration
*/
public Enumeration getFileParameterNames()
{
return files.keys();
}
/**
*返回一个 FileHolder 数组,该数组包含了所有通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择任何上载的文件,则返回一个 零元素的数组(不是 null )。
* @param name 一个 <code>;String</code>; ,对应于 Html 页面窗体中 file 控件
*的name 属性。
*
* @return 返回一个 FileHolder 数组,该数组包含了所有通过字段名为 name 的 file 控件上载的文件信息,
*如果不存在这个字段或者提交页面时,没有选择任何上载的文件,则返回一个 零元素的数组(不是 null )。
*
* @see #getFileParameter
*/
public FileHolder[] getFileParameterValues(String name)
{
Vector v=(Vector)files.get(name);
if(v!=null)
{
FileHolder[] result=new FileHolder[v.size()];
v.toArray(result);
return result;
}
return new FileHolder[0];
}
//------------->;Factory 部分
/**
**返回根据当前请求生成的一个 ContentFactory 实例
**@param request 提交的请求
**@return 返回根据当前请求生成的一个 ContentFactory 实例,如果 request
数据包的内容不是以 mutilpart/form-data 型编码,则返回 null。
**@throws ContentFactoryException 当提交的数据和文件太大时抛出,
**根据 Content-Length 判断,默认的许可值为 1024* 1024。
**/
public static ContentFactory getContentFactory(HttpServletRequest request) throws ContentFactoryException,IOException
{
// default maxLength is 1MB.
return getContentFactory(request, 1024*1024);
}
/**
**返回根据当前请求生成的一个 ContentFactory 实例
**@param request 提交的请求
**@param maxLength 数据包的最大长度,默认为1024*1024
**@return 返回根据当前请求生成的一个 ContentFactory 实例,如果 request
数据包的内容不是以 mutilpart/form-data 型编码,则返回 null。
**@throws ContentFactoryException 当提交的数据和文件太大时抛出,
**根据 Content-Length 判断,默认的许可值为 1024* 1024。
**/
public static ContentFactory getContentFactory(HttpServletRequest request, int maxLength) throws ContentFactoryException, IOException
{
Hashtable values = new Hashtable();
Hashtable files = new Hashtable();
String contentType = request.getContentType();
int contentLength = request.getContentLength();
if (contentLength >; maxLength)
{
ContentFactoryException e=new ContentFactoryException("上传数据太多,请不要选择太大的文件");
throw e;
}
if(contentType == null || !contentType.startsWith("multipart/form-data"))
{
return null;
}
//get out the boudary from content-type
int start = contentType.indexOf("boundary=");
//这里应该
int boundaryLen = new String("boundary=").length();
String boundary = contentType.substring(start + boundaryLen);
boundary = "--" + boundary;
//用字节表示,以免 String 和 byte 数组的长度不一致
boundaryLen = bytesLen(boundary);
//把request 中的数据读入一个byte数组
byte buffer[] = new byte[contentLength];
int once = 0;
int total = 0;
DataInputStream in = new DataInputStream(request.getInputStream());
while((total < contentLength) && (once >;= 0))
{
once = in.read(buffer, total, contentLength);
total += once;
}
//对buffer中的数据进行拆分
int pos1 = 0; //pos1 记录 在buffer 中下一个 boundary 的位置
//pos0,pos1 用于 subBytes 的两个参数
int pos0 = byteIndexOf(buffer, boundary, 0);//pos0 记录 boundary 的第一个字节在buffer 中的位置
do
{
pos0 += boundaryLen; //记录boundary后面第一个字节的下标
pos1 = byteIndexOf(buffer, boundary, pos0);
if(pos1==-1)
{
break;
}//
pos0 += 2;//考虑到boundary后面的 \r\n
parse(subBytes(buffer, pos0, pos1-2), values, files); //考虑到boundary后面的\r\n
pos0=pos1;
}while(true);
return new ContentFactory(values,files);
}
private static void parse(byte[] buffer, Hashtable values, Hashtable files)
{
/* this is a smiple to parse
[boundary]
Content-Disposition: form-data; name="file3"; filename="C:\Autoexec.bat"
Content-Type: application/octet-stream
@echo off
prompt $d $t [ $p ]$_$$
[boundary]
Content-Disposition: form-data; name="Submit"
Submit
[boundary]
*/
String[] tokens={"name=\"","\"; filename=\"", "\"\r\n","Content-Type: ","\r\n\r\n"};
// 0 1 2 3 4
int[] position=new int[tokens.length];
for (int i=0;i<tokens.length ;i++ )
{
position=byteIndexOf(buffer,tokens,0);
}
if (position[1]>;0 && position[1]<position[2])
{
//包含tokens 中的第二个元素,说明是个文件数据段
//1.得到字段名
String name =subBytesString(buffer,position[0]+bytesLen(tokens[0]),position[1]);
//2.得到文件名
String file= subBytesString(buffer,position[1]+bytesLen(tokens[1]),position[2]);
if (file.equals("")) return;
file=new File(file).getName(); //this is the way to get the name from a path string
//3.得到 Content-Type
String contentType=subBytesString(buffer,position[3]+bytesLen(tokens[3]),position[4]);
//4.得到文件内容
byte[] b=subBytes(buffer,position[4]+bytesLen(tokens[4]),buffer.length);
FileHolder f=new FileHolder(b,contentType,file,name);
Vector v=(Vector)files.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(f))
{
v.add(f);
}
files.put(name,v);
//同时将 name 属性和 file 属性作为普通字段,存入values;
v=(Vector)values.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(file))
{
v.add(file);
}
values.put(name,v);
}else
{
// String[] tokens={"name=\"","\"; filename=\"", "\"\r\n","Content-Type: ","\r\n\r\n"}
// index 0 1 2 3 4
//不包含tokens 中的第二个元素,说明是个 name/value 型的数据段
//所以没有tokens[1]和 tokens[3]
//name 在 tokens[0] 和 tokens[2] 之间
//value 在 tokens[4]之后
//1.得到name
String name =subBytesString(buffer,position[0]+bytesLen(tokens[0]),position[2]);
String value= subBytesString(buffer,position[4]+bytesLen(tokens[4]),buffer.length);
Vector v=(Vector)values.get(name);
if (v==null)
{
v=new Vector();
}
if (!v.contains(value))
{
v.add(value);
}
values.put(name,v);
}
}
/**字节数组中的 indexof 函数,与 String 类中的 indexOf类似
**@para source 源字节数组
**@para search 目标字符串
**@para start 搜索的起始点
**@return 如果找到,返回search的第一个字节在buffer中的下标,没有则返回-1
**/
private static int byteIndexOf (byte[] source,String search,int start)
{
return byteIndexOf(source,search.getBytes(),start);
}
/**字节数组中的 indexof 函数,与 String 类中的 indexOf类似
**@para source 源字节数组
**@para search 目标字节数组
**@para start 搜索的起始点
**@return 如果找到,返回search的第一个字节在buffer中的下标,没有则返回-1
**/
private static int byteIndexOf (byte[] source,byte[] search,int start)
{
int i;
if (search.length==0)
{
return 0;
}
int max=source.length-search.length;
if (max<0)
return -1;
if (start>;max)
return -1;
if (start<0)
start=0;
// 在source中找到search的第一个元素
searchForFirst:
for (i=start;i<=max ; i++)
{
if (source==search[0])
{
//找到了search中的第一个元素后,比较剩余的部分是否相等
int k=1;
while(k<search.length)
{
if (source[k+i]!=search[k])
{
continue searchForFirst;
}
k++;
}
return i;
}
}
return -1;
}
/**
**用于从一个字节数组中提取一个字节数组
**类似于 String 类的substring()
**/
private static byte[] subBytes(byte[] source,int from,int end)
{
byte[] result=new byte[end-from];
System.arraycopy(source,from,result,0,end-from);
return result;
}
/**
**用于从一个字节数组中提取一个字符串
**类似于 String 类的substring()
**/
private static String subBytesString(byte[] source,int from,int end)
{
return new String(subBytes(source,from,end));
}
/**
**返回字符串S转换为字节数组后的长度
**/
private static int bytesLen(String s)
{
return s.getBytes().length;
}
}
请问那位大侠知道JSP查询结果导出为excle表格,为什么只能导出14条的吗?急!! 这14条是数据库里的最后14条纪录。如果输入的数据大于14,则随机输出小于14的纪录? 这是为什么啊???请各位大侠帮忙!!!!
代码如下:
<%
String pagesize=request.getParameter("page");
int pageSize=(int)Integer.parseInt(pagesize);
System.out.println("总共导出数据是:"+pageSize+"条");
String quanxian = (String)session.getAttribute("quanxian");
//System.out.println("quanxian="+quanxian);
String searchType = request.getParameter("searchType");
String keyWord = request.getParameter("keyWord");
String strCurterPage=request.getParameter("page");//获取当前页数
if (keyWord==null){
keyWord = "";
}else{
keyWord = keyWord.replaceAll("'","");
keyWord = keyWord.replaceAll("'","''");
keyWord = new String(keyWord.getBytes("ISO8859-1"), "GB2312").trim();
}
if (searchType == null){
searchType = "";
}else{
searchType = new String(searchType.getBytes("ISO8859-1"), "GB2312").trim();
}
int curterPage;
if(strCurterPage == null){
curterPage = 1;
}else{
curterPage = java.lang.Integer.parseInt(strCurterPage);
if(curterPage<1) curterPage = 1;
}
//int pageSize = 15;
ArrayList list = log.getAllLog(pageSize,curterPage,searchType,keyWord);
int countRow = log.getCountRow();//总的行数
int countPage = log.getCountPage();//总的页数
curterPage = curterPage<countPage?curterPage:countPage;
%>
<html>
<head>
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}
function check(){
if(document.form1.searchType.value!=""){
if( document.form1.keyWord.value==""){
alert("请输入关键词");
document.form1.keyWord.focus();
return false;
}
return true;
}
}
function delItem(ID,page){
if (window.confirm("是否确定删除?")){
window.location.href="delrizhi.jsp?id="+ID+"&page="+page;
}
}
function change(){
if(document.form1.searchType.value==""){
document.form1.keyWord.value="";
}
}
//-->
</script>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<title></title>
<link href="../../css/pt9.css" rel="stylesheet" type="text/css">
<script language="javascript" src="../../js/page.js"></script>
</head>
<body>
<table width="90%" border="1" cellpadding="3" cellspacing="0" class="pt9" bordercolorlight="#000000" bordercolordark="#FFFFFF">
<tr bgcolor="#39B4D7">
<td bgcolor="#3FBCF1" >
<div align="center">序号</div></td>
<td bgcolor="#3FBCF1">
<div align="center">用户</div></td>
<td bgcolor="#3FBCF1">
<div align="center">操作内容</div></td>
<td bgcolor="#3FBCF1">
<div align="center">操作时间</div></td>
<td bgcolor="#3FBCF1">
<div align="center">IP</div></td>
</tr>
<%
for(int i=0;i<list.size();i++){
LogForm info = (LogForm)list.get(i);
%>
<tr>
<td>
<div align="center"><%=((curterPage-1)*pageSize+i+1)%></div></td>
<td>
<div align="center"><%=info.getRealName()%></div></td>
<td>
<div align="center"><%=info.getActionName()%></div></td>
<td>
<div align="center"><%=info.getActionTime()%></div></td>
<td>
<div align="center"><%=info.getUserIP()%></div></td>
</tr>
<% }%>
</table>
</form>
<%
String target=request.getParameter("target");
System.out.println(target);
if(target==null)
target="";
if(!target.equals(""))
{
response.setContentType("application/vnd.ms-excel; charset=GBK");
response.setHeader("Content-Disposition","attachment; filename=\"AQEExport.xls\"");
}
else
{
response.setContentType("text/html; charset=GBK");
}
%>
</body>
</html>
1,首先,新建一个Tapestry工程文件,命名为upload,在向导里面有三个步骤,我基本是打入工程名就直接按回车了。新建好工程后,你可以看到一个典型的web目录,在 WEB-INF自动生成4个文件:
upload.appliaction tapestry的应用程序文件。
Home.html tapestry的模版文件
Home.page tapestry的定义的摸版的配置文件
web.xml
2.接着,再新建两个Tapestry page文件,各命名为Upload ,Download.(注意:要确认Generate an assiated HTML File,Ceate a new class被选定,对于要生成的.java我还是用Upload,Download来命名!);
对于生产.page和.jwc文件spindle提供了一个比较有用的向导,省了我好多工夫,呵呵。
3,现在就可以写代码了。
(1)Home.html
代码如下:
<html jwcid="@Shell" title="欢迎学习Tapestry!">
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<body> <p><a href="#" jwcid="@PageLink" page="Upload">上传文件</a></p> <p><a href="#" jwcid="@PageLink" page="Dowload">下载文件</a></p>
</body></html>
(2) Upload.html
<html jwcid="@Shell" title="上传文件">
<body>
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<P><FORM jwcid="@Form" listener="ognl:listeners.submit">
请选择你要上传的文件<input jwcid="@Upload" file="ognl:fileName" type="file"></input><INPUT type="submit" value="上传"/>
</FORM>
</body>
</html>
(3)Dowload.html
<html jwcid="@Shell" title="上传文件">
<body>
<H1><FONT color="red">十分钟搞定----在Tapestry实现文件上传与下载</FONT></H1>
<a href="#" jwcid="@DirectLink" listener="ognl:listeners.dowload">点击下载</a>
</body>
</html>
4.到此,三个简单的html文件已经写好,接下来就实现java文件。
(1).,Upload.java
package wenone;
import org.apache.tapestry.IRequestCycle;import java.io.*;
import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.request.IUploadFile;
public abstract class Upload extends BasePage
{
public abstract IUploadFile getFile();
public void formSubmit(IRequestCycle cycle)
{
IUploadFile file = getFile();
if (file == null)
return;
File newFile=new File(file.getFileName());
file.write(newFile);//存到当前工作区
cycle.activate("Home");
}
}
5.Dowload.java
package wenone;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.html.BasePage;
import java.io.*;
public abstract class Download extends BasePage{
public void download(IRequestCycle cycle)
{
File file=new File("file.zip");
try
{
HttpServletResponse response =
cycle.getRequestContext().getResponse();
byte[] data = new byte[1024];
FileInputStream in = document.getFileInputstream();
response.setHeader("Content-disposition",
"inline; filename=" +
document.getFileName());
response.setContentType(file.getMimeType());
response.setContentLength(new Long(file.getSize()).intValue());
ServletOutputStream out = response.getOutputStream();
while (in.read(data) > -1)
{
out.write(data);
}
in.close();
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
如果只是下在某个文件的话,直接用超连接就可以搞定但是用超链不安全,谁都可以访问,用程序当然好,可是把WEB不能访问的目录的文件下载给经过认证的访问者.
前面我写过一个把图片从数据库取出来推向页面的例子.
你只要把从数据库取的数据源改成从一个文件读到的数据源,然后把文档头
"image/gif"
改成"application/x-msdownload"就可以把一个向浏览器输出一个文件了.
File t_file = new java.io.File(sourceFilePathName);
long l = t_file.length(); //文件长度
InputStream in = new FileInputStream (t_file);
if(in != null)
{
String fs = t_file.getName();
response.reset();
response.setContentType("application/x-msdownload"); //
String s = "attachment; filename="+fs; //
response.setHeader("Content-Disposition", s); //以上输出文件元信息
response.setContentLength((int)l); //设置输入文件长度
byte[] b = new byte[2048];
int len = 0;
while({len=in.read(b)) >0);
{
response.getOutputStream().write(b,0,len); //向浏览器输出
}
in.close(); //关闭文件输入流
}
有人经常会问这样一个问题:“服务器端程序如何向客户端输出一个文件,然后让浏览器
打开一个保存文件的对话框,来保存这个文件。” 当然了,一个很简单的做法,就是做一个
连接,指向要输出的文件,比如 <a href="a.rar">下载a.rar</a>,这样,当用户点击
连接的时候就会弹出IE的保存文件对话框,然后下载。
不过,这样做有两方面的缺陷:
一是,浏览器有时候会自作聪明,对于一些常见的文件类型会调用相关的应用程序打开,
比如,下载一个word文档.doc文件, 有时候浏览器会默认用word程序打开它。
二是,就是防止盗链的问题。一个用户可以直接通过url地址来随意的引用这个文件,造成
文件的盗用。
现在,在jsp中就可以直接通过文件流的方式向客户端写数据,类似于我们在asp中用到
的adodb.stream对象。这样,我们就可以把我们需要保护的文件放到Web根目录以外的地方,
比如web根目录在F:\tomcat\webapps\ROOT,而我们可以把文件放到f:\software\目录
下,这样别人就没有办法通过调用url来下载文件了。
好了,下面我们就来看看代码如何编写。
首先,设置一下response对象的contenttype为 APPLICATION/OCTET-STREAM;
接着,设置response对象的http header属性 Content-Disposition 为一个文件名,
比如: attachment; filename="a.rar" ,其中的filename是“另存为”对话框出现的
文件名。
最后,就要用 FileInputStream 对象从文件中读取数据,然后输出。
具体例子为:
<%
String filename = "JavaFlash.rar";
String filepath = "f:\\";
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition","attachment; filename=\"a.rar\"");
java.io.FileInputStream fileInputStream =new java.io.FileInputStream(filepath+filename);
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i); }
fileInputStream.close();
out.close();
%>
特别值得注意的一点就是: 这种方法是直接从文件中读取数据,然后输出到客户端。 所以在整个文件中,不能再
向客户端输出任何信息,因为通过别的方式输出的信息也会保存在文件中,这样就破坏了文件的结构了。比如,
<%符号前面出现的哪怕一个空格,一个回车都不可以,所以千万要小心。
发表评论
-
Skype4Java开发文档以及示例代码
2010-03-02 22:38 902Skype4Java开发文档以及示例代码Skype4Java开 ... -
java 版的SSL
2010-03-02 21:58 761java 版的Sjava 版的SSLSLjava 版的SSL ... -
My97DatePicker时间控件
2010-02-04 09:36 1132My97DatePicker时间控件 -
Java硬盘目录的实现
2010-02-04 00:20 850Java硬盘目录的实现 -
单点登陆
2010-01-23 16:46 1111单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统 ... -
Linux下常用压缩格式的压缩与解压方法
2009-12-23 01:08 734Linux下常用压缩格式的压缩与解压方法 日期:2005-01 ... -
BlackBerry开发指南、
2009-12-22 22:33 958BlackBerry开发指南BlackBerry开发指南 -
JavaScript网页设计300例
2009-12-11 09:35 1002JavaScript网页设计300例JavaScript网页设 ... -
javascript 常用代码
2009-11-18 09:56 8011、后退 前进 <input type=" ... -
javascript可以获得mac地址
2009-11-05 17:36 1987javascript可以获得mac地址【普索】http://w ... -
计算机超级中心
2009-10-22 11:37 749http://www.sccas.cn/gb/index.ht ... -
JAVA媒体播放器源代码.rar
2009-10-08 23:13 4644JAVA媒体播放器源代码.rarJAVA媒体播放器源代码.ra ... -
proxool-0.9.1-source.zip
2009-10-03 14:27 782proxool-0.9.1-source.ziphttp:// ... -
java 开源chat
2009-10-01 15:24 780java 开源chathttp://www.pusuo.net ... -
JavaMai教程JavaMai教程
2009-09-30 20:07 752JavaMai教程JavaMai教程http://www.pu ... -
在线学习管理系统源码
2009-09-28 22:58 2155在线学习管理系统源码在线学习管理系统源码 -
java 进销存java 进销存java 进销存
2009-09-28 00:22 1611java 进销存java 进销存java 进销存 -
俄罗斯方块(带设计文档)
2009-09-28 00:10 1015俄罗斯方块(带设计文档).】俄罗斯方块(带设计文档) -
遗传算法遗传算法
2009-09-01 02:09 947遗传算法遗传算法遗传算法遗传算法 -
apache2.2
2009-08-22 00:36 663apache2.2apache2.2apache2.2apac ...
相关推荐
本资源“API接口模板-含Word和excel”提供了两种格式的接口文档模板,以满足不同的工作需求。 首先,我们来看Word模板。Word是一种常见的文本编辑工具,适用于创建结构化的文档,对于长篇幅的API文档来说,它提供了...
表格导出到excel经常用到,但导出到word却不常用,一旦要用到也挺烦人的,于是稍稍研究了一下,代码简单,功能更简单,勉强实现导出到word文档而已,但最重要的是能通过这些代码给操作word文档一个思路
在IT行业中,尤其是在Web开发领域,提供用户在线预览PDF、Word、Excel等文档的功能是一项常见且实用的需求。本文将详细讲解如何利用Java Web技术实现这样的功能,主要涉及Maven构建工具、前端PDF插件以及后台...
// 隐藏Excel窗口,仅显示在Winform中 excel.Visible = false; // 创建新的工作簿 Workbook workbook = excel.Workbooks.Add(); // 获取活动工作表 Worksheet worksheet = (Worksheet)workbook.ActiveSheet; // 在A1...
"C# 操作work模版打印"这个主题涉及到如何利用C#来处理打印任务,特别是在使用特定的工作模版(可能是Excel或Word文档)时。下面将详细阐述这个领域的相关知识点。 首先,C#中的打印功能通常依赖于.NET Framework...
#### 一、导出Excel文档概述 在Java中,导出Excel文档是一项常见的需求,尤其在处理大量数据时。本文档将详细介绍如何利用Apache POI库来实现这一功能。Apache POI是Apache软件基金会的Jakarta项目中的一个子项目,...
标题中的“Excel表格+Word文档各类各行业模板-作业标准时间测定”暗示了这个压缩包包含了一系列用于不同行业的模板,特别关注的是作业标准时间和测定方法。在企业和生产管理中,作业标准时间(Work Standard Time,...
1. **Apache POI**:一个用于读写Microsoft Office文档的开源库。它支持包括Excel在内的多种Office文件格式。 2. **SpringMVC**:基于Spring框架的一个MVC架构实现,用于构建Web应用程序。 3. **MultipartRequest**...
苹果 iWork 是一个 office 软件套件,包括 Pages、Numbers 和 Keynote,它们分别对应 Word、Excel 和 PowerPoint。这些应用程序可以输入和编辑 Office 文件内容,但是它们不能存成 Office 格式的文件。 苹果 iWork ...
它包含了三个主要的应用程序:Numbers(表格处理)、Pages(文字处理)及 Keynote(演示文稿),这三个应用程序分别对应微软Office中的Excel、Word和PowerPoint。iWork以其简洁直观的操作界面、强大的功能以及与iOS...
iWork 08是一款由苹果公司开发的办公软件套装,它包含了一系列适用于文档处理、电子表格制作以及演示文稿创建的应用程序。这些应用程序旨在提供一种简单而强大的工具集,帮助用户高效地完成各种任务。iWork 08中的...
苹果iWork是苹果公司推出的一套生产力软件套装,专为Mac系统设计,旨在提供高效、直观的文档处理、电子表格管理和演示文稿创建功能。该套装包括了Pages(文字处理)、Numbers(电子表格)和Keynote(演示文稿)三款...
标题中的“Excel表格+Word文档各类各行业模板-作业标准时间研究 表”指的是一个包含Excel表格和Word文档的资源包,专门针对不同行业的作业标准时间进行研究。这个压缩包可能包含了各种行业的工作流程、任务分配、...
标题中的"Office_free Focus_office_work_word_word 表格"暗示了这个压缩包包含的是与Microsoft Office相关的免费资源,特别是Word文档和表格编辑。描述提到是"word形式的办公表格文档 量很大 free下载",这表明...
2. **Microsoft Office 文件** (.docx, .xlsx, .pptx):可能包括Word文档、Excel电子表格和PowerPoint演示文稿,用于撰写报告、分析数据或制作演讲稿。 3. **编程文件** (.cpp, .java, .py): 如果是编程作业,那么会...
SAS学习系列04.-导入数据Ⅱ——Excel文件 本节内容主要讲述了使用...PROC IMPORT OUT= WORK.RESULTS DATAFILE= "D:\我的文档\My SAS Files\9.3\exercise.xlsx" DBMS=EXCEL REPLACE; RANGE="tests1"; GETNAMES=YES;
- A..DOC、B..TXT、C..XLS、D..DOT是文件扩展名,分别代表文档(Word)、文本文件、Excel表格、模板(Word)。 - 选择题中出现了多个选项组合(如A、B、C、D)以及操作指令(如Ctrl+A),这些都是Excel中的常用...
SAS学习系列04.-导入数据Ⅱ——Excel文件.docx 本篇文章主要讲解了使用SAS导入Excel文件的两种方法...PROC IMPORT OUT= WORK.RESULTS DATAFILE= "D:\我的文档\My SAS Files\9.3\exercise.xlsx" DBMS=EXCEL REPLACE;
在本例中,“Work01”可能是用户为一组工作文档创建的归档,可能是为了组织项目、任务或日常工作的文件。 描述中同样提到“Work01.rar”,这暗示了压缩包可能包含了与某个项目或工作任务相关的多种文件。由于没有...
由于压缩包内的文件名称只给出"workorder",我们可以推测这可能是一个包含多个文档或脚本的集合,比如: 1. **工作订单模板**:可能有Excel或PDF格式的文件,定义了工作订单的标准格式和所需信息,如任务描述、...