1. ホーム

MultipartEntityBuilder 転送添付ファイルに関する注意事項

2022-03-22 10:50:22

先週、このMultipartEntityBuilderを使い、数日経ってようやくチューニングしました。ようやく動くようになった。

なぜこのMultipartEntityBuilderを使用するのか?

 本来の動作は以下の通りです。

OAは会社の基幹データであり、イントラネットでしかアクセスできない。そして、転送の踏み台としてゲートウェイシステムを追加し、権限制約を設ける。

うまくいっていたのに、新たな要件として 外部事業者がワークフローを作成し、添付ファイルをアップロードできるようにする。 . 元の httpClient のフォームポスト json ベースのアプローチでは、添付ファイルをサポートしていませんでした。そこで、MultipartEntityBuilderを追加して、添付ファイルのアップロードをサポートするようにしました。

フォーム送信のようなアプローチに

フォームポスト 

データです。{...}

ファイル...

ファイル...

ファイル...

使用方法

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);



//text content
StringBody contentBody = new StringBody(jsonContent,ContentType.APPLICATION_JSON);
		builder.addPart("data", contentBody);

//files
		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);
			}
		}

//constitute the total content
		builder.setContentType(ContentType.MULTIPART_FORM_DATA);
		HttpEntity data = builder.build();



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

CloseableHttpResponse response = httpClient.execute(request);


問題点

ファイル名が文字化けする

Web上の多くのコードでは、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);
			}
		}


テキスト中国語の混乱

ただ、パーツを追加したときに、パーツごとにcontent-typeが異なるんです。

// Each part of the submission has a different contentType. set the character set based on the contentType.
StringBody contentBody = new StringBody(reqJson,ContentType.APPLICATION_JSON);