利用支付宝的团队编写的 HttpProtocolHandler 、StringRequestEntity 调用微信 支付引发的 body不是UTF8编码的

来源:互联网 发布:大数据的关键技术 编辑:程序博客网 时间:2024/05/04 09:03


HttpProtocolHandler 代码修改后的代码如下


package com.whb.common.util.httpclient;import java.io.File;import java.io.IOException;import java.net.URLEncoder;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.List;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpConnectionManager;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.HttpMethod;import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;import org.apache.commons.httpclient.NameValuePair;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.PostMethod;import org.apache.commons.httpclient.methods.StringRequestEntity;import org.apache.commons.httpclient.methods.multipart.FilePart;import org.apache.commons.httpclient.methods.multipart.FilePartSource;import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;import org.apache.commons.httpclient.methods.multipart.Part;import org.apache.commons.httpclient.methods.multipart.StringPart;import org.apache.commons.httpclient.params.HttpMethodParams;import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;import org.apache.http.entity.StringEntity;import org.apache.log4j.Logger;import com.whb.common.util.Util;/* * *类名:HttpProtocolHandler *功能:HttpClient方式访问 *详细:获取远程HTTP数据 *版本:3.3 *日期:2012-08-17 *说明: *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 */public class HttpProtocolHandler {private static Logger log = Logger.getLogger(HttpProtocolHandler.class);     private static String              DEFAULT_CHARSET                     = "utf-8";    /** 连接超时时间,由bean factory设置,缺省为8秒钟 */    private int                        defaultConnectionTimeout            = 8000;    /** 回应超时时间, 由bean factory设置,缺省为30秒钟 */    private int                        defaultSoTimeout                    = 30000;    /** 闲置连接超时时间, 由bean factory设置,缺省为60秒钟 */    private int                        defaultIdleConnTimeout              = 60000;    private int                        defaultMaxConnPerHost               = 30;    private int                        defaultMaxTotalConn                 = 80;    /** 默认等待HttpConnectionManager返回连接超时(只有在达到最大连接数时起作用):1秒*/    private static final long          defaultHttpConnectionManagerTimeout = 3 * 1000;    /**     * HTTP连接管理器,该连接管理器必须是线程安全的.     */    private HttpConnectionManager      connectionManager;    private static HttpProtocolHandler httpProtocolHandler                 = new HttpProtocolHandler();    /**     * 工厂方法     *      * @return     */    public static HttpProtocolHandler getInstance() {        return httpProtocolHandler;    }    /**     * 私有的构造方法     */    private HttpProtocolHandler() {        // 创建一个线程安全的HTTP连接池        connectionManager = new MultiThreadedHttpConnectionManager();        connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost);        connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn);        IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread();        ict.addConnectionManager(connectionManager);        ict.setConnectionTimeout(defaultIdleConnTimeout);        ict.start();            }    /**     * 执行Http请求     *      * @param request 请求数据     * @param strParaFileName 文件类型的参数名     * @param strFilePath 文件路径     * @return      * @throws HttpException, IOException      */    public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath) throws HttpException, IOException {        HttpClient httpclient = new HttpClient(connectionManager);                       // 设置连接超时        int connectionTimeout = defaultConnectionTimeout;        if (request.getConnectionTimeout() > 0) {            connectionTimeout = request.getConnectionTimeout();        }        httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);        // 设置回应超时        int soTimeout = defaultSoTimeout;        if (request.getTimeout() > 0) {            soTimeout = request.getTimeout();        }        httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);        // 设置等待ConnectionManager释放connection的时间        httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);        String charset = request.getCharset();        charset = charset == null ? DEFAULT_CHARSET : charset;        HttpMethod method = null;        //get模式且不带上传文件        if (request.getMethod().equals(HttpRequest.METHOD_GET)) {            method = new GetMethod(request.getUrl());            method.getParams().setCredentialCharset(charset);            // parseNotifyConfig会保证使用GET方法时,request一定使用QueryString            method.setQueryString(request.getQueryString());        } else if(strParaFileName.equals("") && strFilePath.equals("")) {        //post模式且不带上传文件            method = new PostMethod(request.getUrl());                        ((PostMethod) method).addParameters(request.getParameters());            method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);                                    String body=request.getBody();                        /**             * 如果没有这样设置 默认编码格式是 ISO-8859-1 向微信发送请求会有问题             */            method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);            if(!Util.isEmpty(body))            ((PostMethod) method).setRequestEntity(new StringRequestEntity(body,"text/html",charset));        }        else {        //post模式且带上传文件            method = new PostMethod(request.getUrl());            List<Part> parts = new ArrayList<Part>();            for (int i = 0; i < request.getParameters().length; i++) {            parts.add(new StringPart(request.getParameters()[i].getName(), request.getParameters()[i].getValue(), charset));            }            //增加文件参数,strParaFileName是参数名,使用本地文件            parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath))));                        // 设置请求体            ((PostMethod) method).setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams()));        }        // 设置Http Header中的User-Agent属性        method.addRequestHeader("User-Agent", "Mozilla/4.0");        HttpResponse response = new HttpResponse();        try {            httpclient.executeMethod(method);            if (request.getResultType().equals(HttpResultType.STRING)) {                response.setStringResult(method.getResponseBodyAsString());            } else if (request.getResultType().equals(HttpResultType.BYTES)) {                response.setByteResult(method.getResponseBody());            }            response.setResponseHeaders(method.getResponseHeaders());        } catch (UnknownHostException ex) {            return null;        } catch (IOException ex) {            return null;        } catch (Exception ex) {            return null;        } finally {            method.releaseConnection();        }        return response;    }    /**     * 将NameValuePairs数组转变为字符串     *      * @param nameValues     * @return     */    protected String toString(NameValuePair[] nameValues) {        if (nameValues == null || nameValues.length == 0) {            return "null";        }        StringBuffer buffer = new StringBuffer();        for (int i = 0; i < nameValues.length; i++) {            NameValuePair nameValue = nameValues[i];            if (i == 0) {                buffer.append(nameValue.getName() + "=" + nameValue.getValue());            } else {                buffer.append("&" + nameValue.getName() + "=" + nameValue.getValue());            }        }        return buffer.toString();    }}



修改过的代码:

原先不支持 Post for body 后来 我加了 如下 ,如下代码 会引发微信 支付引发的 body不是UTF8编码的,但如果用Main发送请求是正常的


            method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);            if(!Util.isEmpty(body))            ((PostMethod) method).setRequestEntity(new StringRequestEntity(body));

但对 StringRequestEntity 用的不多,后来修改如下:


            method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);            if(!Util.isEmpty(body))            ((PostMethod) method).setRequestEntity(new StringRequestEntity(body,"text/html",charset));




1 0
原创粉丝点击