【问题标题】:Sending base64 image via http request in Java miss up some chars在 Java 中通过 http 请求发送 base64 图像会丢失一些字符
【发布时间】:2020-04-28 10:57:09
【问题描述】:

我一直在尝试使用javaNodeJS API 发送base64 图像,经过几个小时的工作和搜索,我不知道是什么导致了以下问题,问题如下:

在 nodejs 中记录 base64 图像后,我看到所有 + 字符都替换为 space

这是Java中原始base64的一部分

f8A0NH2qH+/+hooouAfaof7/wCho+1Q/

这是NodeJS中收到的图片的一部分

f8A0NH2qH / hooouAfaof7/wCho 1Q/

我尝试通过POSTMAN 发送图像,完全没有问题。

所有步骤如下:

1- 我正在使用以下 sn-p 将图像转换为 base64

public static String imgToBase64String(final RenderedImage img, final String formatName) {
        final ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(img, formatName, Base64.getEncoder().wrap(os));
            return os.toString(StandardCharsets.ISO_8859_1.name());
        } catch (final IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    }

    public static BufferedImage base64StringToImg(final String base64String) {
        try {
            return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(base64String)));
        } catch (final IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    }

并截图

    final Robot robot = new Robot();
    final Rectangle r = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    final BufferedImage bi = robot.createScreenCapture(r);
    final String base64String = Base64Converter.imgToBase64String(bi, "jpg");

2- 我正在使用Gson 库来字符串化对象

3- 我在NodeJS 中使用bodyParser

4- 发送HTTP 请求为:

public static void sendPOST(String image) throws Exception {
        String POST_PARAMS = "screenShotData";
        URL obj = new URL(POST_URL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setConnectTimeout(5000); // 5 seconds
        con.setReadTimeout(5000); // 5 seconds

        Gson gson = new Gson();
        Http.ScreenShot screenShot = new ScreenShot(); // This is just a class with a string property
        screenShot.setImage(image);
        POST_PARAMS += gson.toJsonTree(screenShot).getAsJsonObject();


        con.setDoOutput(true);
        OutputStream os = con.getOutputStream();
        byte[] outputBytesArray = POST_PARAMS.getBytes();
        os.write(outputBytesArray);
        os.flush();
        os.close();


        int responseCode = con.getResponseCode();
        System.out.println("POST Response Code :: " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_OK) { //success
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            Object responseObject = gson.fromJson(response.toString(), Object.class);
            System.out.println("Res: " + responseObject);
        } else {
            System.out.println(con.getResponseMessage());
        }
    }

【问题讨论】:

    标签: java node.js base64 content-type


    【解决方案1】:

    在 URL 编码文本中,+ 字符表示空格字符。例如,

    https://example.com/?s=nodejs+bodyparser
    

    发送带有值的s参数

    nodejs bodyparser 
    

    (注意空格)。

    当你做一个普​​通的表单发布(浏览器做的那种)时,你使用application/x-www-form-urlencoded 数据类型,这意味着你的 POST 操作的负载看起来像一个查询字符串。我认为您将 JSON 对象作为文本字符串传递,而没有对其进行 url 编码。

    您可能想改用application/json 数据类型。 nodejs 的正文解析器从您的 Content-type 标头中检测到它是 JSON 并正确解析它。

    试试这个。 (未调试,抱歉。)

        string payload = gson.toJsonTree(screenShot).getAsJsonObject();
        byte[] outputBytesArray = payload.getBytes();
    
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);
        OutputStream os = con.getOutputStream();
        os.write(outputBytesArray);
        os.flush();
        os.close();
    

    【讨论】:

    • 我在添加con.setRequestProperty("Content-Type", "application/json");后得到bad request 400
    • 不管上面的评论,我已经解决了,非常感谢您的帮助,非常感谢!!!
    • 不客气。内容类型的东西可能会让 xxxx 感到头疼!
    【解决方案2】:

    您忘记关闭打包的 Base64 编码器流。只有关闭它才能写入base64编码数据的末尾:

    public static String imgToBase64String(final RenderedImage img, final String formatName) {
        final ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            try (OutputStream wrapped = Base64.getEncoder().wrap(os)) {
                ImageIO.write(img, formatName, wrapped);
            }
            return os.toString(StandardCharsets.ISO_8859_1.name());
        } catch (final IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    }
    

    【讨论】:

    • 感谢您的回答,但它并没有解决问题
    • @AbdulrahmanFalyoun 哪个问题没有解决。至少你在标题中提到的你“错过了一些字符”应该得到解决。
    • 实际上我的意思是缺少+ 字符,事实证明这是因为没有将content-type 设置为json 所以它将所有加号字符替换为空格
    【解决方案3】:

    我曾遇到过这个问题,但我无权改变课堂或其他事情。 我只是简单地用 + 替换了空格,在大多数情况下它都可以工作。

    【讨论】:

    • 这是我第一次这样做,然后意识到这会导致性能出现问题
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多