HttpClient 请求参数中文编码问题

来源:互联网 发布:手机乐器软件架子鼓 编辑:程序博客网 时间:2024/06/02 02:17
  • 目录

  • 问题
  • 问题分析

问题

首先看下我们正常使用HttpClient作POST请求的处理方法

public static String doHttpPost(String url, JSONObject params)            throws IOException {    CloseableHttpClient httpclient = HttpClients.createDefault();    try {        HttpPost httpPost = new HttpPost(url);        List<NameValuePair> nvps = new ArrayList<NameValuePair>();        params.forEach((key, value) -> {            if (value != null) {                nvps.add(new BasicNameValuePair(key, String.valueOf(value)));            } else {                nvps.add(new BasicNameValuePair(key, ""));            }        });        HttpEntity reqEntity = EntityBuilder                .create()                .setContentEncoding('UTF-8")                .setParameters(nvps).build();        httpPost.setEntity(reqEntity);        CloseableHttpResponse response = httpclient.execute(httpPost);        HttpEntity entity = response.getEntity();        String result = null;        if (entity != null) {            result = EntityUtils.toString(entity, "UTF-8");        }        EntityUtils.consume(entity);        response.close();        return result;    } finally {        httpclient.close();    }}

初看之下没有问题,平时使用也经常看不出问题(因为程序员在作请求都会本能规避请求参数中含有中文内容),但是一旦传参params含有中文,就会在收到的请求中看到???这种分分钟让程序猿高潮的东西!因为setContentEncoding('UTF-8")这一句根本没起作用


问题分析

请求参数的处理主要集中在下面这部分

HttpEntity reqEntity = EntityBuilder.create().setContentEncoding('UTF-8").setParameters(nvps).build();

可以看出是典型的装饰者模式,通过Maven查看EntityBuilder源码中的build()函数如下:

public HttpEntity build() {    final AbstractHttpEntity e;    //......    else if (this.parameters != null) {        e = new UrlEncodedFormEntity(this.parameters,                this.contentType != null ? this.contentType.getCharset() : null);    }    //......    e.setContentEncoding(this.contentEncoding);    //......    return e;}

可以看到,这个setContentEncoding不是设置请求参数编码的,参数编码设置是e = new UrlEncodedFormEntity(this.parameters,this.contentType != null ? this.contentType.getCharset() : null);这一句完成的,所以参数编码要用setContentType()来设置。再来看ContentType的源码

public static final ContentType APPLICATION_ATOM_XML = create(            "application/atom+xml", Consts.ISO_8859_1);public static final ContentType APPLICATION_FORM_URLENCODED = create(        "application/x-www-form-urlencoded", Consts.ISO_8859_1);public static final ContentType APPLICATION_JSON = create(        "application/json", Consts.UTF_8);public static final ContentType APPLICATION_OCTET_STREAM = create(        "application/octet-stream", (Charset) null);public static final ContentType APPLICATION_SVG_XML = create(        "application/svg+xml", Consts.ISO_8859_1);public static final ContentType APPLICATION_XHTML_XML = create(        "application/xhtml+xml", Consts.ISO_8859_1);public static final ContentType APPLICATION_XML = create(        "application/xml", Consts.ISO_8859_1);public static final ContentType MULTIPART_FORM_DATA = create(        "multipart/form-data", Consts.ISO_8859_1);public static final ContentType TEXT_HTML = create(        "text/html", Consts.ISO_8859_1);public static final ContentType TEXT_PLAIN = create(        "text/plain", Consts.ISO_8859_1);public static final ContentType TEXT_XML = create(        "text/xml", Consts.ISO_8859_1);public static final ContentType WILDCARD = create(        "*/*", (Charset) null);

尼玛,固有的全是ISO_8859_1,要中文啊,还好有ContentType.create(mimeType, charset)可以用,所以最终完成的代码如下:

public static String doHttpPost(String url, JSONObject params)            throws IOException {    CloseableHttpClient httpclient = HttpClients.createDefault();    try {        HttpPost httpPost = new HttpPost(url);        List<NameValuePair> nvps = new ArrayList<NameValuePair>();        params.forEach((key, value) -> {            if (value != null) {                nvps.add(new BasicNameValuePair(key, String.valueOf(value)));            } else {                nvps.add(new BasicNameValuePair(key, ""));            }        });        HttpEntity reqEntity = EntityBuilder                .create()                .setContentType(                        ContentType.create(                                "application/x-www-form-urlencoded",                                Consts.UTF_8)).setParameters(nvps).build();        httpPost.setEntity(reqEntity);        CloseableHttpResponse response = httpclient.execute(httpPost);        HttpEntity entity = response.getEntity();        String result = null;        if (entity != null) {            result = EntityUtils.toString(entity, "UTF-8");        }        EntityUtils.consume(entity);        response.close();        return result;    } finally {        httpclient.close();    }}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新疆办理暂住证有案底不办给怎么办 我的驾驶证吊销了车年审怎么办 好几个超速分不够扣了怎么办 刚拿c1驾照扣6分怎么办 别人开我车扣12分怎么办 办健康证大便拉不出来怎么办 欠信用卡钱被网上通缉抓到后怎么办 上海房子卖了户口没地方迁怎么办 没有户口本在北京身份证丢了怎么办 武汉科目四考试居住证过期了怎么办 农行卡密码输错3次怎么办 驾照罚款缴纳了网上没消怎么办 外地驾驶证分数扣12分了怎么办 有生产日期的赠品在超市过期怎么办 6年免检车辆逾期未年检怎么办 行驶证检验有效期过期2年怎么办 骑摩托车忘带驾驶证和行驶证怎么办 驾驶证逾期未审验怎么办有什么后果 车祸至人腿部骨折沒钱偿还的怎么办 我有c4驾驶证想办c3怎么办 驾驶证和行驶证被交警扣了怎么办 行驶证被交警弄丢了怎么办 没带行驶证让警察发现怎么办 首尔转机换票换乘怎么办过境签证 驾驶证约考帐号与登密码丢失怎么办 考驾照的时候预约密码忘了怎么办 考驾照的预约密码忘了怎么办 摩托车不能挂档不能摘挡了怎么办 身份证丢失了派出所不给挂失怎么办 快递员在中午还送货夏天怎么办啊 驾照一个记分周期扣满12分怎么办 佛山南海车管所怎么办替人消分流程 福州快处中心几流程要怎么办 被对方追尾了对方只有交强险怎么办 摩托车行驶证年检过期一年半怎么办 户口迁到杭州了身份证掉了怎么办 户口已迁至外面要补办结婚证怎么办 汽车年检时间过了1个月怎么办 户口在老家在北京工作怎么办招工 报考驾照时手机号留错了怎么办 合肥驾照换证体检没过怎么办