上传文件和下载文件,struts2为文件上传下载提供了实现机制,我们只要按照规则使用就可以了,不要当心我们不会做,码农最重要的一点学习,看各种文档就是家常便饭,要学会适应这样的生活。dayday–raise
<s:form action="doUpload" method="post" enctype="multipart/form-data">
<s:file name="upload" label="File"/>
<s:submit/>
</s:form>
The fileUpload interceptor will use setter injection to insert the uploaded file and related data into your Action class. For a form field named upload you would provide the three setter methods shown in the following example:
fileUpload拦截器将使用setter注入将上传的文件和相关的数据插入到你的操作类。 表单字段命名上传你能提供下面的示例中所示的三个setter方法:`。让我们去操作文件的属性啊。
方法签名 | 描述 |
---|---|
setX(File file) | The file that contains the content of the uploaded file. This is a temporary file and file.getName() will not return the original name of the file临时的文件哦。不会返回原来的名字 |
setXContentType(String contentType) | The mime type of the uploaded file |
setXFileName(String fileName) | The actual file name of the uploaded file (not the HTML name)真实的文件名哦 |
-首先我们要清楚一点,这里的file并不是真正指代jsp上传过来的文件,当文件上传过来时,struts2首先会寻找struts.multipart.saveDir 我在讲属性的时候说过的,可以去看看完整的就在前面的文章中提到过的(这个是在default.properties里面有)这个name所指定的存放位置,我们可以新建一个struts.properties属性文件来指定这个临时文件存放位置,如果没有指定,那么文件会存放在tomcat的localhost\目录下,然后我们可以指定文件上传后的存放位置,通过输出流将其写到流里面就行了,这时我们就可以在文件夹里看到我们上传的文件了。
这个下面的属性的名字随便,但是必须有相应的方法和我们的拦截器设置属性的一一对应起来才可以的。可以自己去看看那个拦截器怎么实现的,
也是有
ActionContext ac = invocation.getInvocationContext();
HttpServletRequest request=(HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
这些东西是必须的!
package com.example;
import java.io.File;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private File file;//临时的文件不可以获得getName()不是原来的啦
private String contentType;
private String filename;//这里的filename才是
public void setUpload(File file) {
this.file = file;
}
public void setUploadContentType(String contentType) {
this.contentType = contentType;
}
public void setUploadFileName(String filename) {
this.filename = filename;
}
public String execute() {
//...
return SUCCESS;
}
}
我们还有对放入缓存的文件进行处理是,这个就是输入输出的事情啦啦
public String execute() throws Exception
{
String root =ServletActionContext.getServletContext().getRealPath("/upload");
InputStream is = new FileInputStream(file);
//输出到指定的文件就行了。
OutputStream os = new FileOutputStream(new File(root, fileFileName));
System.out.println("fileFileName: " + fileFileName);
// 因为file是存放在临时文件夹的文件,我们可以将其文件名和文件路径打印出来,看和之前的fileFileName是否相同
System.out.println("file: " + file.getName());
System.out.println("file: " + file.getPath());
byte[] buffer = new byte[500];
int length = 0;
while(-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer);
}
os.close();
is.close();
return SUCCESS;
}
Struts 2default.properties文件定义了几个设置影响行为的文件上传。 你可能会发现需要更改这些值。 名称和默认值是:
struts.multipart.parser=jakarta
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
除了这个之外,我们还可以定义文件上传的类型,也可以不定义在xml中直接使用,我们的自己手动判断,也可以的。下面的拦截器是什么意思呢?自己可以看看的!百度…
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.multipart.maxSize" value="1000000" />
<action name="doUpload" class="com.example.UploadAction">
<interceptor-ref name="basicStack"/>
<interceptor-ref name="fileUpload">
<param name="maximumSize">500000</param>
//最大的文件大小
<param name="allowedTypes">image/jpeg,image/gif</param>
//文件的类型是什么
</interceptor-ref>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
<result name="success">good_result.jsp</result>
</action>
</struts>
发生错误,应为我们的拦截器在处理的时候,会把错误的key加入到我们的错误处理那里面的,我们可以通过key关键字获得错误类型,源码中可以看到发生错误哦,或增加进入的。
ValidationAware validation = null;
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
validation = (ValidationAware) action;
}
MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;
if (multiWrapper.hasErrors()) {
for (String error : multiWrapper.getErrors()) {
if (validation != null) {
validation.addActionError(error);
}
}
}
错误的关键 | 描述 |
---|---|
struts.messages.error.uploading | 一般的错误发生在文件无法上传 |
struts.messages.error.file.too.large | 发生在maximumSize指定的上传文件太大。 |
struts.messages.error.content.type.not.allowed | 上传文件时指定的预期内容类型不匹配 |
struts.messages.error.file.extension.not.allowed | 上传文件时不允许扩展 |
struts.messages.upload.error.SizeLimitExceededException | 发生在上传请求(作为一个整体)超过配置struts.multipart.maxSize |
struts.messages.upload.error。 <异常类SimpleName > | 发生在任何其他文件上传过程中异常发生 |
文件上传后我们还需要将其下载下来,其实struts2的文件下载原理很简单,就是定义一个输入流,然后将文件写到输入流里面就行,关键配置还是在struts.xml这个配置文件里配置
<result name="success" type="stream">
<param name="contentType">image/jpeg</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">attachment;filename="document.pdf"</param>
<param name="bufferSize">1024</param>
</result>
public class StreamResult extends StrutsResultSupport {
private static final long serialVersionUID = -1468409635999059850L;
protected static final Logger LOG = LoggerFactory.getLogger(StreamResult.class);
public static final String DEFAULT_PARAM = "inputName";
protected String contentType = "text/plain";
protected String contentLength;
protected String contentDisposition = "inline";
protected String contentCharSet ;
protected String inputName = "inputStream";
protected InputStream inputStream;
protected int bufferSize = 1024;
protected boolean allowCaching = true;
Annotation based Configuration,注解的方式
package com.mycompany.webapp.actions;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.struts2.convention.annotation.Result;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
@Result(
name = "success",
type = "stream",
params = {
"contentType", "${type}",
"inputName", "stream", //输入流的值在这里获取的!!!
"bufferSize", "1024",
"contentDisposition", "attachment;filename=\"${filename}\""
}
)
public class FileDisplay extends ActionSupport {
private String type = "image/jpeg";
private String filename;
private InputStream stream;
public String execute() throws Exception {
filename = "myimage.jpg";
File img = new File("/path/to/image/image.jpg");
stream = new FileInputStream(img);
return Action.SUCCESS;
}
private String getType() {
return this.type;
}
private String getFilename() {
return this.filename;
}
private String getStream() {
return this.stream;
}
}
或者xml配置也可以!
<result name="success" type="stream">
<param name="contentType">image/jpeg</param>
<param name="inputName">stream</param>//这个很重要的哦!!!和上面的一一对应啊!
<param name="contentDisposition">attachment;filename="document.pdf"</param>
<param name="bufferSize">1024</param>
</result>
我们的讲解,完了。我又去看小伙伴们的实现的!怎么样,加固我们的理解。
import com.opensymphony.xwork2.ActionSupport;
//文件下载
public class FileDownload extends ActionSupport{
private int number ;
private String fileName;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
//返回一个输入流,作为一个客户端来说是一个输入流,但对于服务器端是一个 输出流
!!!!注意这里,我们的inputname!!!==downloadFile 获得输出流!
public InputStream getDownloadFile() throws Exception
{
if(1 == number)
{
this.fileName = "Dream.jpg" ;
//获取资源路径
return ServletActionContext.getServletContext().getResourceAsStream("upload/Dream.jpg") ;
}
else if(2 == number)
{
this.fileName = "jd2chm源码生成chm格式文档.rar" ;
//解解乱码
this.fileName = new String(this.fileName.getBytes("GBK"),"ISO-8859-1");
return ServletActionContext.getServletContext().getResourceAsStream("upload/jd2chm源码生成chm格式文档.rar") ;
}
else
return null ;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
struts>
<package name="struts2" extends="struts-default">
<action name="FileDownload" class="com.struts2.filedownload.FileDownload">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="contentDisposition">attachment;fileName="${fileName}"</param>
<param name="inputName">downloadFile</param>
<param name="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
多文件的处理上传!一样的,贴哈代码自己体会
package org.apache.struts2.showcase.fileupload;
import com.opensymphony.xwork2.ActionSupport;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/** * Showcase action - multiple file upload using List * * @version $Date$ $Id$ */
public class MultipleFileUploadUsingListAction extends ActionSupport {
private List<File> uploads = new ArrayList<File>();
private List<String> uploadFileNames = new ArrayList<String>();
private List<String> uploadContentTypes = new ArrayList<String>();
public List<File> getUpload() {
return this.uploads;
}
public void setUpload(List<File> uploads) {
this.uploads = uploads;
}
public List<String> getUploadFileName() {
return this.uploadFileNames;
}
public void setUploadFileName(List<String> uploadFileNames) {
this.uploadFileNames = uploadFileNames;
}
public List<String> getUploadContentType() {
return this.uploadContentTypes;
}
public void setUploadContentType(List<String> contentTypes) {
this.uploadContentTypes = contentTypes;
}
public String upload() throws Exception {
System.out.println("\n\n upload1");
System.out.println("files:");
for (File u : uploads) {
System.out.println("*** " + u + "\t" + u.length());
}
System.out.println("filenames:");
for (String n : uploadFileNames) {
System.out.println("*** " + n);
}
System.out.println("content types:");
for (String c : uploadContentTypes) {
System.out.println("*** " + c);
}
System.out.println("\n\n");
return SUCCESS;
}
}
…….搞定?哈哈!自己处理流的问题就好了,其他的都是上面一样的!
每天都有进步。