【问题标题】:How to construct correct MultipartEntity to send a multipart/related request in java?如何构造正确的 MultipartEntity 以在 java 中发送多部分/相关请求?
【发布时间】:2019-01-16 07:11:06
【问题描述】:

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

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

图片附件应该是second 部分,它应该适用于任何图片内容类型(例如,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);

【问题讨论】:

    标签: java apache-httpcomponents multipart-mixed-replace


    【解决方案1】:

    我在几周前解决了这个问题,为了方便起见,我为这两种情况(远程和文件上传)创建了一个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 );
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-22
      • 2011-02-06
      • 2020-03-15
      • 1970-01-01
      • 2020-12-11
      • 2019-08-16
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多