HttpClient 上传文件接口报错“missing content( 二 )


遗憾的是不行,又报出新的错误:“themay havebeen read by” 。
那么最大嫌疑就只能是er.build()方法,是不是这里生成了?我们来验证下 。
public HttpEntity build() {return buildEntity();}
可以看到er.build()调用的是er.()
MultipartFormEntity buildEntity() {String boundaryCopy = boundary;if (boundaryCopy == null && contentType != null) {boundaryCopy = contentType.getParameter("boundary");}if (boundaryCopy == null) {//生成随机数BoundaryboundaryCopy = generateBoundary();}Charset charsetCopy = charset;if (charsetCopy == null && contentType != null) {charsetCopy = contentType.getCharset();}final List paramsList = new ArrayList(2);paramsList.add(new BasicNameValuePair("boundary", boundaryCopy));if (charsetCopy != null) {paramsList.add(new BasicNameValuePair("charset", charsetCopy.name()));}final NameValuePair[] params = paramsList.toArray(new NameValuePair[paramsList.size()]);//contentType 为空默认设置为multipart/form-dataprivate final static String DEFAULT_SUBTYPE = "form-data";final ContentType contentTypeCopy = contentType != null ?contentType.withParameters(params) :ContentType.create("multipart/" + DEFAULT_SUBTYPE, params);final List bodyPartsCopy = bodyParts != null ? new ArrayList(bodyParts) :Collections.emptyList();final HttpMultipartMode modeCopy = mode != null ? mode : HttpMultipartMode.STRICT;final AbstractMultipartForm form;switch (modeCopy) {case BROWSER_COMPATIBLE:form = new HttpBrowserCompatibleMultipart(charsetCopy, boundaryCopy, bodyPartsCopy);break;case RFC6532:form = new HttpRFC6532Multipart(charsetCopy, boundaryCopy, bodyPartsCopy);break;default:form = new HttpStrictMultipart(charsetCopy, boundaryCopy, bodyPartsCopy);}return new MultipartFormEntity(form, contentTypeCopy, form.getTotalLength());}
/*** The pool of ASCII chars to be used for generating a multipart boundary.*/private final static char[] MULTIPART_CHARS ="-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();//生成一个30到40位长的随机数private String generateBoundary() {final StringBuilder buffer = new StringBuilder();final Random rand = new Random();final int count = rand.nextInt(11) + 30; // a random size from 30 to 40for (int i = 0; i < count; i++) {buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);}return buffer.toString();}
从上面源码可以看到,原来er默认-type为 /form-data,并且会自动帮我们生成一个生成一个30到40位长的随机数 。
总结
这就解释的通为什么注释掉
//uploadFile.setHeader("Content-Type", "multipart/form-data");
还能调用成功,因为er帮我们生成了,并用这个分割请求内容,并且默认-type为 /form-data 。
所以当自己设置时:
uploadFile.setHeader("Content-Type", "multipart/form-data;----ba77f35b192c8918628309c77e6add06");
又和er生成的不一样,一样报错调用不成功 。
扩展
“ -type ” 错误其实和网上大家经常遇到的错误“thewasnowas found”是一样的,应该是不同框架,报错的提示不一样 。
以为例:为空的处理在. new (),留个引子待后续继续研究 。
FileItemIteratorImpl(RequestContext ctx)throws FileUploadException, IOException {if (ctx == null) {throw new NullPointerException("ctx parameter");}String contentType = ctx.getContentType();if ((null == contentType)|| (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {throw new InvalidContentTypeException(String.format("the request doesn't contain a %s or %s stream, content type header is %s",MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));}final long requestSize = ((UploadContext) ctx).contentLength();InputStream input; // N.B. this is eventually closed in MultipartStream processingif (sizeMax >= 0) {if (requestSize != -1 && requestSize > sizeMax) {throw new SizeLimitExceededException(String.format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",Long.valueOf(requestSize), Long.valueOf(sizeMax)),requestSize, sizeMax);}// N.B. this is eventually closed in MultipartStream processinginput = new LimitedInputStream(ctx.getInputStream(), sizeMax) {@Overrideprotected void raiseError(long pSizeMax, long pCount)throws IOException {FileUploadException ex = new SizeLimitExceededException(String.format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",Long.valueOf(pCount), Long.valueOf(pSizeMax)),pCount, pSizeMax);throw new FileUploadIOException(ex);}};} else {input = ctx.getInputStream();}String charEncoding = headerEncoding;if (charEncoding == null) {charEncoding = ctx.getCharacterEncoding();}boundary = getBoundary(contentType);if (boundary == null) {IOUtils.closeQuietly(input); // avoid possible resource leakthrow new FileUploadException("the request was rejected because no multipart boundary was found");}notifier = new MultipartStream.ProgressNotifier(listener, requestSize);try {multi = new MultipartStream(input, boundary, notifier);} catch (IllegalArgumentException iae) {IOUtils.closeQuietly(input); // avoid possible resource leakthrow new InvalidContentTypeException(String.format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);}multi.setHeaderEncoding(charEncoding);skipPreamble = true;findNextItem();}