Cannot retry request with a non-repeatable request entity. The cause lists the

27         MultipartEntity multipartEntity = new MultipartEntity();
28         multipartEntity.addPart("pixel_middle", new StringBody("960,600"));
29         multipartEntity.addPart("pixel_small", new StringBody("192,120"));
30         multipartEntity.addPart("system", new StringBody("01"));
31         multipartEntity.addPart("sort", new StringBody("01"));
32         multipartEntity.addPart("uploader", new StringBody("0283"));
33         multipartEntity.addPart("image", new InputStreamBody(new FileInputStream(new File("D:/httpclient/images/0.jpg");), file.getName()));
34 
35         httpPost.setEntity(multipartEntity);
36         HttpResponse response = httpclient.execute(httpPost);
37         try {
38             int statusCode = response.getStatusLine().getStatusCode();
39             if (200 == statusCode) {
40                 HttpEntity entity = response.getEntity();
41                 System.out.println(EntityUtils.toString(entity));
42             } else {
43                 System.out.println("Error " + statusCode + "!");
44             }
45         } finally {
46             httpPost.releaseConnection();
47         }
48     }
49 }于是查看官方HttpClient Tutorial的1.1.4.1. Repeatable entities节,内容如下:

An entity can be repeatable, meaning its content can be read more than once. This is only possible with self contained entities (like ByteArrayEntity or StringEntity)

根据上面对Repeatable Entity的介绍,就可以确定问题是因为构建multipartEntity时包含除ByteArrayEntity和StringEntity以外的Entity。修改代码如下:


 1 import org.apache.http.HttpEntity;
 2 import org.apache.http.HttpResponse;
 3 import org.apache.http.client.HttpClient;
 4 import org.apache.http.client.methods.HttpPost;
 5 import org.apache.http.entity.mime.MultipartEntity;
 6 import org.apache.http.entity.mime.content.InputStreamBody;
 7 import org.apache.http.entity.mime.content.StringBody;
 8 import org.apache.http.impl.client.DefaultHttpClient;
 9 import org.apache.http.util.EntityUtils;
10 import org.jdom2.JDOMException;
11 
12 import java.io.*;
13 
14 /**
15  * Created with IntelliJ IDEA.
16  * User: qutengfei
17  * Date: 12-11-15
18  * Time: 下午2:00
19  * To change this template use File | Settings | File Templates.
20  * 测试 MultipartForm
21  */
22 public class TestMultipartForm {
23     public static void main(String[] args) throws IOException, JDOMException {
24         HttpClient httpclient = new DefaultHttpClient();
25         HttpPost httpPost = new HttpPost("http://10.5.13.21/upload/");
26 
27         MultipartEntity multipartEntity = new MultipartEntity();
28         multipartEntity.addPart("pixel_middle", new StringBody("960,600"));
29         multipartEntity.addPart("pixel_small", new StringBody("192,120"));
30         multipartEntity.addPart("system", new StringBody("01"));
31         multipartEntity.addPart("sort", new StringBody("01"));
32         multipartEntity.addPart("uploader", new StringBody("0283"));
33         multipartEntity.addPart("image", new InputStreamBody(new FileInputStream(new File("D:/httpclient/images/0.jpg");), file.getName()));
34         
35         // 显示实体是否可重复
36         System.out.println("Repeatable:" + multipartEntity.isRepeatable());
37         
38         httpPost.setEntity(multipartEntity);
39         HttpResponse response = httpclient.execute(httpPost);
40         try {
41             int statusCode = response.getStatusLine().getStatusCode();
42             if (200 == statusCode) {
43                 HttpEntity entity = response.getEntity();
44                 System.out.println(EntityUtils.toString(entity));
45             } else {
46                 System.out.println("Error " + statusCode + "!");
47             }
48         } finally {
49             httpPost.releaseConnection();
50         }
51     }
52 }编译执行上述程序,结果如下:

Repeatable:false

注释第33行代码,重新编译执行程序,结果如下:

Repeatable:true

根据上面的执行结果,可以确定InputStreamBody是造成multipartEntity为不可重复实体的元凶。

HttpClient有ByteArrayBody、FileBody、InputStreamBody和StringBody四种Body。经过笔者测试,其中只有用InputStreamBody构建multipartEntity才是non-repeatable entity。

总结:

笔者最早使用InputStreamBody而不是FileBody,是因为业务需要前置系统将图片上传到图片服务器,并保存图片链接地址到前置系统的数据库。但是前置系统是B/S架构,图片从页面上传到前置的后台是以流的方式,故而才使用InputStreamBody。最后,使用ByteArrayBody代替InputStreamBody

链接:http://www.cnblogs.com/zrcoffee/archive/2012/11/16/2772752.html

你可能感兴趣的:(request)