base64出现空格问题的解决方案

文章出处链接: http://www.devcheng.net/post/54aeaf8d.html
使用背景
项目中有一个参数是 byte[],在构建 http请求的时候不便参数的传输,于是就想到了 使用base64进行编码之后当成字符串进行传输。
接下来就用自己写了一个http工具类,代码如下(片段):

/**
 * 参数方式post发送 .
 *
 * @param simpleHttpRequest 请求
 * @return 响应
 */
public static SimpleHttpResponse post(SimpleHttpRequest simpleHttpRequest) {
    try {
        HttpClient httpClient = buildHttpClient(simpleHttpRequest);
        PostMethod method = new PostMethod(simpleHttpRequest.getUrl());
        method.addRequestHeader("Connection", "close"); // 服务端应答完毕自动关闭连接
        method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        if (simpleHttpRequest.getHttpHeader() != null) {
            for (Map.Entry<String, String> entry : simpleHttpRequest.getHttpHeader().entrySet()) {
                method.addRequestHeader(entry.getKey(), entry.getValue());
            }
        }
        if (simpleHttpRequest.getParams() != null && simpleHttpRequest.getParams().size() > 0) {
            NameValuePair[] nameValuePairs = new NameValuePair[simpleHttpRequest.getParams().size()];
            int i = 0;
            for (Map.Entry<String, Object> entry : simpleHttpRequest.getParams().entrySet()) {
                nameValuePairs[i++] = new NameValuePair(entry.getKey(), (String) entry.getValue());
            }
            method.addParameters(nameValuePairs);
            String content = StringUtils.parseMapToParamsStr(simpleHttpRequest.getParams());
            RequestEntity requestEntity = new ByteArrayRequestEntity(content.getBytes("UTF-8"));
            method.setRequestEntity(requestEntity);
        }

        int status = httpClient.executeMethod(method);
        String response = null;
        if (status == HttpStatus.SC_OK) {
            response = method.getResponseBodyAsString();
        }

        return new SimpleHttpResponse(status, response);
    } catch (HttpException e) {
        throw new RuntimeException(e.getMessage(), e);
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }

}

项目启动之后,参数都传递过去了,没什么毛病。但是呢,会出现一个问题,byte[] 用base64编码之后可能会出现一些 “+” 加号,使用自定义的 httpUtils 请求的时候,会把 “+” 变成空格。

使用base64编码之后的 byte[]字符串
问题的原因找到了,那接下来如何解决呢?
解决方案
解决方案 一

将加密后的空格全部替换为 ‘+’ 号,replace(“ “, “+”);
或者,将将加密后的字符串替换为 “%2B”, 再将 “%2B”替换回 ‘+’ 号,replace(“%2B”, “+”)
解决方案 二
使用 post方式提交的时候,参数为 json形式。
具体代码如下:

/**
 *  post请求 json参数
 * @param url 请求地址
 * @param params json参数
 * @return
 */
public static String doPost(String url, JSONObject params){
    String strResult = "";
    // 1. 获取默认的client实例
    CloseableHttpClient client = HttpClients.createDefault();
    // 2. 创建httppost实例
    HttpPost httpPost = new HttpPost(url);
    httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
    try {
        httpPost.setEntity(new StringEntity(params.toJSONString(),"utf-8"));
        CloseableHttpResponse resp = client.execute(httpPost);
        try {
            // 7. 获取响应entity
            HttpEntity respEntity = resp.getEntity();
            strResult = EntityUtils.toString(respEntity, "UTF-8");
        } finally {
            resp.close();
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return strResult;
}

使用 post请求json参数这个方法,具体代码:

String url = "http://127.0.0.1:8080/v1/auth";
JSONObject params = new JSONObject();
params.put("type",String.valueOf(userType));
params.put("data",encodeData);
params.put("user",userName);
String responseBody = HttpUtils.doPost(url, params);

以上两种解决方法,均可以解决这个问题。

base64编码,解码我用的是 sun.misc.BASE64Decoder
开始我还以为 切换成 其他的 base64 类库就不会有这个问题,我尝试了Apache Commons Codec的Base64 然后编码出来的字符串是一样的。

HTTP上传base64编码字符"+"变空格的问题

通过HTTP上传二进制数据可以先使用base64编码将二进制数据变成字符串上传,但是如果编码后的字符串含符号“+”,服务端接收到的就变成了空格,有一种解决的办法就是将base64字符串再调用UrlEncode编码,服务端解码就可以得到正确的数据
URLEncoder.encode(data)处理一下data数据即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值