1.上传界面jsp
enctype属性一定要写成multipart/form-data不然就会以二进制文本上传到服务器端,使用 get/post方法对中文编码转码有影响
- <form enctype="multipart/form-data" action="" method="post">
- <input type="file" id="choosefile" />
- <input type="file" id="f" style="display:none;" />
- <input type="submit" value="上传文件" id="submitBtn" />
- </form>
2.文件上传
- public class FileUploadAction extends ActionSupport
- { <p> <span style="color:#009900;">//file<span style="font-family:宋体;">是文件上传过来存放在临时文件夹下面的文件</span></span>
- </p> private File file;
- <span style="color:#009900;">//提交过来的file的名字</span>
- private String fileFileName;
- <span style="color:#009900;">//提交过来的file的MIME类型</span>
- private String fileContentType;
- public File getFile()
- {
- return file;
- }
- public void setFile(File file)
- {
- this.file = file;
- }
- public String getFileFileName()
- {
- return fileFileName;
- }
- public void setFileFileName(String fileFileName)
- {
- this.fileFileName = fileFileName;
- }
- public String getFileContentType()
- {
- return fileContentType;
- }
- public void setFileContentType(String fileContentType)
- {
- this.fileContentType = fileContentType;
- }
- @Override
- public String execute() throws Exception
- //ServletActionContext.getServletContext().getRealPath()获得文件所在文件夹的相对路径在WebRoot下事先建立upload文件夹,上传的文件临时存在这里
- String root = ServletActionContext.getServletContext().getRealPath("/upload");
- InputStream is = new FileInputStream(file);
- OutputStream os = new FileOutputStream(new File(root, fileFileName));
- byte[] buffer = new byte[500];
- while(-1 != (is.read(buffer, 0, buffer.length)))
- {
- os.write(buffer);
- }
- os.close();
- is.close();
- }
- }
3.struts.xml上传配置
- <!--要设置struts文件上传的大小,这里是1048576000/(1024*1024)=10M之前没设置大文件上传时服务器直接重置-->
- <constant name="struts.multipart.maxSize" value="1048576000"/>
- <action name="addVideo" class="com.scholar.action.VideoServiceAction">
- <!-- fileUpload拦截器配置 -->
- <interceptor-ref name="fileUpload">
- <!--设置上传文件最大字节数10M -->
- <param name="maximumSize">10485760</param>
- </interceptor-ref>
- <interceptor-ref name="defaultStack"/>
- <!-- 设置上传文件的保存位置 -->
- <param name="savePath">upload</param>
- <result name="success">Success.jsp</result>
- <result name="input">Error.jsp</result>
- </action>
注意:
1. jsp中只有name="file"的一个元素,而action中却要得到三个数据 file,fileFileName,fileContentType,这是struts 2中文件上传机制自行实现的。
2.上传文件过程中upload只是临时存放文件的作用,文件上传完毕后会删除数据,所以,在myeclipse的WebRoot下的upload文件中任何时候看都是没有任何文件的,那么上传的文件在哪?
其实是在Tomcat中,打开路径:apache-tomcat-7.0.65-windows-x64\apache-tomcat-7.0.65\webapps\scholar\upload
原来文件最终是上传到了Tomcat服务器中,只有这里有文件才能算是上传成功。
项目的目的是将文件路径上传到了数据库中(代码省略),文件其实存在了服务器中。
4.下载界面jsp
- //动态获取相对应的文件,赋值给fileName
- <li>${fileFileName}<a href="fileDownload.action?fileName=${uploadFileName}">下载</a></li>
5.下载文件(中文命名文件未完全解决,但有试调过程,知道了些东西分享下)
- public class FileDownload extends ActionSupport{
- private String fileName;// 初始的通过param指定的文件名属性
- private String inputPath;// 指定要被下载的文件路径
- public InputStream getInputStream() throws Exception {
- // 通过 ServletContext,也就是application 来读取数据
- return ServletActionContext.getServletContext().getResourceAsStream(inputPath+"\\"+fileName);
- }
- public String execute() throws Exception {
- return SUCCESS;
- }
- public void setInputPath(String value) {
- inputPath = value;
- }
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
- public String getFileName() {
- return this.fileName;
- }
- }
6.struts.xml
- <action name="fileDownload" class="com.scholar.action.FileDownload">
- <!-- 设置文件所在位置 -->
- <param name="inputPath">/upload</param>
- <!-- 下载显示的文件名称 -->
- <param name="fileName">${fileName}</param>
- <result name="success" type="stream">
- <!-- 指定下载文件的文件类型 -->
- <param name="contentType">application/octet-stream;</param>
- <!-- 指定stream方法名称 -->
- <param name="inputName">inputStream</param>
- <!-- 文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,默认为直接显示文件 -->
- <param name="contentDisposition">attachment;fileName="${fileName}" </param>
- <!-- 指定下载文件的缓冲大小 -->
- <param name="bufferSize">40960</param>
- </result>
注意:
1.英文的文件上传没有问题,但是中文上传就报错:
Can not find a Java.io.InputStream with the name [InputStream] in the invocation stack.Check the<param name="inputName'> tag specified for this action.
翻译过来以为是inputName的设置问题,其实也可能是中文命名的文件在Tomcat的upload文件夹下找不到要下载的文件。
测试方法:打印getInpuStream的返回值
- public void getInputStream() throws Exception {
- InputStream in = ServletActionContext.getServletContext().getResourceAsStream(inputPath+"\\"+fileName);
- System.out.println("\n in = "+in);
- }
编码问题原因:项目中所有文件编码都使用UTF-8编码,但是Tomcat传输的编码默认是ISO8859-1编码,编码方式不一致导致文件名匹配不成功找不到文件。
打开文件:apache-tomcat-7.0.65-windows-x64\apache-tomcat-7.0.65\conf \ server.xml
没有URIEncoding="UTF-8"属性的话就是默认的ISO8859-1编码,手动添加:
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" URIEncoding="UTF-8"/>
这样中文命名的文件也可以正确匹配并且下载,但是在下载框中中文会显示为空,会显示英文部分。
最近又知道MyEclipse中Java文件默认的编码是GBK
意思是:
jsp编码:UTF-8(默认是ISO8859-1)
Java编码:GBK(默认)
Tomcat传输编码:ISO8859-1(默认)