MultipartEntityBuilder转发附件 使用笔记

上星期用到这个MultipartEntityBuilder,调了好几天,终于调通。记录点笔记。

 

为什么使用这个MultipartEntityBuilder?

 

 原业务如图下:

OA是公司的核心数据,只能内网访问。那么增加网关系统作为转发跳板,并且进行权限约束。

 

本来用得好好的,现在有一个新需求:外业务可以创建工作流,并可以上传附件。 原来基于httpClient form post json的方式不能支持附件。 所以增加了MultipartEntityBuilder, 用于支持附件上传。

 

变成类似表单提交的方式

form post 

data: {...}

file...

file...

file...

 

使用

系统是基于maven的。引入:

		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>
		
		
		<dependency>
		    <groupId>org.apache.httpcomponents</groupId>
		    <artifactId>httpmime</artifactId>
		    <version>4.5.2</version>
		</dependency>

 

使用如下代码片段:

//builder
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
		builder.setCharset(Consts.UTF_8);



//文本内容
StringBody contentBody = new StringBody(jsonContent,ContentType.APPLICATION_JSON);
		builder.addPart("data", contentBody);

//文件
		if(files!=null && files.size()>0){
			for(File file:files){
				FileBody fb = new FileBody(file, ContentType.DEFAULT_BINARY);
				
				String fileName = file.getName();
                builder.addPart(fileName, fb);
			}
		}

//构成总的内容
		builder.setContentType(ContentType.MULTIPART_FORM_DATA);
		HttpEntity data = builder.build();



//提交
HttpUriRequest request = RequestBuilder.post(url.toString()).setEntity(data).build();

CloseableHttpResponse response = httpClient.execute(request);

 

遇到的问题

文件名乱码

网上很多代码使用的是BROWSER_COMPATIBLE。 这样子是ASICII字符,不支持中文了。需要改为使用RFC6532。

 

MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);

  

响应http 411

转发的时候响应了HTTP 411。网上搜索了较多的解决方案,最终解决问题。这里需要设置几个地方。

 

nginx.conf 设置更大的client_max_body_size。 默认这个配置是没有内容的。

 

网关系统基于springMVC, MultipartHttpServletRequest请求。需要下面的方式重载一下,设置content-length

		if(fileMap!=null && fileMap.size()>0){
			for(String filename:fileMap.keySet()){
				final MultipartFile mf = fileMap.get(filename);
				
				 InputStreamBody inputStreamBody = new InputStreamBody(mf.getInputStream(), filename){
			            @Override
			            public long getContentLength(){return mf.getSize();}
			    };				
				
                builder.addPart(filename, inputStreamBody);
			}
		}

  

文本中文乱码

就是addPart的时候, 每个部分都有不同的content-type。

// 提交的各个部门有不同的contentType。根据contentType设置字符集。
StringBody contentBody = new StringBody(reqJson,ContentType.APPLICATION_JSON);

 

posted on 2019-07-08 15:10  Emmerich.Luang  阅读(8195)  评论(0编辑  收藏  举报

导航