gpt4 book ai didi

java - 如何构造正确的 MultipartEntity 以在 java 中发送多部分/相关请求?

转载 作者:太空宇宙 更新时间:2023-11-04 09:55:26 27 4
gpt4 key购买 nike

我想从本地计算机发送到 OCR 图像,而不是发送到带有图像的远程 URL(这种情况效果很好)。但问题是,我不知道如何正确构造多部分实体的有效负载。我的有效负载应该如下所述。

这就是 documentation of API 中描述的内容。解码多部分/相关数据中直接给出的图像数据。顺序很重要,第一部分应该是 JSON,它告诉它要使用哪个 OCR 引擎。 JSON 的架构记录在 /ocr 端点中。在这种情况下,JSON 的 img_url 参数将被忽略。

图像附件应该是第二部分,并且它应该适用于任何图像内容类型(例如,image/png、image/jpg等)。

   Request (multipart/related; boundary=---BOUNDARY)

-----BOUNDARY
Content-Type: application/json

{"engine":"tesseract"}
-----BOUNDARY

-----BOUNDARY
Content-Disposition: attachment;
Content-Type: image/png
filename="attachment.txt".

PNGDATA.........
-----BOUNDARY

这是我尝试过的。为了执行多部分/相关请求,我使用 org.apache.httpcomponents

    CloseableHttpClient httpClient = HttpClients.createDefault();

MultipartEntityBuilder multipartEntityBuilder =
MultipartEntityBuilder.create().setBoundary(BOUNDARY).setContentType(ContentType.APPLICATION_JSON).addTextBody("engine", "tesseract")
.setBoundary(BOUNDARY).setBoundary(BOUNDARY);

multipartEntityBuilder.addBinaryBody("file_upload", new File(fileTextPath), ContentType.create(CONTENT_TYPE), fileTextPath).setBoundary(BOUNDARY);

HttpEntity entity = multipartEntityBuilder.build();


HttpPost httpPost = new HttpPost(URL);
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_MULTIPART+";boundary="+BOUNDARY);
httpPost.setEntity(entity);

最佳答案

我几周前解决了这个问题,为了方便起见,我创建了一个 lightweight java web application对于这两种情况(远程和文件上传)。

您可以找到上述问题的具体答案here 。多部分请求的源代码如下所示:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class MultipartUtility {
private static final Logger logger = LoggerFactory.getLogger(MultipartUtility.class);

private final String boundary = UUID.randomUUID().toString();
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;

/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @param charset
* @throws IOException
*/
public MultipartUtility(String requestURL, String charset) {
this.charset = charset;

try {
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type", "multipart/related; boundary=\"" + boundary + "\"");
httpConn.setRequestProperty("Accept-Encoding", "gzip");
outputStream = httpConn.getOutputStream();
//outputStream = System.out;
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
} catch (IOException ex) {
logger.error("Error during creation of MultiPart: ", ex);
}
}

/**
* Adds a form field to the request
*/
public void addFormField(String jsonBody) {
writer.append("--").append(boundary).append(LINE_FEED);
writer.append("Content-Type: application/json;").append(LINE_FEED);
writer.append(LINE_FEED);
writer.append(jsonBody).append(LINE_FEED);
writer.flush();
}

/**
* Adds a upload file section to the request
*
* @param uploadFile a File to be uploaded
* @throws IOException
*/
public void addFilePart(File uploadFile) {
String fileName = uploadFile.getName();
writer.append("--").append(boundary).append(LINE_FEED);
writer.append("Content-Disposition: attachment;");
writer.append(" filename=\"" + fileName + "\".").append(LINE_FEED);
writer.append("Content-Type: image/*").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();

try {
FileInputStream inputStream = new FileInputStream(uploadFile);
//byte[] buffer = new byte[(int) uploadFile.length()];
byte[] buffer = Files.readAllBytes(Paths.get(uploadFile.getPath()));
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
} catch (IOException ex) {
logger.error("File transformation to bytes went wrong: {}", ex);
}

writer.append(LINE_FEED);
writer.flush();
}

/**
* Adds a header field to the request.
*
* @param name - name of the header field
* @param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}

/**
* Completes the request and receives response from the server.
*
* @return a list of Strings as response in case the server returned
* status OK, otherwise an exception is thrown.
* @throws IOException
*/
public String finish() {
String response = "";
int status = 0;

writer.flush();
writer.append("--").append(boundary).append("--").append(LINE_FEED);
writer.println();
writer.close();

try {
// checks server's status code first
status = httpConn.getResponseCode();

if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));

String line;
while ((line = reader.readLine()) != null) {
response += line;
}

reader.close();
httpConn.disconnect();
} else {
logger.error("OCR API returned error stream: {}", printErrorStream());
throw new IOException("Server returned non-OK status: " + status + " : " + httpConn.getResponseMessage());
//logger.error("Server returned non-OK status: " + status + " : " + httpConn.getResponseMessage());
}
} catch(IOException ex) {
logger.error("Response message in Multipart finish has been received with problems: ", ex);
}

return response;
}

private String printErrorStream() throws IOException {
//System.out.print("DEBUG System out ocr API error stream: ");
InputStream errorStream = httpConn.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
String errLine = "", tempLine;
while ((tempLine = reader.readLine()) != null) {
errLine += tempLine;
}

return errLine;
}

private void getRequestHeaders(HttpURLConnection httpURLConnection) {
for (Map.Entry<String, List<String>> entries : httpURLConnection.getRequestProperties().entrySet()) {
String values = "";
for (String value : entries.getValue()) {
values += value + ",";
}
System.out.println("Request" + " " + entries.getKey() + " - " + values );
}
}
}

关于java - 如何构造正确的 MultipartEntity 以在 java 中发送多部分/相关请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54211988/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com