content: package com.flame.core.pay.alipay.common;
  
  import com.flame.core.pay.alipay.AlipayConfig;
  import org.apache.commons.httpclient.NameValuePair;
  import org.dom4j.Document;
  import org.dom4j.DocumentException;
  import org.dom4j.Node;
  import org.dom4j.io.SAXReader;
  
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  
  
  
  /* *
   *类名：AlipaySubmit
   *功能：支付宝各接口请求提交类
   *详细：构造支付宝各接口表单HTML文本，获取远程HTTP数据
   *说明：
   *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
   *该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
   */
  
  public class AlipaySubmit {
  
      /**
       * 支付宝提供给商户的服务接入网关URL(新)
       */
      private static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
  
      /**
       * 生成签名结果
       *
       * @param sPara 要签名的数组
       * @return 签名结果字符串
       */
      public static String buildRequestMysign(Map<String, String> sPara) {
          String prestr = AlipayCore.createLinkString(sPara); //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
          String mysign = "";
          if (AlipayConfig.web_sign_type.equals("MD5")) {
              mysign = MD5.sign(prestr, AlipayConfig.web_apy_key, AlipayConfig.input_charset);
          } else if (AlipayConfig.web_sign_type.equals("RSA")) {
              mysign = RSA.sign(prestr, AlipayConfig.private_key, AlipayConfig.input_charset);
          }
          return mysign;
      }
  
      /**
       * 生成要请求给支付宝的参数数组
       *
       * @param sParaTemp 请求前的参数数组
       * @return 要请求的参数数组
       */
      private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {
          //除去数组中的空值和签名参数
          Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
          //生成签名结果
          String mysign = buildRequestMysign(sPara);
          //签名结果与签名方式加入请求提交参数组中
          sPara.put("sign", mysign);
          sPara.put("sign_type", AlipayConfig.web_sign_type);
  
          return sPara;
      }
  
      /**
       * 建立请求，以表单HTML形式构造（默认）
       *
       * @param sParaTemp     请求参数数组
       * @param strMethod     提交方式。两个值可选：post、get
       * @param strButtonName 确认按钮显示文字
       * @return 提交表单HTML文本
       */
      public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {
          //待请求参数数组
          Map<String, String> sPara = buildRequestPara(sParaTemp);
          List<String> keys = new ArrayList<String>(sPara.keySet());
  
          StringBuffer sbHtml = new StringBuffer();
          //target="_blank"
          sbHtml.append("<form id=\"alipaysubmit\"  name=\"alipaysubmit\" action=\"" + ALIPAY_GATEWAY_NEW
                  + "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
                  + "\">");
  
          for (int i = 0; i < keys.size(); i++) {
              String name = (String) keys.get(i);
              String value = (String) sPara.get(name);
  
              sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
          }
  
          //submit按钮控件请不要含有name属性
  //        sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\">");
          sbHtml.append("</form>");
          sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");
  
          return sbHtml.toString();
      }
  
      /**
       * 建立请求，以表单HTML形式构造，带文件上传功能
       *
       * @param sParaTemp       请求参数数组
       * @param strMethod       提交方式。两个值可选：post、get
       * @param strButtonName   确认按钮显示文字
       * @param strParaFileName 文件上传的参数名
       * @return 提交表单HTML文本
       */
      public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName, String strParaFileName) {
          //待请求参数数组
          Map<String, String> sPara = buildRequestPara(sParaTemp);
          List<String> keys = new ArrayList<String>(sPara.keySet());
  
          StringBuffer sbHtml = new StringBuffer();
  
          sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\"  enctype=\"multipart/form-data\" action=\"" + ALIPAY_GATEWAY_NEW
                  + "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
                  + "\">");
  
          for (int i = 0; i < keys.size(); i++) {
              String name = (String) keys.get(i);
              String value = (String) sPara.get(name);
  
              sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
          }
  
          sbHtml.append("<input type=\"file\" name=\"" + strParaFileName + "\" />");
  
          //submit按钮控件请不要含有name属性
          sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
  
          return sbHtml.toString();
      }
  
  
      /**
       * MAP类型数组转换成NameValuePair类型
       *
       * @param properties MAP类型数组
       * @return NameValuePair类型数组
       */
      private static NameValuePair[] generatNameValuePair(Map<String, String> properties) {
          NameValuePair[] nameValuePair = new NameValuePair[properties.size()];
          int i = 0;
          for (Map.Entry<String, String> entry : properties.entrySet()) {
              nameValuePair[i++] = new NameValuePair(entry.getKey(), entry.getValue());
          }
  
          return nameValuePair;
      }
  
      /**
       * 用于防钓鱼，调用接口query_timestamp来获取时间戳的处理函数
       * 注意：远程解析XML出错，与服务器是否支持SSL等配置有关
       *
       * @return 时间戳字符串
       * @throws IOException
       * @throws DocumentException
       * @throws MalformedURLException
       */
      @SuppressWarnings("unchecked")
      public static String query_timestamp() throws MalformedURLException,
              DocumentException, IOException {
  
          //构造访问query_timestamp接口的URL串
          String strUrl = ALIPAY_GATEWAY_NEW + "service=query_timestamp&partner=" + AlipayConfig.partner + "&_input_charset" + AlipayConfig.input_charset;
          StringBuffer result = new StringBuffer();
  
          SAXReader reader = new SAXReader();
          Document doc = reader.read(new URL(strUrl).openStream());
  
          List<Node> nodeList = doc.selectNodes("//alipay/*");
  
          for (Node node : nodeList) {
              // 截取部分不需要解析的信息
              if (node.getName().equals("is_success") && node.getText().equals("T")) {
                  // 判断是否有成功标示
                  List<Node> nodeList1 = doc.selectNodes("//response/timestamp/*");
                  for (Node node1 : nodeList1) {
                      result.append(node1.getText());
                  }
              }
          }
  
          return result.toString();
      }
  }
  