struts2下载文件错误提示误导——结果竟是中文乱码所致

原创 2012年03月29日 17:27:32

在调试struts2文件下载时,提示错误如下:

java.lang.IllegalArgumentException: 
Can not find a java.io.InputStream with the name [fileStream] in the invocation stack. 
Check the <param name="inputName"> tag specified for this action.
	org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:237)
	org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
	com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:277)

出错误,然后根据错误提示,寻找原因。根据错误栈式顺序,出现在第一行的往往是错误源。

请看第一句,想必大家都能看懂吧,找不到fileStream,这个是inputName属性的值,提示让我检查inputName参数是否符合action

根据错误,一直在提示inputName参数,然后把怀疑重心全放到struts配置文件中。

首先来看一下文件下载的程序:

struts2中是以InputStream的形式返回给系统,客户端是直接访问action,然后actionInputStream的形式返回给系统,然后系统生成文件的http响应的消息头。

文件下载的action

package com.download;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

/*
 * 文件下载
 */
public class DownloadFile extends ActionSupport {
	
//	private InputStream inputStream;
	private String fileName;
	
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {	
        try {
			this.fileName = fileName;						
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public InputStream getFileStream() {
		 return ServletActionContext.getServletContext().getResourceAsStream("uploadFile\\"+fileName);
	}
//只有返回return时,才会用到result,然后才会用到result中的参数,即fileInput,
//然后才会调用getFileInput方法,对fileInput进行赋值
	public String execute() throws Exception {
			return "success";
	}
}

Struts中的配置文件:

 <action name="download" class="com.download.DownloadFile">
	  <result name="success" type="stream">
		  <param name="inputName">fileStream</param>
		  <param name="contentType">application/octet-streams</param> 
          <param name="contentDisposition">attachment;filename="${fileName}"</param> 
	  </result>
 </action>

来解释一下配置中下载文件的标签。

inputName:下载文件输出流,文件以流的形式返回。所以action中可以只用到get方式,set方式可以省略。

contentType文件下载的类型。其实就是MIME类型。如:  image/gif(gif格式),application/x-javascript(js格式)

contentDisposition下载文件的处理方式。内联(inline)和附件(attachment)两种方式。是以附件的形式保存(attachment),还是直接在浏览器中显示(inline)。

attachment;filename="${fileName}"这种方式,是以附件形式保存。另一种:filename="${fileName}"则说明是直接在浏览器中显示。

另外还有一个参数,上述配置文件中没有配置:bufferSize下载文件的缓冲大小。

Jsp界面:

<body>
<a href="download?fileName=Struts2多个文件上传示例.doc">Struts2多个文件上传示例.doc</a>
</body>


当时一直用中文名的文件做测试,一次用英文做测试,结果成功了,才发现原来是文件中文名的原因。

原来struts中的配置文件是没有错误的,原来错误提示误导我,一直在寻找配置文件的原因。

中文乱码问题,这个问题,对于IT人士并不陌生。

分析:

jsp中有UTF-8进行编码,所以提交请求的url中,完全转换成了UTF-8,此时的提交的fileName也编码成了???.txt(若是上传文本格式的),在某一路径下寻找匹配的文件,当然会找不到。因此返回的文件流为null

解决的办法如下:

提交的请求文件名是用UTF-8进行编码,然后在actionUTF-8进行解码文件名。

代码如下:

  publicvoid setFileName(String fileName) {   

        try {

        this.fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");

         System.out.println(fileName);  

      } catch (UnsupportedEncodingException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

   }

 这种办法就可以解决文件名是中文了。

若是按照以上这种方式写的话,确实能实现,并且能够成功下载。但是仍然会有一个问题。因为下载保存的时候不会保存中相应的类型,我们不知道要保存什么类型,当然也不知道用什么程序打开。

那如何解决呢?办法如下:在系统返回文件生成响应头信息,更改响应头信息。代码如下:

   public InputStream getFileStream() {

        HttpServletResponse response = ServletActionContext.getResponse();

          try {

           response.setHeader("Content-Disposition", "attachment;fileName="

                   + java.net.URLEncoder.encode(fileName,"UTF-8"));

        } catch (UnsupportedEncodingException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

        }

      return ServletActionContext.getServletContext().getResourceAsStream("uploadFile\\"+fileName);

   }

这样就OK了,即解决了中文文件名,又解决了保存相应类型的问题。

看到这种效果,心里才会挺舒服的。

但是,我还有一个疑问,请教路过的人解答。

在上述setFileName方法中,已经用UTF-8格式进行解码了。恢复到提交的中文参数文件名。但是为啥输出的结果仍然是???.doc呢?

this.fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");

         System.out.println(fileName); 

相关文章推荐

Struts2 文件下载及中文乱码问题的解决方案

Java代码   一 struts.xml文件的编辑         package name="crud-default" extends="convention-default">   ...

Struts2文件上传与下载中的中文乱码问题解决方案

一.、乱码问题概述:在实际项目与应用中,文件上传和下载的对象大多是中文文档,因此在Struts的文件上传和下载功能实现中,中文乱码是一个不得不面对的问题。其中的乱码问题分为两类: 1、jsp页面中...

Struts2文件下载中文乱码解决方案

package csu.soft.boss.action; import java.io.FileInputStream; import java.io.InputStream; import ja...

Struts2 文件上传下载 含下载时中文乱码

对于struts2一直都是看过,很少去动手写里面的功能,今天花了一点时间算整理整理。 整体的项目大致如下: 1:文件上传 uploadAction.java package...

Struts2-文件上传下载-解决下载中文乱码问题

表单元素的enctype属性 表单的enctype属性指定的是表单数据的编码方式,该属性有如下3个值: application/x-www-form-urlencoded:这是默认的编码方式,它只处理...

Struts2文件下载遇到中文乱码、中文丢失的解决方法

Struts2文件下载遇到中文乱码、中文丢失的解决方法

Struts2下载文件中文乱码处理

  • 2014年10月16日 13:00
  • 1KB
  • 下载

Struts2文件上传以及文件名中文乱码解决

这次练习的是一个很简单的内容:将文件上传到服务器。主要功能就是把文件上传到服务器中指定的路径。 开发环境和工具 配置Java开发环境的Windows操作系统,MyEclipse 2014/2...

Struts2 学习笔记 —— 10 —— Action接收参数时的中文乱码问题

在Struts接收参数时,如果输入中文,那么可能就会出现乱码问题     首先写一个index.jsp Insert title here 使用DomainM...
  • rnclcl
  • rnclcl
  • 2014年01月20日 16:01
  • 1237

Struts2上传文件修改默认错误提示

--struts2中文件上传的二个限制,一个是struts.multipart.maxSize,如果不设置,struts2 的核心包下的default.properties文件里有默认的大小设置str...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:struts2下载文件错误提示误导——结果竟是中文乱码所致
举报原因:
原因补充:

(最多只允许输入30个字)