Code Bye

在form表单做上传,用enctype="multipart/form-data" ,request.getParameter()得不到值

 

在form表单做上传,用servlet技术,当有表单属性enctype=”multipart/form-data” ,servlet端request.getParameter(”username”)得不到属性的值,该如何解决,没用struts的上传

使用外部jar包吧。org.apache.commons.fileupload这个可以 自己查下资料
  不会吧,换个名字试试
  不会吧,你换个名字试试,肯定是你的页面问题

33分
List fileItems = upload.parseRequest(request);   
  Iterator iter = fileItems.iterator();   
  while (iter.hasNext()) {   
  FileItem item = (FileItem) iter.next();
  item.getInputStream();
  if (!item.isFormField()) {
  //文件流
  }else{
  //非文件流  
  String value=item.getString();
  value = new String(value.getBytes(“ISO-8859-1″),”UTF-8”);
    
  }

5分
+1这时编码变了,直接通过request去获取参数是得不到的。
引用 4 楼  的回复:

List fileItems = upload.parseRequest(request);  
  Iterator iter = fileItems.iterator();  
  while (iter.hasNext()) {  
  FileItem item = (FileItem) iter.next();
  item.getInputStream();
  if (!i……

原因是你的form里封装的是二进制数据,需要特殊处理,
这样确实有点麻烦,你最好是把文件上传的form和常规数据的form分开提交,
网上搜下 FileItemFactory factory = new DiskFileItemFactory(); 
因如果增加了enctype=”multipart/form-data”,那么提交的表单就不能再用普通的方式取得了。
而且比如Tomcat的Servlet标准实现里也没有对于这样二进制数据的获取实现,所以你得自己解析了。

有很多开源的上传文件的jar包可以用,你搜一下就有了。我这里提供一个实现你参考一下。

public class FileFormAnalysis implements FormAnalysis {

    private static final LogUtil LOG = new LogUtil(LogFactory.getLog(
            FileFormAnalysis.class));

    /**
     * 获取上传各文件文件名所在域的字节数组的迭代器
     * @param request 请求
     * @return 字节数组的迭代器
     * @throws IOException
     */
    @Override
    public Iterator<Field> analysis(HttpServletRequest request)
            throws IOException {

        InputStream input = request.getInputStream();
        //没有设定文件字符集的话,默认是""iso8859_1""
        String charset = UploadBytes.getCharset(request);
        //获取表单域的分隔符
        byte[] boundarys = UploadBytes.getBoundaryStr(request).getBytes(charset);

        return new FieldIterator(input, charset, boundarys);
    }

    /**
     * 获取上传文件迭代器的实现
     */
    private class FieldIterator implements Iterator<Field> {

        private String charset;
        private byte[] boundarys;
        private InputStream input;
        private ByteArrayOutputStream output;
        private Field currentField;
        private List<Field> currentNextFields;
        int num = 0;

        private FieldIterator(InputStream input, String charset,
                byte[] boundarys) {
            this.input = input;
            this.charset = charset;
            this.boundarys = boundarys;

            this.output = new ByteArrayOutputStream();
        }

        @Override
        public boolean hasNext() {
            currentField = null;//初始当前域置为空
            //如果一次取得域有多个
            if (currentNextFields != null && !currentNextFields.isEmpty()) {
                currentField = currentNextFields.remove(0);
                return true;
            }
            
            int r = -1;
            byte[] buff = new byte[1024];
            List<byte[]> fieldList = null;
            List<byte[]> fileList = null;

            try {
                while ((r = input.read(buff)) != -1) {
                    output.write(buff, 0, r);

                    //获取上传文件的各域的字节列表
                    fieldList = UploadBytes.findFiled(boundarys, output);

                    if (fieldList != null && !fieldList.isEmpty()) {
                        //获取实际上传文件字节列表
                        fileList = UploadBytes.getFilesByteList(fieldList,
                                charset);
                        if (fileList != null && !fileList.isEmpty()) {
                            break;
                        }
                    }
                }

                if (fileList == null || fileList.isEmpty()) {
                    return false;
                }
                if (fileList.size() > 1) {//如果该长度范围有多个域时
                    currentNextFields = new ArrayList<Field>(fileList.size());
                }
                
                Field field = null;
                for (int i = 0; i < fileList.size(); i++) {
                    //获取上传文件的实际内容的Field对象
                    field = UploadBytes.getField(fileList.get(i), charset);

                    if (i == 0) {//该范围长度有一个域的情况
                        currentField = field;
                    } else {//如果该长度范围有多个域的情况
                        currentNextFields.add(field);
                    }
                }
            } catch (Exception ex) {
                LOG.errorLog(ex);
                return false;
            }

            return currentField == null ? false : true;
        }

        @Override
        public Field next() {
            return this.currentField;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

至于原理嘛,简单的说下。

<form enctype="multipart/form-data" action="etnetChina/etnetUpload" method="post">
   <input type="file" name="file"/>
   <input type="text" name="text" />
   <input type="submit" value="上传文件" />
</form>

上面是一个表单,同样multipart/form-data。
假设name=”text”这个域我点击了一个文本文件,内容是。

text
This upload test.

所以提交的http请求大概是这样的。

POST /Upload HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------205147955511612195381301874305
Content-Length: 243
-----------------------------205147955511612195381301874305
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
[\r\n]
text
This upload test.
-----------------------------205147955511612195381301874305
Content-Disposition: form-data; name="text"
[\r\n]
test
-----------------------------205147955511612195381301874305--
[\r\n]

上面的代码就是解析这些东东。其中
boundary=—————————205147955511612195381301874305
表示了这些各个域之间的分隔是什么。

简单就是这些。

response.setCharacterEncoding(“UTF-8”);
request.setCharacterEncoding(“UTF-8”);
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding(“UTF-8”);
List items = null;
items = upload.parseRequest(request);
Iterator itrTwo = items.iterator();
String path = “”;
while(itrTwo.hasNext()){
FileItem item = (FileItem) itr.next();
if(item.isFormField()){
if(item.getFieldName().equals(“path”)){
path = new String(item.getString().getBytes(“iso8859-1″),”utf-8”);;
break;
}
}
}

摘了一部分 

ommons.fileupload,smartload都试了,还是解决不了,难道只能用框架(比如struts的上传)上传吗?

2分
+1 , 因为你设置了表达是文件流形式提交的,request获取不到值
引用 4 楼  的回复:

List fileItems = upload.parseRequest(request);   
  Iterator iter = fileItems.iterator();   
  while (iter.hasNext()) {   
  FileItem item = (FileItem) iter.next();
  item.getInputStream();
  if……

解决了 谢谢大家
说原理的不得分,直接给个能用的就行了。。。。原来如此。
引用 4 楼 s478853630 的回复:

List fileItems = upload.parseRequest(request);   
  Iterator iter = fileItems.iterator();   
  while (iter.hasNext()) {   
  FileItem item = (FileItem) iter.next();
  item.getInputStream();
  if (!item.isFormField()) {
  //文件流
  }else{
  //非文件流  
  String value=item.getString();
  value = new String(value.getBytes(“ISO-8859-1″),”UTF-8”);
    
  }

List fileItems = upload.parseRequest(request);   中的upload是什么?

//如果用的是smartupload的话

SmartUpload mySmartUpload=new SmartUpload();
String name=mySmartUpload.getRequest().getParameter(“name”);

问题好棒,正好遇到了这个问题!

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明在form表单做上传,用enctype="multipart/form-data" ,request.getParameter()得不到值