如何使用Java从formdata获取有意义的数据?

时间:2012-10-15 20:16:18

标签: java servlets multipartform-data

我有一个这样的表格:

  <form id="test" name="test" action="/pages/font/getFontTitle.jsp" method="POST" enctype="multipart/form-data">
    <div class="dialog">
      <table>
        <tbody>
          <tr class="prop"><td valign="top">Name</td><td><input type="text" name="name"></td></tr>
          <tr class="prop"><td valign="top"><input type="file" name="fname" size="62" value="" id="fname"/></td><td><span class="button"><s:submit/></span></td></tr>
        </tbody>
      </table>
    </div> 
  </form>

我的servlet看起来像这样:

String contentType=request.getContentType(),Location="0.";
out.println("Done");
System.out.println("contentType = "+contentType);

  boolean isMultipart=ServletFileUpload.isMultipartContent(request);           // Check that we have a file upload request
  System.out.println("isMultipart = "+isMultipart);

  int formDataLength=request.getContentLength();                           // We are taking the length of Content type data
  byte dataBytes[]=new byte[formDataLength];
  System.out.println("dataBytes = "+dataBytes.length+"\n"+dataBytes.toString());

  java.util.Map<java.lang.String,java.lang.String[]> ParameterMap=request.getParameterMap();
  Iterator it=ParameterMap.entrySet().iterator();
  while (it.hasNext())
  {
    Map.Entry pair=(Map.Entry)it.next();
    System.out.println(pair.getKey()+" = "+(pair.getValue()).toString());
//    it.remove(); // avoids a ConcurrentModificationException
  }
  System.out.println("request = \n"+request.getParameterNames().toString());

  if (isMultipart)
  {
    FileItemFactory factory=new DiskFileItemFactory();
    ServletFileUpload upload=new ServletFileUpload(factory);
    List items=null;
Location+="1.";
    try { items=upload.parseRequest(request); }
    catch (FileUploadException e) { e.printStackTrace(); }
    Location+="2.";
    Iterator itr=items.iterator();
    Location+="3.";
    while (itr.hasNext()) 
    {
        Location+="4.";
      FileItem item=(FileItem)itr.next();
      if (item.isFormField())
      {
        String name=item.getFieldName(),value=item.getString();
        System.out.println("name = "+name+"  value = "+value);
        Location+="5.";
      }
      else
      {
        try
        {
          Location+="6.";
          String itemName=item.getName(),savedFilePath=itemName;
          File savedFile=new File(savedFilePath);
          System.out.println("savedFile = "+savedFile.getAbsolutePath());
          item.write(savedFile);
        }
        catch (Exception e) { e.printStackTrace(); }
      }
    }
  }
Location+="e.";

  out.println(" [ "+Location+" ]");
  out.flush();

我得到的结果是:

contentType = multipart/form-data; boundary=---------------------------15890672924370
isMultipart = true
dataBytes = 35909
[B@14d3ba9
name = [Ljava.lang.String;@187f9d7
request = 
java.util.Vector$1@23ca6e

dataBytes中有一个文件,但它从未进入while(itr.hasNext())循环,jsp输出为:Done [0.1.2.3.e. ],位置4,5,6从未到达。

[1]为什么? [2]如何将“dataBytes = [B @ 14d3ba9”变成可读或文件? [3]如何将“name = [Ljava.lang.String; @ 187f9d7”转换为原始字符串值? [4]我正在使用“(pair.getValue())。toString()”,但为什么它不是一个可读的字符串?

3 个答案:

答案 0 :(得分:1)

客户端只会发送一次HTTP请求正文。

然而,您的代码尝试两次读取请求正文。第一次通过getParameterMap()电话:

java.util.Map<java.lang.String,java.lang.String[]> ParameterMap=request.getParameterMap();

第二次由Apache Commons FileUpload(将面临空请求):

try { items=upload.parseRequest(request); }

这不起作用。

使用 标准Servlet API方法, Apache Commons FileUpload。

另见:

答案 1 :(得分:0)

use应该使用servlet 3.0规范并相应地注释你的servlet,然后使用can user request.getParts()和所有多部分数据。了解它。

答案 2 :(得分:0)

子问题1,3,4:如果你不能使用Servlet 3.0中添加的文件上传功能,我认为你最好使用Commons Fileupload,或多或少是将文件上传到servlet的事实标准。它功能强大,经过良好测试,可以正常使用。

子问题2:Javadoc for ServletRequest's getParameterMap州:

  

返回:包含参数名称作为键的不可变java.util.Map   和参数值作为地图值。参数图中的键是   类型为String。 参数映射中的值的类型为String   阵列

强调补充:返回的值是字符串数组,而不是字符串。这就是为什么你得到奇怪的输出值。尝试

System.out.println( pair.getKey()+" = "+ pair.getValue()[0] );

但是也考虑在servlet中使用记录器,这比在System.out中转储东西更好。

ps:使用IDE中可用的代码格式化功能,您的代码很难阅读。