最近在做一个项目,涉及到在客户端,用HttpClient上传文件的问题。而且要上传的不仅仅是文件,还包含其他的一些字段(元数据)。而且有一个特性,文本字段和文件字段的数量是动态的,不确定。
于是,根据API DOC的说明,完成了以下代码:
//准备参数
BasicHttpParams httpParams = new BasicHttpParams();
HttpClient httpclient = new DefaultHttpClient();
HttpPost post=new HttpPost("http://localhost:8080/test/test.do");
//准备上传文件,获得源目录下的文件列表
MultipartEntityBuilder builder =MultipartEntityBuilder.create();
builder.addTextBody("a1", "av1");
builder.addTextBody("a2", "av2");
builder.addBinaryBody("b1", new File("d:/tmp/20130604_122352.jpg"));
builder.addTextBody("b2", "true");
builder.addBinaryBody("b3", new File("d:/tmp/20130604_122352.jpg"));
post.setEntity(builder.build());
try {
HttpResponse response = new DefaultHttpClient(httpParams).execute(post);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
catch (Exception e)
{
}
然后,在客户端,以如下的方式接收和处理参数
@RequestMapping(value="/arrayPost", method = RequestMethod.POST)
@ResponseBody
public String uploadPositionFile(
HttpServletRequest request,
HttpServletResponse response)
{
Enumeration<String> names=request.getParameterNames();
while(names.hasMoreElements())
{
String aName=names.nextElement();
Object object=request.getParameter(aName);
System.out.println(object.getClass().getName());
}
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
Iterator<String> iter = multiRequest.getFileNames();
while(iter.hasNext()){
String fileName=iter.next();
MultipartFile file = multiRequest.getFile(fileName);
}
return "success";
}
最初在测试环境测试的时候,很好用,没有任何问题。 request.getParameterNames(); 能够得到所有非文件字段的名字,再通过名字可以得到值。但是到了运行环境,出现了问题,发现request.getParameterNames(); 不但能够得到所有非文件字段的名字,而且文件字段的名字也能得到,也就是上例中的b1 b3 居然也包含在了name集合中。结果可以预见,系统出现了异常。
经过仔细的检查,发现肯定不是代码的问题。然后便怀疑是运行环境的问题。 仔细的一查POM, 才发现,开发环境用的是http 4.5.3 而运行环境是4.5 就是这么一个小版本号的差异,居然导致了这个问题。 随后,更换开发环境的httpclient的版本号,终于一切正常。可以实现动态表单的模拟。