Struts2基础学习(六)—文件的上传和下载

一、文件的上传

1.单个文件上传

     Struts2使用拦截器完成了文件的上传,而且底层使用的也是FileUpload开源组件。

客户端注意事项:

(1)method="post"

(2)enctype="multipart/form-data"

(3)<intput type="file" name="photo">

 

在Action编写文件上传时,需要定义三个属性。

(1)文件类型File,属性名与表单中的file的name属性名一致。

(2)字符串类型,属性名: name属性名 + FileName eg: photoFileName 。

(3)字符串类型,属性名: name属性名 + ContentType eg: photoContentType 。

最后要为上述的三个属性名提供getXXX 和SetXXX方法。然后通过FileUtils的copyFile方法进行文件复制,将文件上传到服务器。

 

index.jsp

<s:form action="uploadOne" method="post" enctype="multipart/form-data">
    
        <s:textfield name="username" label="用户名"/>
        <s:file name="photo" label="照片"/>
        <s:submit value="上传"/>
    
    </s:form>

UploadAction.java

public class UploadAction extends ActionSupport{

	private String username;
	private File photo;
	private String photoFileName;// 上传的文件名
	private String photoContentType;// 上传的文件的MIME类型

	public String uploadOne() throws IOException{

		System.out.println("username = " + username + "\nphotoName = " + photoFileName + "\nphotoContentType = "
				+ photoContentType);

		// 上传
		String storeDir = ServletActionContext.getServletContext().getRealPath("/upload");

		FileUtils.copyFile(photo,new File(storeDir,photoFileName));

		return SUCCESS;
	}

	public String getPhotoFileName(){
		return photoFileName;
	}

	public void setPhotoFileName(String photoFileName){
		this.photoFileName = photoFileName;
	}

	public String getPhotoContentType(){
		return photoContentType;
	}

	public void setPhotoContentType(String photoContentType){
		this.photoContentType = photoContentType;
	}

	public String getUsername(){
		return username;
	}

	public void setUsername(String username){
		this.username = username;
	}

	public File getPhoto(){
		return photo;
	}

	public void setPhoto(File photo){
		this.photo = photo;
	}
}

结果:

      image

 

2.文件上传存在的问题

     文件上传总大小默认是2M,如果超过了2M,程序会报异常,可使用<s:actionError>查看具体信息。

     (1)解决总大小的设置,找到常量

     struts.multipart.parser=jakarta    默认文件上传解析器,就是FileUpload组件
     struts.multipart.saveDir=        文件上传的临时文件存储目录
     struts.multipart.maxSize=2097152    文件上传的最大值(总大小),默认是2M
     在struts.xml设置常量,修改文件上传的默认总大小

	<!-- 配置上传文件的大小 -->
	<constant name="struts.multipart.maxSize" value="5000000"/>

 

    (2)还可以通过配置拦截器来设置文件上传

		<action name="uploadOne" class="com.kiwi.action.UploadAction" method="uploadOne">

			<interceptor-ref name="fileUpload">
				<!-- 配置允许上传的文件类型,多个用","分隔 -->
				<param name="allowedTypes">
					image/bmp,image/png,image/gif,image/jpeg,image/jpg
					,image/x-png,image/pjpeg
				</param>
				<!-- 配置允许上传的文件大小,单位字节 -->
				<param name="maximumSize">102400</param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack" />

			<result name="success">/success.jsp</result>
			
		</action>

 

     (3)修改显示错误信息的资源文件信息

     第一步:创建新的资源文件例如message_zh_CN.properties,放置在src下在该资源文件中增加如下信息:

              struts.messages.error.uploading=上传错误: {0}

              struts.messages.error.file.too.large=上传文件太大: {0} "{1}" "{2}" {3}

              struts.messages.error.content.type.not.allowed=上传文件的类型不允许: {0} "{1}" "{2}" {3}

              struts.messages.error.file.extension.not.allowed=上传文件的后缀名不允许: {0} "{1}" "{2}" {3}

     第二步:在struts.xml文件加载该资源文件

<constant name="struts.custom.i18n.resources" value="message"/>

 

3.多文件上传

     在JSP的页面上提供多组文件上传的输入框,选择多个文件上传。

index.jsp

<s:form action="uploadOne" method="post" enctype="multipart/form-data">
    
        <s:textfield name="username" label="用户名"/>
        <s:file name="photo" label="照片1"/>
        <s:file name="photo" label="照片2"/>
        <s:file name="photo" label="照片3"/>
        <s:submit value="上传"/>
    
    </s:form>

UploadAction.java

public class UploadAction2 extends ActionSupport{

	private String username;
	private File[] photo;
	private String[] photoFileName;// 上传的文件名
	private String[] photoContentType;// 上传的文件的MIME类型

	public String uploadOne() throws IOException{
		
		// 上传
		String storeDir = ServletActionContext.getServletContext().getRealPath("/upload");

		if(photo != null && photo.length > 0){
			for(int i = 0;i < photo.length;i++){
				FileUtils.copyFile(photo[i],new File(storeDir,photoFileName[i]));
			}
		}
		return SUCCESS;
	}

	public String getUsername(){
		return username;
	}

	public void setUsername(String username){
		this.username = username;
	}

	public File[] getPhoto(){
		return photo;
	}

	public void setPhoto(File[] photo){
		this.photo = photo;
	}

	public String[] getPhotoFileName(){
		return photoFileName;
	}

	public void setPhotoFileName(String[] photoFileName){
		this.photoFileName = photoFileName;
	}

	public String[] getPhotoContentType(){
		return photoContentType;
	}

	public void setPhotoContentType(String[] photoContentType){
		this.photoContentType = photoContentType;
	}
}

 

二、文件的下载

index.jsp

<s:a action="download?filename=1.jpg">1.jpg</s:a> <br>
<s:a action="download?filename=2.jpg">2.jpg</s:a><br>
<s:a action="download?filename=3.jpg">3.jpg</s:a><br>

struts.xml

 

		<!-- 文件下载 -->
		<action name="download" class="com.kiwi.action.DownloadAction">
			<result name="success" type="stream">
				<!-- 设置文件名称的MIME类型,值不是固定的,值是动态的 -->
				<param name="ContentType">${contentType}</param>
				<!-- 设置弹出下载的窗口,文件名称是动态的值 -->
				<param name="ContentDisposition">attachment;filename=${downloadFilename}</param>
			</result>
		</action>
DownloadAction.java
public class DownloadAction extends ActionSupport{

	//接受文件的名称
	private String filename;

	/*
	 *  get请求的中文乱码问题需要自己解决
	 */
	public void setFilename(String filename) throws UnsupportedEncodingException{
		this.filename = new String(filename.getBytes("ISO-8859-1"),"UTF-8");
	}
	
	/*
	 *  提供一个方法,能获取的文件的MIME类型
	 */
	public String getContentType(){
		return ServletActionContext.getServletContext().getMimeType(filename);
	}
	
	/*
	 * 返回的是文件的名称
	 * 在弹出的下载窗口中,显示中文会有乱码的问题
	 * 判断浏览器,根据不同的编码解决乱码的问题
	 */
	public String getDownloadFilename() throws IOException{
		// 先获取user-agent头信息
		String agent = ServletActionContext.getRequest().getHeader("user-agent");
		// 调用该方法,编码
		String name = this.encodeDownloadFilename(filename, agent);
		return name;
	}
	
	/*
	 * 根据user-agent的头,和文件的名称,解决中文文件名编码的问题
	 */
	public String encodeDownloadFilename(String filename, String agent) throws IOException{
		if(agent.contains("Firefox")){ // 火狐浏览器
			filename = "=?UTF-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
		}else{ // IE及其他浏览器
			filename = URLEncoder.encode(filename,"utf-8");
		}
		return filename;
	}
	
	
	/*
	 * 提供一个方法名称必须是getInputStream()方法
	 */
	public InputStream getInputStream(){
		// 获取要下载的文件的输入流,返回
		return ServletActionContext.getServletContext().getResourceAsStream("/download/"+filename);
	}
	
	@Override
	public String execute() throws Exception{
		return SUCCESS;
	}
}

结果:

      image

posted @ 2016-05-11 00:34  ✈✈✈  阅读(237)  评论(0编辑  收藏  举报