/**
 * HTTP 请求工具类
 */
public class HttpUtil {
    /**
     * 针对微信发送请求,前置需要使用证书,如果不需要使用证书请不要使用这个接口
     * @param apiUrl
     * @param data<XML格式>
     * @param cert 使用的证书路径
     * @param mchId 证书密码默认为您的商户ID(如:10010000)
     * @return
     */
    public static String doPostByWXSSL(String url, String data, String certPath, String mchId) {
        StringBuffer message = new StringBuffer();
        try {
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(certPath));//使用的证书
            keyStore.load(instream, mchId.toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, mchId.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            HttpPost httpost = new HttpPost(url);
 
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            System.out.println("executing request" + httpost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println("--------------------发送微信接收参数开始--------------------");
                System.out.println("请求响应状态:" + response.getStatusLine());
                if (entity != null) {
                    System.out.println("响应字节总长度: " + entity.getContentLength());
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                        message.append(text);
                    }
                }
                System.out.println("--------------------发送微信接收参数结束--------------------");
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                response.close();
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return message.toString();
 
    }
 
}
 
 
 
public class WXRedPacket{
 
    /**
     * 调用微信发送红包接口
     * 微信官方接口文档说明2018年1月4日:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1
     * 微信调用结果成功返回案例2018年1月4日:
     * <xml> 
     * <return_code><![CDATA[SUCCESS]]></return_code> 
     * <return_msg><![CDATA[发放成功.]]></return_msg> 
     * <result_code><![CDATA[SUCCESS]]></result_code> 
     * <err_code><![CDATA[0]]></err_code> 
     * <err_code_des><![CDATA[发放成功.]]></err_code_des> 
     * <mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno> 
     * <mch_id>10010404</mch_id> 
     * <wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid> 
     * <re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid> 
     * <total_amount>1</total_amount> 
     * </xml> 
     * 微信调用结果失败返回案例2018年1月4日:
     * <xml> 
     * <return_code><![CDATA[FAIL]]></return_code> 
     * <return_msg><![CDATA[系统繁忙,请稍后再试.]]></return_msg> 
     * <result_code><![CDATA[FAIL]]></result_code> 
     * <err_code><![CDATA[268458547]]></err_code> 
     * <err_code_des><![CDATA[系统繁忙,请稍后再试.]]></err_code_des> 
     * <mch_billno><![CDATA[0010010404201411170000046542]]></mch_billno> 
     * <mch_id>10010404</mch_id> 
     * <wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid> 
     * <re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid> 
     * <total_amount>1</total_amount> 
     * </xml> 
     * @param RequestHandler
     * @return
     */
    public void sendRedPacket(RequestHandler rh) {
        // TODO Auto-generated method stub
        Map<String, String> result = new HashMap<String, String>();
        try {
            String sign = rh.createMd5Sign("key", "秘钥");//key,秘钥和值根据微信加密规则加密签名
            rh.setParameter("sign", sign);//设置签名到请求参数中
            String data = rh.parseXML();//调用现金红包接口需要的数据XML格式
            String xmlResult = HttpUtil.doPostByWXSSL("接口地址", data, "证书路径", "mchid");//现金红包接口返回的xml
            System.out.println("调用微信接口返回数据:" + xmlResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    @Test
    public void test1() {
        RequestHandler rh = new RequestHandler();
        rh.setParameter("nonce_str", "");//随机字符串,不长于32位
        rh.setParameter("mch_billno", "");//商户订单号(每个订单号必须唯一)组成:mch_id+yyyymmdd+10位一天内不能重复的数字。接口根据商户订单号支持重入,如出现超时可再调用。
        rh.setParameter("mch_id", "");//微信支付分配的商户号
        rh.setParameter("wxappid", "");//微信分配的公众账号ID(企业号corpid即为此appId)。接口传入的所有appid应该为公众号的appid(在mp.weixin.qq.com申请的),不能为APP的appid(在open.weixin.qq.com申请的)。 
        rh.setParameter("send_name", "");//商户名称
        rh.setParameter("re_openid", "");//用户openid  接受红包的用户用户在wxappid下的openid
        rh.setParameter("total_amount", "");//付款金额 单位分
        rh.setParameter("total_num", "");//红包发放总人数
        rh.setParameter("wishing", "");//红包祝福语
        rh.setParameter("client_ip", "");//Ip地址
        rh.setParameter("act_name", "");//活动名称
        rh.setParameter("remark", "");//备注
        rh.setParameter("scene_id", "");//场景id,发放红包使用场景,红包金额大于200时必传,PRODUCT_1:商品促销 ,PRODUCT_2:抽奖 ,PRODUCT_3:虚拟物品兑奖  ,PRODUCT_4:企业内部福利 ,PRODUCT_5:渠道分润 ,PRODUCT_6:保险回馈 ,PRODUCT_7:彩票派奖 ,PRODUCT_8:税务刮奖
        rh.setParameter("risk_info", "");//活动信息,posttime:用户操作的时间戳 ,mobile:业务系统账号的手机号,国家代码-手机号。不需要+号 ,deviceid :mac 地址或者设备唯一标识  ,clientversion :用户操作的客户端版本 ,把值为非空的信息用key=value进行拼接,再进行urlencode ,urlencode(posttime=xx& mobile =xx&deviceid=xx)
        rh.setParameter("consume_mch_id", "");//资金授权商户号,服务商替特约商户发放时使用
 
        sendRedPacket(rh);
 
    }
 
}