如何在JSON POST请求中发送字节数组?

8

我有一个接收 byte[] serialData 的WCF服务,现在我正在开发一个需要调用相同方法的Java客户端。

当我将字节数组作为JSON POST请求发送到服务时,它会抛出一个异常,如下所示:java.io.IOException: Server returned HTTP response code: 400

以下是我的代码:

WCF 方法:

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "saveSerialNumbers", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
Dictionary<string, object> saveSerialNumbers(byte[] serialData);

Java客户端:

for (int i = 1; i < 100; i++) {      
                sb.append(String.valueOf(gen()));
    }
byte[]   bytesEncoded = Base64.encodeBase64(sb.toString().getBytes());
String json = "{\"serialDataByte\":\""+sb.toString()+"\"}";

这是我的post请求方法:

public String getResultPOST(String jsonObject,String uri,String method) throws Exception{
        try {
            URL url = new URL(uri+method);
            System.out.println(url.toString());
            URLConnection connection = url.openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            OutputStreamWriter out;
            try {
                out = new OutputStreamWriter(connection.getOutputStream());
                  out.write(jsonObject);
                    out.close();
            } catch (Exception e) {
                /
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            String line = "";
            StringBuilder builder = new StringBuilder();
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            while ((line = in.readLine()) != null) {
                builder.append(line);
            }

            in.close();
            return builder.toString();
        } catch (Exception e) {
            throw e;
            //here is the exception
        }
    }

这是我的方法调用:

 String json = "{\"serialData\":\""+ new String(bytesEncoded)  +"\",\"guProductID\":\""+guProductID+"\",\"guStoreID\":\""+guStoreID+"\",\"securityToken\":\""+SecurityToken+"\"}";
 String serialContract  = serialClient.getResultPOST(json, "http://localhost:3361/EcoService.svc/Json/", "saveSerialNumbers");

为什么你在客户端将base64字符串转换为字节?尝试不要在客户端中将字符串转换为字节,也不要将字节转换为字符串。发送从编码器获取的base64字符串。 - user784540
1
我指的是 String json = "{\"serialDataByte\":\"" + new String(bytesEncoded) + "\"}"; - user784540
1
@RafaelOsipov 谢谢,我会尝试的。 - Sajeetharan
1
在你的代码中,你发送了未转换的字符串,因为sb缓冲区包含未转换的字符串。在我的代码中,由于你已经获得了一个base64编码字节的byte[]数组,你可以组成一个base64字符串并将其包含在你的json中。 - user784540
@RafaelOsipov,对我来说仍然没有起作用! - Sajeetharan
显示剩余2条评论
1个回答

12

下面是一个简单的工作原型,用于从字符串实例生成json。使用此代码片段更新您的客户端部分。它应该可以正常工作。

import java.util.Base64;

public class Test {

    public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();

        // composing string to be encoded
        sb.append("Part 1 of some text to be encoded to base64 format\n");
        sb.append("Part 2 of some text to be encoded to base64 format\n");
        sb.append("Part 3 of some text to be encoded to base64 format");


        // getting base64 encoded string bytes
        byte[]   bytesEncoded = Base64.getEncoder().encode(sb.toString().getBytes());

        // composing json
        String json = "{\"serialDataByte\":\""+ new String(bytesEncoded) +"\"}";        

        System.out.println(json);

    }
}

更新:

该代码使用Java 8 SDK。如果您使用的是Java8之前的版本,则可以考虑使用Apache Commons Codec来完成此任务。

下面是一个示例代码,它使用Apache Commons Codec进行Base64编码(请注意导入指令已更改):

import org.apache.commons.codec.binary.Base64;

public class Test {

    public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();

        // composing string to be encoded
        sb.append("Part 1 of some text to be encoded to base64 format\n");
        sb.append("Part 2 of some text to be encoded to base64 format\n");
        sb.append("Part 3 of some text to be encoded to base64 format");


        // getting base64 encoded string bytes
        byte[] bytesEncoded =  Base64.encodeBase64(sb.toString().getBytes());

        // composing json
        String json = "{\"serialDataByte\":\""+ new String(bytesEncoded) +"\"}";        

        System.out.println(json);

    }
}

更新2:

发送POST请求时,请确保将您的请求标记为POST请求。在发送请求之前,不要忘记这一行代码:

connection.setRequestMethod("POST");

使用HttpURLConnection而不是URLConnection:

import java.net.HttpURLConnection;

代码使用Java 8 SDK。你使用哪个Java版本? - user784540
1
仍然无法工作,这是我的JSon对象 {"serialData":"MTAzNDcxMDM0NzEwMzQ3MTAzNDcxMDM0NzEwMzQ3MTAzNDcxMDM0NzEwMzQ3","guProductID":"123456789","guStoreID":"123456","securityToken":"57b998ef02afa6957b94bd476c00e469"} - Sajeetharan
@rafeal 是的,java.io.IOException: 服务器返回 HTTP 响应代码: 400,URL 为:http://localhost:3361/EcoService.svc/Json/saveSerialNumbers。 - Sajeetharan
没有调用connection.setRequestMethod("POST");。确保将请求类型设置为POST。因为默认情况下,HTTP请求会发送为GET请求。似乎您的请求大小超过了GET请求限制,因此出现了HTTP 400错误。 - user784540
我对WCF并不熟悉。似乎服务器端有些问题,可能是服务器设置的问题。按照我之前的评论所提到的,制作一个简单的servlet来检查您的POST请求,以确保一切正常。 - user784540
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接