关于common fileUpload 接收非文件的参数和中文乱码的问题
最近的项目中要用到common fileUpload 在接收参数时出现了中文乱码,在这里我记录一下,以供后来的人可以少走这个弯路。由于在网上找到的文章好多都是转载的,所以解决这个问题也用了我一个上午的时间。
这里贴出一部分的代码
代码中的一些变量没有定义的是在try{}catch(){}以外定义的。代码中有些不严谨的地方,我并没有修改
- try{
- String regExp = ".+////(.+)$"; // 正则匹配,去掉路径取文件名.
- String errortype[] = { ".exe", ".com", ".cgi", ".asp" };
- Pattern p = Pattern.compile(regExp);
- String uploadPath = "D:/image"; //这里我用的是绝对路径,这里可以在web.xml中配置,如果一定要用绝对路径的 话
- boolean isMultipart = FileUploadBase.isMultipartContent(request);
- DiskFileItemFactory factory = new DiskFileItemFactory();
- factory.setSizeThreshold(1024);
- ServletFileUpload upload = new ServletFileUpload(factory);
- upload.setSizeMax(1024 * 1024);
- upload.setHeaderEncoding("gb2312"); //这里要设置一下,设置成你需要的格式
- List<FileItem> fileItem = upload.parseRequest(request);
- Iterator<FileItem> it = fileItem.iterator();
- while (it.hasNext()) {
- FileItem fi = it.next();
- String oriFileName = fi.getName();
- if (fi.isFormField()) { //在这里判断一下,是否要接收非文件的参数,这里接收的非文件的参数
- String formName = fi.getFieldName();
- String formContent = fi.getString();
- formName = new String(formName.getBytes(), "gb2312"); //这一句似乎不用也行,没测试
- formContent = new String(formContent.getBytes(), "gb2312");//这一句也没有测试,好象不用也行
- if (formName.equalsIgnoreCase("categoryId")) {
- categoryId = Integer.parseInt(formContent);
- } else if (formName.equalsIgnoreCase("goodsName")) {
- goodsName = formContent;
- } else if (formName.equalsIgnoreCase("price")) {
- price = Float.parseFloat(formContent);
- } else if (formName.equalsIgnoreCase("salePrice")) {
- salePrice = Float.parseFloat(formContent);
- } else if (formName.equalsIgnoreCase("description")) {
- description = formContent;
- } else if (formName.equalsIgnoreCase("isExist")) {
- isExist = Integer.parseInt(formContent);
- }
- }
- else{ //这里接收的是文件的参数。
- if (!fi.isFormField() && (oriFileName != null)) {
- Matcher m = p.matcher(oriFileName);
- boolean result = m.find();
- if (result) {
- for (int i = 0; i < errortype.length; i++) {
- if (m.group(1).endsWith(errortype[i])) {
- throw new IOException(oriFileName
- + " wrong type");
- }
- }
- try {
- fi.write(new File(uploadPath + "/"
- + m.group(1)));
- path = uploadPath + "/" + m.group(1); //这个path是我在try{}catch(){}以外定义的,以便得到这个值存入数据库
- System.out.println("上传成功");
- } catch (Exception es) {
- es.printStackTrace();
- }
- }
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
上面的方法可以接收正确的中文,也可以接收非文件域的参数
如果是大量的用到文件上传的话也可以把这个功能单独写到一个类里,以便调用。下面我贴出一个别人写好的类。
如果要用,这个可以做个参考,直接拿来用不是个好的学习习惯。
- package com.flc.util;
- import java.util.*;
- import java.io.*;
- import javax.servlet.http.*;
- import org.apache.commons.fileupload.*;
- /**
- * * Jakarta commans FileUpload 封装类. 提供: 参数读取(在 Tomcat 4 下测试过似乎没有中文问题), 文件保存功能. *
- * 示例代码(在 JSP 页面中, 忽略了异常处理代码): test.htm Input name: Select a file: test.jsp
- * JakartaFileUploadHandler uploadHandler = new
- * JakartaFileUploadHandler(request); // 如果是文件上传表单
- * if(uploadHandler.isMultipart()) // 读取参数 { String parameterValue =
- * uploadHandler.getParameter("username"); // 保存文件
- * JakartaFileUploadHandler.saveFileItem(uploadHandler.getFileItem("file1"), new
- * File("file1.txt")); } 更多参考资料请看 Apache 的网站上的指导文章: Using FileUpload
- *
- * @link http://jakarta.apache.org/commons/fileupload/using.html *
- * @see #getParameter(String) *
- * @see #getParameterValues(String) *
- * @see #saveFileItem(FileItem, File) * * 这个类依赖于 Jakarta
- * commons-fileupload-1.0.p. * *
- * @author 刘长炯 *
- * @version 1.0 * 2005-03-23
- */
- public class JakartaFileUploadHandler {
- /** 文件域列表 */
- private Map fileFields = new TreeMap();
- /** 表单域列表 */
- private Map formFields = new TreeMap();
- /** Check that we have a file upload request */
- private boolean isMultipart = false;
- private HttpServletRequest request = null;
- /** * 空构造器. */
- public JakartaFileUploadHandler() {
- }
- /** * 根据现有参数构造一个上传处理器. */
- public JakartaFileUploadHandler(HttpServletRequest request) {
- setRequest(request);
- }
- /**
- * * 设置 HttpServletRequest 并分析里面的表单数据. *
- *
- * @param request -
- * HttpServletRequest
- */
- public void setRequest(HttpServletRequest request) {
- this.request = request;
- isMultipart = FileUpload.isMultipartContent(request); // 如果是文件上传请求,
- // 就提取里面的参数
- if (isMultipart) {
- // Create a new file upload handler
- DiskFileUpload upload = new DiskFileUpload();
- try {
- // Parse the request
- List /* FileItem */items = upload.parseRequest(request);
- // Process the uploaded items
- Iterator iter = items.iterator();
- while (iter.hasNext()) {
- FileItem item = (FileItem) iter.next();
- String name = item.getFieldName();
- String value = item.getString();
- if (item.isFormField()) {
- processFormField(item);
- } else {
- processUploadedFile(item);
- }
- }
- } catch (Exception ex) {
- System.err.println("无法处理上传数据:" + ex);
- }
- }
- }
- /**
- * * 处理表单项目. *
- *
- * @param item -
- * FileItem 对象
- *
- */
- private void processFormField(FileItem item) {
- String name = item.getFieldName();
- String value = item.getString(); // 首先尝试获取原来的值
- Object oldValue = formFields.get(name);
- if (oldValue == null) {
- formFields.put(name, value);
- } else {
- // 多个值存储为 List // 原来为单个值则添加现有的值
- try {
- String oldString = (String) oldValue;
- List list = new ArrayList();
- list.add(oldString);
- list.add(value);
- formFields.put(name, list);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- // 原来为多个值则添加现有的值
- try {
- List list = (List) oldValue;
- list.add(value);
- formFields.put(name, list);
- } catch (Exception ex) {//
- ex.printStackTrace();
- }
- }
- }
- /**
- * * 处理文件项目.
- *
- * @param item
- * -FileItem 对象
- *
- */
- private void processUploadedFile(FileItem item) {
- String name = item.getFieldName();
- fileFields.put(name, item);
- }
- }
这个类是我在网上搜集到的。没有测试。