Posted on 2005-12-07 17:21
BlueO2 阅读(716)
评论(1) 编辑 收藏 所属分类:
MVC Framework
虽然struts上传下载文件很简单,但是封装一下还是好地。
/*
* $Id: DownloadAction.java 164530 2005-04-25 03:11:07Z niallp $
*
* Copyright 2004-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.
apache.
struts.
actions;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* This is an abstract base class that minimizes the amount of special coding
* that needs to be written to download a file. All that is required to use
* this class is to extend it and implement the <code>getStreamInfo()</code>
* method so that it returns the relevant information for the file (or other
* stream) to be downloaded. Optionally, the <code>getBufferSize()</code>
* method may be overridden to customize the size of the buffer used to
* transfer the file.
*
* @since Struts 1.2.6
*/
public abstract class DownloadAction
extends Action {
/**
* If the <code>getBufferSize()</code> method is not overridden, this is
* the buffer size that will be used to transfer the data to the servlet
* output stream.
*/
protected static final int DEFAULT_BUFFER_SIZE =
1024 *
4;
/**
* Returns the information on the file, or other stream, to be downloaded
* by this action. This method must be implemented by an extending class.
*
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request (if any).
* @param request The HTTP request we are processing.
* @param response The HTTP response we are creating.
*
* @return The information for the file to be downloaded.
*
* @throws Exception if an exception occurs.
*/
protected abstract StreamInfo getStreamInfo
(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response
)
throws Exception;
/**
* Returns the size of the buffer to be used in transferring the data to
* the servlet output stream. This method may be overridden by an extending
* class in order to customize the buffer size.
*
* @return The size of the transfer buffer, in bytes.
*/
protected int getBufferSize
() {
return DEFAULT_BUFFER_SIZE;
}
/**
* Process the specified HTTP request, and create the corresponding HTTP
* response (or forward to another web component that will create it).
* Return an <code>ActionForward</code> instance describing where and how
* control should be forwarded, or <code>null</code> if the response has
* already been completed.
*
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request (if any).
* @param request The HTTP request we are processing.
* @param response The HTTP response we are creating.
*
* @throws Exception if an exception occurs.
*/
public ActionForward execute
(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response
)
throws Exception {
StreamInfo info = getStreamInfo
(mapping, form, request, response
);
String contentType = info.
getContentType();
InputStream stream = info.
getInputStream();
try {
response.
setContentType(contentType
);
copy
(stream, response.
getOutputStream());
} finally {
if (stream !=
null) {
stream.
close();
}
}
// Tell Struts that we are done with the response.
return null;
}
/**
* Copy bytes from an <code>InputStream</code> to an
* <code>OutputStream</code>.
*
* @param input The <code>InputStream</code> to read from.
* @param output The <code>OutputStream</code> to write to.
*
* @return the number of bytes copied
*
* @throws IOException In case of an I/O problem
*/
public int copy
(InputStream input,
OutputStream output
)
throws IOException {
byte[] buffer =
new byte[getBufferSize
()];
int count =
0;
int n =
0;
while (-
1 !=
(n = input.
read(buffer
))) {
output.
write(buffer,
0, n
);
count += n;
}
return count;
}
/**
* The information on a file, or other stream, to be downloaded by the
* <code>DownloadAction</code>.
*/
public static interface StreamInfo
{
/**
* Returns the content type of the stream to be downloaded.
*
* @return The content type of the stream.
*/
public abstract String getContentType
();
/**
* Returns an input stream on the content to be downloaded. This stream
* will be closed by the <code>DownloadAction</code>.
*
* @return The input stream for the content to be downloaded.
*/
public abstract InputStream getInputStream
() throws IOException;
}
/**
* A concrete implementation of the <code>StreamInfo</code> interface which
* simplifies the downloading of a file from the disk.
*/
public static class FileStreamInfo
implements StreamInfo
{
/**
* The content type for this stream.
*/
private String contentType;
/**
* The file to be downloaded.
*/
private File file;
/**
* Constructs an instance of this class, based on the supplied
* parameters.
*
* @param contentType The content type of the file.
* @param file The file to be downloaded.
*/
public FileStreamInfo
(String contentType,
File file
) {
this.
contentType = contentType;
this.
file = file;
}
/**
* Returns the content type of the stream to be downloaded.
*
* @return The content type of the stream.
*/
public String getContentType
() {
return this.
contentType;
}
/**
* Returns an input stream on the file to be downloaded. This stream
* will be closed by the <code>DownloadAction</code>.
*
* @return The input stream for the file to be downloaded.
*/
public InputStream getInputStream
() throws IOException {
FileInputStream fis =
new FileInputStream(file
);
BufferedInputStream bis =
new BufferedInputStream(fis
);
return bis;
}
}
/**
* A concrete implementation of the <code>StreamInfo</code> interface which
* simplifies the downloading of a web application resource.
*/
public static class ResourceStreamInfo
implements StreamInfo
{
/**
* The content type for this stream.
*/
private String contentType;
/**
* The servlet context for the resource to be downloaded.
*/
private ServletContext context;
/**
* The path to the resource to be downloaded.
*/
private String path;
/**
* Constructs an instance of this class, based on the supplied
* parameters.
*
* @param contentType The content type of the file.
* @param context The servlet context for the resource.
* @param path The path to the resource to be downloaded.
*/
public ResourceStreamInfo
(String contentType, ServletContext context,
String path
) {
this.
contentType = contentType;
this.
context = context;
this.
path = path;
}
/**
* Returns the content type of the stream to be downloaded.
*
* @return The content type of the stream.
*/
public String getContentType
() {
return this.
contentType;
}
/**
* Returns an input stream on the resource to be downloaded. This stream
* will be closed by the <code>DownloadAction</code>.
*
* @return The input stream for the resource to be downloaded.
*/
public InputStream getInputStream
() throws IOException {
return context.
getResourceAsStream(path
);
}
}
}