`
iamlotus
  • 浏览: 108114 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

struts2 文件上传/下载/乱码 碎碎念

阅读更多

我的环境

英文windows xp

location :United states

language for non-Unicode program: Chinese(PRC)

tomcat 6.0

struts2-core-2.2.1

 

网上关于struts file upload/download的文章好多地雷。在我的环境中,花了一个星期才把struts2下上传下载都调好,以下是一点经验。

 

1)使用缺省的jakarta上传空文件会抛出NullPointerException,你可以自己捕捉FileNotFoundException然后自己给一个空的byte[],也可以换用其他的file upload component,比如cos。jakarta把request转存到本时会给一个uuid,cos则是存成request中的fileName。尽管每次处理完这个temp file都会被删掉,但大量并发时上传同名文件还是会有冲突(后一个覆盖前一个)

2)如果你想用cos的话,一定注意,google出来前几个配法都是不成功的 ,正确的配法是

2.1)写一个自己的cos->struts Adaptor (我也是网上找的)

package myapp.view.action.common;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;

import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;

@SuppressWarnings("unchecked")
public class CosMultiPartRequest implements MultiPartRequest {
	private static Log log = LogFactory.getLog(CosMultiPartRequest.class);
	private ArrayList<File> alFile;
	private Hashtable<String, ArrayList<?>> files;
	private ArrayList<String> fileNames;
	private ArrayList<String> contentType;
	private ArrayList<String> fileSystemName;
	private Hashtable<String, ArrayList<String>> parameters;
	private Hashtable<String, ArrayList<?>> filePara;
	private ArrayList<String> paraValues;
	private String encode;

	public CosMultiPartRequest() {
		super();
	}

	public String getEncode() {
		return encode;
	}

	public void setEncode(String encode) {
		this.encode = encode;
	}

	public String[] getContentType(String arg0) {
		ArrayList<String> aList = (ArrayList<String>) files.get(arg0
				+ "_ContentType");
		String[] str = new String[aList.size()];
		for (int i = 0; i < aList.size(); i++) {
			str[i] = aList.get(i);
		}
		return str;
	}

	public List getErrors() {
		return Collections.EMPTY_LIST;
	}

	public File[] getFile(String arg0) {
		ArrayList<File> aList = (ArrayList<File>) files.get(arg0);
		File[] file = new File[aList.size()];
		for (int i = 0; i < aList.size(); i++) {
			file[i] = aList.get(i);
		}
		return file;
	}

	public String[] getFileNames(String arg0) {
		ArrayList<String> aList = (ArrayList<String>) files.get(arg0 + "_name");
		String[] stt = new String[aList.size()];
		for (int i = 0; i < aList.size(); i++) {
			stt[i] = aList.get(i);
		}
		return stt;
	}

	public Enumeration<String> getFileParameterNames() {
		return filePara.keys();
	}

	public String[] getFilesystemName(String arg0) {
		ArrayList<String> arrayList = (ArrayList<String>) files.get(arg0
				+ "_SysName");
		String[] ss = new String[arrayList.size()];
		for (int i = 0; i < arrayList.size(); i++) {
			ss[i] = arrayList.get(i);
		}
		return ss;
	}

	public String getParameter(String arg0) {
		if (parameters.keySet().contains(arg0))
			return arg0;
		return "";
	}

	public Enumeration<String> getParameterNames() {
		return parameters.keys();
	}

	public String[] getParameterValues(String arg0) {

		ArrayList<String> al = parameters.get(arg0);
		String[] str = new String[al.size()];
		for (int i = 0; i < al.size(); i++) {
			str[i] = al.get(i);
		}
		return str;
	}

	public void parse(HttpServletRequest request, String saveDir)
			throws IOException {
		if (log.isDebugEnabled()) {
			log.debug("Parse by CosMultiPartRequest");
		}

		MultipartParser mp = new MultipartParser(request, 1024 * 1024 * 10);
		// actually ,should be injected
		mp.setEncoding("UTF-8");
		Part part;

		files = new Hashtable<String, ArrayList<?>>();
		alFile = new ArrayList<File>();
		fileNames = new ArrayList<String>();
		fileSystemName = new ArrayList<String>();
		contentType = new ArrayList<String>();
		filePara = new Hashtable<String, ArrayList<?>>();
		paraValues = new ArrayList<String>();
		parameters = new Hashtable<String, ArrayList<String>>();

		for (int i = 0; (part = mp.readNextPart()) != null; i++) {
			if (part.isFile()) {
				FilePart fp = (FilePart) part;

				alFile = (ArrayList) files.get(fp.getName());
				if (alFile == null || alFile.size() < 1) {
					alFile = new ArrayList();
				}
				File fil = new File(saveDir + fp.getFileName());
				fp.writeTo(fil);
				alFile.add(fil);

				fileNames = (ArrayList) files.get(fp.getName() + "_name");
				if (fileNames == null || fileNames.size() < 1) {
					fileNames = new ArrayList<String>();
				}
				fileNames.add(fp.getFileName());

				fileSystemName = (ArrayList) files.get(fp.getName()
						+ "_SysName");
				if (fileSystemName == null || fileSystemName.size() < 1) {
					fileSystemName = new ArrayList<String>();
				}
				fileSystemName.add(fp.getFilePath());

				contentType = (ArrayList) files.get(fp.getName()
						+ "_ContentType");
				if (contentType == null || contentType.size() < 1) {
					contentType = new ArrayList<String>();
				}
				contentType.add(fp.getContentType());

				files.put(fp.getName(), alFile);
				files.put(fp.getName() + "_name", fileNames);
				files.put(fp.getName() + "_SysName", fileSystemName);
				files.put(fp.getName() + "_ContentType", contentType);
				filePara.put(fp.getName(), alFile);
			} else if (part.isParam()) {
				ParamPart pp = (ParamPart) part;
				paraValues = parameters.get(pp.getName());
				if (paraValues == null || paraValues.size() < 1) {
					paraValues = new ArrayList<String>();
				}
				paraValues.add(pp.getStringValue());
				parameters.put(pp.getName(), paraValues);

			} else {

			}
		}
	}

 2.2) 在struts.xml中配一个叫cos的bean,把自己写的这个Adaptor配到系统中

    <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest"
        class="myapp.view.action.common.CosMultiPartRequest" name="cos" scope="prototype">

 

网上很多文章都没提到,struts-default.xml里面是没配cos这个bean的。

 

2.3) 打开 struts中的开关,同样是在struts.xml中

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

    这里不要 像网上写的那样配成struts.multipart.parser , 那个属性不起作用的

 

3) 上传时,最好把contentype,fileName用数据库单独存起来,这些信息下载时都要用到。至于内容是存在数据库还是文件系统中随意

 

4) 上传时,文件名为乱码(不是%BC这样的Unicode编码,而是 &#39277; 这样的乱码),这是由于上传(包含File控件)的jsp没有指定编码。把jsp的meta改成

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

 

5)下载时,遇见Can not find a java.io.InputStream with the name [XXX] in the invocation stack。这个异常很误导。可能不是你的param配错了,而是文件找不到,getXXX返回了null。最好在action里处理下,这时直接return INPUT算了。

 

6)下载时,链接中文件名中显示为乱码问题的方法,在tomcat/conf/server.xml中加Encoding参数 ,如下

        <Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
 


这似乎是个bug,见http://www.blogjava.net/wangzhouyu/archive/2007/04/26/113705.html ,原因嘛,是Tomcat对于get param(archor属于get method)没用ISO-8859-1去decode,而是自己搞了一套。很奇怪为什么这个bug现在还没fix

 

7)下载时,点击链接后本地浏览器显示的文件名为乱码,需要这样转一下

String downloadfileName = new String(fileName.getBytes("GBK"),"ISO-8859-1"); 

前面的GBK是怎么来的我也不知道,我只知道后面的"ISO-8859-1"是因为浏览器对fileName按照ISO-8859-1去解析, 可以参见这个文档http://www.busfly.net/csdn/post/449.html

但把GBK hardcoding 在这里就比较urgly了希望知道的同志指点一下这个GBK的来源

 

8)这些中文log下来可能也是编码,需要把log4j.xml的编码改一下,在FILE appender中加一行

<param name="encoding" value="UTF-8" />

 

9)下载时,为了让浏览器正确识别文件类型,刚才让存在数据库的那些contentType和Name就派上用场了

			<result name="success" type="stream">
				<param name="inputName">fileStream</param>
				<param name="contentType">{$attachment.contentType};</param>
				<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
				<param name="contentCharSet">UTF-8</param>
			</result>

 这里的downloadFileName别忘了按照7)里说的转一下,否则浏览器提示保存时是乱码

 

分享到:
评论
2 楼 iamlotus 2011-01-27  
应该不行,因为没有地方记录file size
1 楼 daichangfu 2011-01-22  
学习一下! 我还有一个问题,请问这样下载文件时,显示文件下载的大小吗?可以显示下载进度条吗?

相关推荐

    struts2文件上传下载源代码

    在Struts2中,文件上传和下载是常见的功能需求,特别是在处理用户交互和数据交换时。这篇博客文章提供的"struts2文件上传下载源代码"旨在帮助开发者理解和实现这些功能。 文件上传功能允许用户从他们的设备上传文件...

    struts2实现文件上传下载

    本篇文章将详细探讨如何在Struts2框架下实现文件的上传与下载。 首先,我们需要了解Struts2中的文件上传机制。Struts2提供了`FileUploadInterceptor`拦截器来处理文件上传请求。在处理文件上传时,开发者需要在...

    struts2文件下载/绝对路径+相对路径

    在Struts2中,文件下载功能是常见的需求,尤其是在处理用户请求获取服务器上的静态或动态资源时。这篇博文(http://blog.csdn.net/love_xiolan/article/details/54945859)提供了关于如何在Struts2中实现文件下载的...

    struts2文件下载(解决了中文乱码问题)

    在处理文件下载时,Struts2提供了一套完整的解决方案,包括处理中文文件名的乱码问题。在标题提到的场景中,开发者可能遇到了在使用Myeclipse 6.5集成开发环境,JDK1.6和Tomcat 6.0服务器环境下,通过Struts2进行...

    struts2文件上传和下载

    在Struts2中,文件上传和下载是常见的功能需求,对于用户交互和数据交换至关重要。以下是对这些知识点的详细阐述: 1. **文件上传**: 在Struts2中,文件上传主要依赖于`Commons FileUpload`库,它是一个Apache提供...

    Struts2文件上传下载 中文乱码

    在Struts2框架中,文件上传和下载是常见的功能需求,但处理中文文件名或内容时,可能会遇到中文乱码的问题。这个问题主要涉及到字符编码的处理,包括HTTP请求的编码、文件名的编码以及文件内容的编码。接下来,我们...

    struts2文件上传与下载

    在Struts2中,文件上传和下载是常见的功能需求,主要用于处理用户在Web表单中提交的文件,如图片、文档等。下面将详细介绍Struts2中文件上传和下载的实现方法。 ### 1. 文件上传 #### 1.1 配置Struts2 首先,我们...

    Struts文件上传/下载,支持多文件上传

    本案例将重点讲解如何在Struts中实现文件的上传与下载,并支持多文件上传。 一、文件上传 1. 配置Struts.xml 首先,我们需要在`struts.xml`配置文件中添加相应的action配置,以处理文件上传请求。例如: ```xml ...

    Struts2文件上传与下载

    Struts2是一个强大的Java web框架,它为开发者提供了丰富的功能,包括处理用户表单提交、进行文件上传和下载。在Web应用中,文件上传和下载是常见的需求,例如用户上传头像、下载文档等。Struts2通过其Action类和...

    struts2文件上传(解决中文乱码)

    Struts2是一个强大的Java Web...总之,解决Struts2中的中文乱码问题,关键在于配置正确的字符编码,并在文件上传和下载过程中处理好编码转换。通过以上步骤,你可以有效地在Struts2项目中实现对中文URL和文件名的支持。

    struts2文件上传下载

    在这个特定的项目中,我们关注的是"struts2文件上传下载"的功能,这涉及到用户通过Web界面上传文件到服务器,以及从服务器下载文件到用户的设备。 文件上传是Web应用中的常见需求,例如用户可能需要提交图片、文档...

    搭建struts2框架

    struts2框架的详细搭建 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ...

    Struts2之struts2文件上传详解案例struts011

    在Struts2中,文件上传功能是常见的需求,比如用户可能需要上传个人照片、文档或者其他类型的文件。在这个"Struts2之struts2文件上传详解案例struts011"中,我们将深入探讨如何实现这一功能。 首先,我们需要了解...

    Struts2开发包/struts-2.3.24.1/apps/struts2-blank

    有些人不知道Struts2开发包/apps/struts2-blank怎么解压 用WinRAR其实是可以解压成功的 邮件打开方式里里面选择WinRAR压缩文件管理器为默认打开方式就可以解压了 还是不行的话就下载我上传的这个吧

    Struts2下载文件中文乱码处理

    ### Struts2下载文件中文乱码处理 在Web开发中,使用Struts2框架进行文件下载操作时,经常遇到的一个问题是文件名中的中文字符显示为乱码。这主要是因为浏览器和服务器之间的编码不一致所导致的。为了确保用户能够...

    struts2上传下载 解决中文文件名乱码

    通过上述实践和调试,我们已经成功解决了Struts2框架下中文文件名上传和下载的乱码问题。在遇到类似问题时,可以按照这些步骤进行排查和修复。记住,关键在于正确配置Struts2的拦截器、请求编码以及在处理文件名时...

    struts2中的批量上传与文件下载(解决中文乱码问题)

    本文将详细介绍如何在Struts2框架下实现批量上传与文件下载,并解决中文乱码问题。 一、Struts2文件上传 1. 配置Struts2文件上传支持: 在struts.xml配置文件中,我们需要添加`&lt;constant&gt;`元素来设置允许上传的...

    Struts2多文件上传下载实例

    在实际项目中,文件上传和下载功能是必不可少的,本实例将详细讲解如何在Struts2框架下实现单个文件及多个文件的上传与下载。 首先,我们需要在Struts2的配置文件(struts.xml)中添加相关的Action配置,以便处理文件...

    struts2_uploadify带进度条的多文件上传下载

    Struts2 Uploadify是一个在Java Web开发中常用的插件,它结合了Struts2框架和Uploadify jQuery插件,能够实现文件的多选、上传进度显示以及后台处理等功能。这个项目示例提供了一个完整的解决方案,使得用户在上传多...

Global site tag (gtag.js) - Google Analytics