您的位置:首页 > 编程语言 > Java开发

文件的上传下载---struts2学习笔记

2012-09-06 19:37 761 查看
先简述下学习过程中碰到的一个问题:上传中文命名的文件成功后无法显示

解决办法:修改tomcat下的server.xml文件

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="1000"/>改成

<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" connectionTimeout="1000"
/>

一.上传

Struts2本身并没提供上传的组件,我们可以通过调用上传框架来实现文件的上传。

1、配置上传解析器

首先要配置项目的框架,也就是倒导入"struts2-core-2.2.1.jar"库文件,找到org.apache.struts2包下的default.porperties资源文件。如下
图;资源文件中给出了不同的strus2的默认配置,我们可看到struts2默认是jakarta作为其文件上传的解析器。



jakarta是Commo-FileUpload的框架。如果要使用Commo-FileUpload框架来上传文件,只需将"commons-fileupload-1.2.1.jar"和"commons-io-1.3.2.jar"两个jar复制到项目中的WEB-INF/lib目录下就可。

如果想要使用COS框架来上传文件,只需将“cos.jar”复制到项目中就可以,然后在修改struts.multipart.parser常量值。

修改常量值有两种方法,一是在"struts.xml"中修改,代码如下:

<constant name="struts.multipart.paeser" value="cos"></constant>

二是在struts.properties中修改,代码如下:

  sruts.multipart.parser=cos

2..实现文件上传的Action

  创建表单:upload.jsp

       <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>Struts2文件上传</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->

</head>

<body>
<center>
<h1>Struts 2完成上传</h1>
<form action="upload.action" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" ></td>
</tr>
<tr>
<td>上传文件:</td>
<td><input type="file" name="myFile"></td>
</tr>
<tr>
<td><input type="submit" value="上传"></td>
<td><input type="reset"></td>
</tr>
</table>
</form>
</center>
</body>
</html>


完成上传Action

package net.hncu.struts2.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {
// username属性用来封装用户名
private String username;

// myFile属性用来封装上传的文件
private File myFile;

// myFileContentType属性用来封装上传文件的类型
private String myFileContentType;

// myFileFileName属性用来封装上传文件的文件名
private String myFileFileName;

//获得username值
public String getUsername() {
return username;
}

//设置username值
public void setUsername(String username) {
this.username = username;
}

//获得myFile值
public File getMyFile() {
return myFile;
}

//设置myFile值
public void setMyFile(File myFile) {
this.myFile = myFile;
}

//获得myFileContentType值
public String getMyFileContentType() {
return myFileContentType;
}

//设置myFileContentType值
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}

//获得myFileFileName值
public String getMyFileFileName() {
return myFileFileName;
}

//设置myFileFileName值
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}

public String execute() throws Exception {

//基于myFile创建一个文件输入流
InputStream is = new FileInputStream(myFile);

// 设置上传文件目录
String uploadPath = ServletActionContext.getServletContext()
.getRealPath("/upload");

// 设置目标文件
File toFile = new File(uploadPath, this.getMyFileFileName());

// 创建一个输出流
OutputStream os = new FileOutputStream(toFile);

//设置缓存
byte[] buffer = new byte[1024];

int length = 0;

//读取myFile文件输出到toFile文件中
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
System.out.println("上传用户"+username);
System.out.println("上传文件名"+myFileFileName);
System.out.println("上传文件类型"+myFileContentType);
//关闭输入流
is.close();

//关闭输出流
os.close();

return SUCCESS;
}

}


配置上传Action

   <?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>

<package name="struts2" extends="struts-default">
<action name="upload" class="net.hncu.struts2.action.UploadAction">
<result name="success">/result.jsp</result>
<result name="input">/upload.jsp</result>
</action>
</package>

<!-- Add packages here -->

</struts>


3.文件过滤

简述下原理,具体方法很多

通过struts.xml配置文件配置允许上传的文件类型(即Action下面的param子元素),在Action里面定义一个属性接收写好的参数,在通过和uploadContentType属性进行比较,达到过滤的效果

当然也可以用拦截器过滤文件

通过struts.xml配置文件配置fileUpload拦截器(写在Action子元素里)并配置类型,大小等等(interceper-ref子元素里)从而达到过滤

4.国际化

对于手动过滤,自己指定国际化key

拦截器过滤:

文件太大的提示消息KEY是“struts.messages.error.file.too.large”

类型不允许提示消息KEY是“struts.messages.error.content.type.not.allowed”

可以google下文件上传的常量配置

二.下载

可能很多人会觉得,文件下载太简单,直接在页面上给出一个超级链接,该链接的href属性等于要下载文件的文件名,不就可以实现文件下载了吗?大部分时候的确可以实现文件下载,但如果该文件的文件名为中文文件名,则会导致下载失败;或者应用程序需要在让用户下载之前进行进一步检查,比如判断用户是否有足够权限来下载该文件等。 

看下面的一个原始的下载页面代码片段: 
<h1>原始的下载</h1> 
<ul><li> 
<!-- 包含中文文件名的下载链接 --> 
下载Struts2的Logo:<a href="images/中.gif">下载图形文件</a> 
</li><li> 
下载Struts2的Logo的压缩文件:<a href="images/struts-gif.zip">下载压缩文件</a> 
</li></ul> 
上面页面的包含两个下载的超级链接,两个链接的资源都是存在的,但因为第一个资源文件的文件名是中文文件名,如果单击第一个超级链接,将出现如下图所示的页面。 
从图中页面中椭圆形框包围的地方,我们看到被下载的文件名变成了包含大量%的字符串,很明显,这种文件名显然无法取得需要下载的文件。 
为了解决这个问题,我们使用Struts2的文件下载支持来下载该文件。 

Struts2的文件下载Action与普通的Action并没有太大的不同,仅仅是该Action需要提供一个返回InputStream流的方法,该输入流代表了被下载文件的入口。该Action类的代码如下: 
public class FileDownloadAction implements Action 

//该属性是依赖注入的属性,该属性可以在配置文件中动态指定该属性值 
private String inputPath; 
//依赖注入该属性值的setter方法 
public void setInputPath(String value) 

inputPath = value; 

/* 
下载用的Action应该返回一个InputStream实例, 
该方法对应在result里的inputName属性值为targetFile 
*/ 
public InputStream getTargetFile() throws Exception 

return ServletActionContext.getServletContext().getResourceAsStream(inputPath); 

//处理用户请求的execute方法,该方法返回success字符串 
public String execute() throws Exception 

return SUCCESS; 


从上面的Action中看到,该Action中包含了一个getTargetFile()方法,该方法返回一个InputStream输入流,这个输入流返回的是下载目标文件的入口。该方法的方法名为getTargetFile,表明该Action有一个targetFile属性来返回下载文件。 
一旦我们定义了该Action,就可通过该Action来实现文件下载。 

3 配置Action 
配置该文件下载的Action与配置普通的Action并没有太大的不同,需要在配置普通Action的基础之上,在加上额外的download的拦截器引用。 
除此之外,关键是需要配置一个类型为stream的结果,配置stream类型的结果时需要指定如下四个属性: 
 contentType:指定被下载文件的文件类型。 
 inputName:指定被下载文件的入口输入流。 
 contentDisposition:指定下载的文件名。 
 bufferSize:指定下载文件时的缓冲大小。 
因为stream结果类型的逻辑视图是返回给客户端一个输入流,因此无需指定location属性。 
提示:配置stream类型的结果时,因为无需指定实际的显示的物理资源,所以无需指定location属性,只需要指定inputName属性,该属性指向被下载文件。 
下面是配置该下载所用的Action类的配置文件片段: 
<?xml version="1.0" encoding="GBK"?> 
<!-- 指定Struts2配置文件的DTD信息 --> 
<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
"http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
<!-- 配置Struts2国际化资源文件的baseName --> 
<constant name="struts.custom.i18n.resources" value="globalMessages"/> 
<!-- 配置Struts2应用的编码集 --> 
<constant name="struts.i18n.encoding" value="GBK"/> 
<package name="lee" extends="struts-default"> 
<!-- 配置下载的拦截器引用 --> 
<default-action-ref name="download"/> 
<action name="download" class="lee.FileDownloadAction"> 
<!-- 指定被下载资源的位置 --> 
<param name="inputPath">\images\中.gif</param>  =======服务器上文件的路径
<!-- 配置结果类型为stream的结果 --> 
<result name="success" type="stream"> 
<!-- 指定下载文件的文件类型 --> 
<param name="contentType">image/gif</param> 
<!-- 指定下载文件的文件位置 --> 
<param name="inputName">targetFile</param> 
<param name="contentDisposition">filename="struts.gif"</param>  ============下载时的文件名(用户看到的)
<!-- 指定下载文件的缓冲大小 --> 
<param name="bufferSize">4096</param> 
</result> 
</action> 
</package> 
</struts> 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息