Commit aa8011de authored by jmdhappy's avatar jmdhappy
Browse files

升级支付宝为最新接口

parent 6bb11b08
......@@ -20,7 +20,7 @@ CREATE TABLE `t_pay_channel` (
`ChannelMchId` varchar(32) NOT NULL COMMENT '渠道商户ID',
`MchId` varchar(30) NOT NULL COMMENT '商户ID',
`State` tinyint(6) NOT NULL DEFAULT '1' COMMENT '渠道状态,0-停止使用,1-使用中',
`Param` varchar(2048) NOT NULL COMMENT '配置参数,json字符串',
`Param` varchar(4096) NOT NULL COMMENT '配置参数,json字符串',
`Remark` varchar(128) DEFAULT NULL COMMENT '备注',
`CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
......
......@@ -53,7 +53,7 @@ public class PayConstant {
public static final String RETURN_VALUE_FAIL = "FAIL";
public static final String RETURN_ALIPAY_VALUE_SUCCESS = "success";
public static final String RETURN_ALIPAY_VALUE_FAIL = "failed";
public static final String RETURN_ALIPAY_VALUE_FAIL = "fail";
public static class JdConstant {
public final static String CONFIG_PATH = "jd" + File.separator + "jd"; // 京东支付配置文件路径
......
......@@ -5,13 +5,13 @@ import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.*;
import org.xxpay.shop.dao.model.GoodsOrder;
import org.xxpay.shop.service.GoodsOrderService;
......@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
......@@ -383,6 +382,32 @@ public class GoodsOrderController {
_log.info("====== 支付中心通知处理完成 ======");
}
@RequestMapping("/toAliPay.html")
@ResponseBody
public String toAliPay(HttpServletRequest request, Long amount, String channelId) {
String logPrefix = "【支付宝支付】";
_log.info("====== 开始接收支付宝支付请求 ======");
String goodsId = "G_0001";
_log.info("{}接收参数:goodsId={},amount={},channelId={}", logPrefix, goodsId, amount, channelId);
// 先插入订单数据
Map params = new HashMap<>();
params.put("channelId", channelId);
// 下单
GoodsOrder goodsOrder = createGoodsOrder(goodsId, amount);
Map<String, String> orderMap = createPayOrder(goodsOrder, params);
if(orderMap != null && "success".equalsIgnoreCase(orderMap.get("resCode"))) {
String payOrderId = orderMap.get("payOrderId");
GoodsOrder go = new GoodsOrder();
go.setGoodsOrderId(goodsOrder.getGoodsOrderId());
go.setPayOrderId(payOrderId);
go.setChannelId(channelId);
int ret = goodsOrderService.update(go);
_log.info("修改商品订单,返回:{}", ret);
}
if(PayConstant.PAY_CHANNEL_ALIPAY_MOBILE.equalsIgnoreCase(channelId)) return orderMap.get("payParams");
return orderMap.get("payUrl");
}
void outResult(HttpServletResponse response, String content) {
response.setContentType("text/html");
PrintWriter pw;
......
......@@ -13,14 +13,14 @@ import java.util.Map;
public class PayOrderDemo {
// 商户ID
static final String mchId = "20001223";
static final String mchId = "20001223";//20001223,20001245
// 加签key
static final String reqKey = "M86l522AV6q613Ii4W6u8K48uW8vM1N6bFgyv769220MdYe9u37N4y7rI5mQ";
// 验签key
static final String repKey = "Hpcl522AV6q613KIi46u6g6XuW8vM1N8bFgyv769770MdYe9u37M4y7rIpl8";
//static final String baseUrl = "http://api.xxpay.org/api";
static final String baseUrl = "http://localhost:3020/api";
static final String baseUrl = "http://api.xxpay.org/api";
//static final String baseUrl = "http://localhost:3020/api";
static final String notifyUrl = "http://www.baidu.com"; // 本地环境测试,可到ngrok.cc网站注册
public static void main(String[] args) {
......@@ -32,8 +32,8 @@ public class PayOrderDemo {
JSONObject paramMap = new JSONObject();
paramMap.put("mchId", mchId); // 商户ID
paramMap.put("mchOrderNo", System.currentTimeMillis()); // 商户订单号
paramMap.put("channelId", "WX_NATIVE"); // 支付渠道ID, WX_NATIVE,ALIPAY_WAP
paramMap.put("amount", 100); // 支付金额,单位分
paramMap.put("channelId", "ALIPAY_PC"); // 支付渠道ID, WX_NATIVE,ALIPAY_WAP,ALIPAY_PC,ALIPAY_MOBILE
paramMap.put("amount", 1); // 支付金额,单位分
paramMap.put("currency", "cny"); // 币种, cny-人民币
paramMap.put("clientIp", "114.112.124.236"); // 用户地址
paramMap.put("device", "WEB"); // 设备
......
......@@ -32,9 +32,7 @@
</table>
</div>
<#if (client == 'alipay')>
<script>
location.href = '${orderMap.payUrl}';
</script>
${orderMap.payUrl}
</#if>
<#if (client == 'wx')>
<script>
......
# \u652F\u4ED8\u5B9D\u56DE\u8C03\u5730\u5740
# \u652F\u4ED8\u5B9D\u670D\u52A1\u5668\u5F02\u6B65\u901A\u77E5\u9875\u9762\u8DEF\u5F84
ali.notify_url=http://api.xxpay.org/notify/pay/aliPayNotifyRes.htm
# \u652F\u4ED8\u5B9D\u9875\u9762\u8DF3\u8F6C\u540C\u6B65\u901A\u77E5\u9875\u9762\u8DEF\u5F84(\u81EA\u884C\u914D\u7F6E)
ali.return_url=http://www.xxpay.org
# \u5FAE\u4FE1\u652F\u4ED8\u56DE\u8C03\u5730\u5740
wx.notify_url=http://api.xxpay.org/notify/pay/wxPayNotifyRes.htm
# \u652F\u4ED8\u8BC1\u4E66\u6839\u8DEF\u5F84
cert.root.path=/Users/dingzhiwei/java/tmp/cert
\ No newline at end of file
cert.root.path=/home/xxpay/service/cert
\ No newline at end of file
# \u652F\u4ED8\u5B9D\u56DE\u8C03\u5730\u5740
ali.notify_url=http://api.xxpay.org/notify/pay/aliPayNotifyRes.htm
ali.return_url=http://www.xxpay.org
# \u5FAE\u4FE1\u652F\u4ED8\u56DE\u8C03\u5730\u5740
wx.notify_url=http://api.xxpay.org/notify/pay/wxPayNotifyRes.htm
# \u652F\u4ED8\u8BC1\u4E66\u6839\u8DEF\u5F84
cert.root.path=/Users/dingzhiwei/java/tmp/cert
\ No newline at end of file
cert.root.path=/home/xxpay/service/cert
\ No newline at end of file
# \u652F\u4ED8\u5B9D\u56DE\u8C03\u5730\u5740
ali.notify_url=http://api.xxpay.org/notify/pay/aliPayNotifyRes.htm
ali.return_url=http://www.xxpay.org
# \u5FAE\u4FE1\u652F\u4ED8\u56DE\u8C03\u5730\u5740
wx.notify_url=http://api.xxpay.org/notify/pay/wxPayNotifyRes.htm
# \u652F\u4ED8\u8BC1\u4E66\u6839\u8DEF\u5F84
cert.root.path=/Users/dingzhiwei/java/tmp/cert
\ No newline at end of file
cert.root.path=/home/xxpay/service/cert
\ No newline at end of file
......@@ -55,18 +55,28 @@
</dependency>
<!--ali_pay-->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
<groupId>com.alipay</groupId>
<artifactId>sdk</artifactId>
<version>1.5</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/alipay-sdk-java20170818173712.jar</systemPath>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/webapp/WEB-INF/lib/</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes/</targetPath>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
......
package org.xxpay.service.channel.alipay;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
/**
* @author: dingzhiwei
* @date: 17/8/21
* @description:
*/
@RefreshScope
@Service
public class AlipayConfig {
// 商户appid
private String app_id;
// 私钥 pkcs8格式的
private String rsa_private_key;
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
@Value("${ali.notify_url}")
private String notify_url;
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
@Value("${ali.return_url}")
private String return_url;
// 请求网关地址
private String url = "https://openapi.alipay.com/gateway.do";
// 编码
public static String CHARSET = "UTF-8";
// 返回格式
public static String FORMAT = "json";
// 支付宝公钥
public String alipay_public_key;
// RSA2
public static String SIGNTYPE = "RSA2";
// 是否沙箱环境,1:沙箱,0:正式环境
private Short isSandbox = 0;
/**
* 初始化支付宝配置
* @param configParam
* @return
*/
public AlipayConfig init(String configParam) {
Assert.notNull(configParam, "init alipay config error");
JSONObject paramObj = JSON.parseObject(configParam);
this.setApp_id(paramObj.getString("appid"));
this.setRsa_private_key(paramObj.getString("private_key"));
this.setAlipay_public_key(paramObj.getString("alipay_public_key"));
this.setIsSandbox(paramObj.getShortValue("isSandbox"));
if(this.getIsSandbox() == 1) this.setUrl("https://openapi.alipaydev.com/gateway.do");
return this;
}
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public String getRsa_private_key() {
return rsa_private_key;
}
public void setRsa_private_key(String rsa_private_key) {
this.rsa_private_key = rsa_private_key;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getReturn_url() {
return return_url;
}
public void setReturn_url(String return_url) {
this.return_url = return_url;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Short getIsSandbox() {
return isSandbox;
}
public void setIsSandbox(Short isSandbox) {
this.isSandbox = isSandbox;
}
public String getAlipay_public_key() {
return alipay_public_key;
}
public void setAlipay_public_key(String alipay_public_key) {
this.alipay_public_key = alipay_public_key;
}
}
package org.xxpay.service.channel.alipay.config;
/* *
*类名:AlipayConfig
*功能:基础配置类
*详细:设置帐户有关信息及返回路径
*版本:3.3
*日期:2012-08-10
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*提示:如何获取安全校验码和合作身份者ID
*1.用您的签约支付宝账号登录支付宝网站(www.alipay.com)
*2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
*3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”
*安全校验码查看时,输入支付密码后,页面呈灰色的现象,怎么办?
*解决方法:
*1、检查浏览器配置,不让浏览器做弹框屏蔽设置
*2、更换浏览器或电脑,重新登录查询。
*/
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.common.util.PropertiesFileUtil;
import java.util.Date;
import java.util.Map;
@RefreshScope
@Service
public class AlipayConfig {
private static final MyLog _log = MyLog.getLog(AlipayConfig.class);
public AlipayConfig init(String configParam) {
Assert.notNull(configParam, "init alipay config error");
JSONObject paramObj = JSON.parseObject(configParam);
this.setAppId(paramObj.getString("appid"));
this.setPartner(paramObj.getString("partner"));
this.setAli_account(paramObj.getString("ali_account"));
this.setPrivate_key(paramObj.getString("private_key"));
return this;
}
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 合作身份者ID,以2088开头由16位纯数字组成的字符串
public String partner = "";
// 商户的私钥
public String private_key = "";
// 支付宝的公钥,无需修改该值
public static String ali_public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// 支付宝账号
public String ali_account = "";
// 字符编码格式 目前支持 gbk 或 utf-8
public static String input_charset = "utf-8";
// 签名方式 不需修改
public static String sign_type = "RSA";
// 提供给支付宝的通知地址
@Value("${ali.notify_url}")
private String notify_url;
// 是否验证支付宝的通知地址
private boolean is_verify_notify_url = true;
// 支付宝即时到帐网关
private String gateway = "https://mapi.alipay.com/gateway.do";
// 支付宝新网关(查询等)
private String openapiGateway = "https://openapi.alipay.com/gateway.do";
// appid
public String appId = "";
// 配置加载时间
private Long loadTime = new Date().getTime();
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getPartner() {
return partner;
}
public void setPartner(String partner) {
this.partner = partner;
}
public String getPrivate_key() {
return private_key;
}
public void setPrivate_key(String private_key) {
this.private_key = private_key;
}
public String getAli_account() {
return ali_account;
}
public void setAli_account(String ali_account) {
this.ali_account = ali_account;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public boolean is_verify_notify_url() {
return is_verify_notify_url;
}
public void setIs_verify_notify_url(boolean is_verify_notify_url) {
this.is_verify_notify_url = is_verify_notify_url;
}
public String getGateway() {
return gateway;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
public String getOpenapiGateway() {
return openapiGateway;
}
public void setOpenapiGateway(String openapiGateway) {
this.openapiGateway = openapiGateway;
}
public Long getLoadTime() {
return loadTime;
}
public void setLoadTime(Long loadTime) {
this.loadTime = loadTime;
}
@Override
public String toString() {
return "AlipayConfig{" +
"partner='" + partner + '\'' +
", private_key='" + private_key + '\'' +
", ali_account='" + ali_account + '\'' +
", notify_url='" + notify_url + '\'' +
", is_verify_notify_url='" + is_verify_notify_url + '\'' +
", gateway='" + gateway + '\'' +
", openapiGateway='" + openapiGateway + '\'' +
", appId='" + appId + '\'' +
", loadTime=" + loadTime +
'}';
}
}
\ No newline at end of file
/*
* Copyright (C) 2010 The MobileSecurePay Project
* All right reserved.
* author: shiqun.shi@alipay.com
*/
package org.xxpay.service.channel.alipay.sign;
public final class Base64 {
static private final int BASELENGTH = 128;
static private final int LOOKUPLENGTH = 64;
static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16;
static private final int FOURBYTE = 4;
static private final int SIGN = -128;
static private final char PAD = '=';
static private final boolean fDebug = false;
static final private byte[] base64Alphabet = new byte[BASELENGTH];
static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
static {
for (int i = 0; i < BASELENGTH; ++i) {
base64Alphabet[i] = -1;
}
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i - 'A');
}
for (int i = 'z'; i >= 'a'; i--) {
base64Alphabet[i] = (byte) (i - 'a' + 26);
}
for (int i = '9'; i >= '0'; i--) {
base64Alphabet[i] = (byte) (i - '0' + 52);
}
base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63;
for (int i = 0; i <= 25; i++) {
lookUpBase64Alphabet[i] = (char) ('A' + i);
}
for (int i = 26, j = 0; i <= 51; i++, j++) {
lookUpBase64Alphabet[i] = (char) ('a' + j);
}
for (int i = 52, j = 0; i <= 61; i++, j++) {
lookUpBase64Alphabet[i] = (char) ('0' + j);
}
lookUpBase64Alphabet[62] = (char) '+';
lookUpBase64Alphabet[63] = (char) '/';
}
private static boolean isWhiteSpace(char octect) {
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
}
private static boolean isPad(char octect) {
return (octect == PAD);
}
private static boolean isData(char octect) {
return (octect < BASELENGTH && base64Alphabet[octect] != -1);
}
/**
* Encodes hex octects into Base64
*
* @param binaryData Array containing binaryData
* @return Encoded Base64 array
*/
public static String encode(byte[] binaryData) {
if (binaryData == null) {
return null;
}
int lengthDataBits = binaryData.length * EIGHTBIT;
if (lengthDataBits == 0) {
return "";
}
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
char encodedData[] = null;
encodedData = new char[numberQuartet * 4];
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
int encodedIndex = 0;
int dataIndex = 0;
if (fDebug) {
System.out.println("number of triplets = " + numberTriplets);
}
for (int i = 0; i < numberTriplets; i++) {
b1 = binaryData[dataIndex++];
b2 = binaryData[dataIndex++];
b3 = binaryData[dataIndex++];
if (fDebug) {
System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
}
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
if (fDebug) {
System.out.println("val2 = " + val2);
System.out.println("k4 = " + (k << 4));
System.out.println("vak = " + (val2 | (k << 4)));
}
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
}
// form integral number of 6-bit groups
if (fewerThan24bits == EIGHTBIT) {
b1 = binaryData[dataIndex];
k = (byte) (b1 & 0x03);
if (fDebug) {
System.out.println("b1=" + b1);
System.out.println("b1<<2 = " + (b1 >> 2));
}
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
encodedData[encodedIndex++] = PAD;
encodedData[encodedIndex++] = PAD;
} else if (fewerThan24bits == SIXTEENBIT) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
encodedData[encodedIndex++] = PAD;
}
return new String(encodedData);
}
/**
* Decodes Base64 data into octects
*
* @param encoded string containing Base64 data
* @return Array containind decoded data.
*/
public static byte[] decode(String encoded) {
if (encoded == null) {
return null;
}
char[] base64Data = encoded.toCharArray();
// remove white spaces
int len = removeWhiteSpace(base64Data);
if (len % FOURBYTE != 0) {
return null;//should be divisible by four
}
int numberQuadruple = (len / FOURBYTE);
if (numberQuadruple == 0) {
return new byte[0];
}
byte decodedData[] = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
int i = 0;
int encodedIndex = 0;
int dataIndex = 0;
decodedData = new byte[(numberQuadruple) * 3];
for (; i < numberQuadruple - 1; i++) {
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
|| !isData((d3 = base64Data[dataIndex++]))
|| !isData((d4 = base64Data[dataIndex++]))) {
return null;
}//if found "no data" just return null
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
}
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
return null;//if found "no data" just return null
}
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
d3 = base64Data[dataIndex++];
d4 = base64Data[dataIndex++];
if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
if (isPad(d3) && isPad(d4)) {
if ((b2 & 0xf) != 0)//last 4 bits should be zero
{
return null;
}
byte[] tmp = new byte[i * 3 + 1];
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
return tmp;
} else if (!isPad(d3) && isPad(d4)) {
b3 = base64Alphabet[d3];
if ((b3 & 0x3) != 0)//last 2 bits should be zero
{
return null;
}
byte[] tmp = new byte[i * 3 + 2];
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
return tmp;
} else {
return null;
}
} else { //No PAD e.g 3cQl
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
}
return decodedData;
}
/**
* remove WhiteSpace from MIME containing encoded Base64 data.
*
* @param data the byte array of base64 data (with WS)
* @return the new length
*/
private static int removeWhiteSpace(char[] data) {
if (data == null) {
return 0;
}
// count characters that's not whitespace
int newSize = 0;
int len = data.length;
for (int i = 0; i < len; i++) {
if (!isWhiteSpace(data[i])) {
data[newSize++] = data[i];
}
}
return newSize;
}
}
package org.xxpay.service.channel.alipay.sign;
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSA{
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
/**
* RSA签名
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey) );
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update( content.getBytes(input_charset) );
byte[] signed = signature.sign();
return Base64.encode(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA验签名检查
* @param content 待签名数据
* @param sign 签名值
* @param ali_public_key 支付宝公钥
* @param input_charset 编码格式
* @return 布尔值
*/
public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(ali_public_key);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes(input_charset) );
boolean bverify = signature.verify(Base64.decode(sign) );
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* 解密
* @param content 密文
* @param private_key 商户私钥
* @param input_charset 编码格式
* @return 解密后的字符串
*/
public static String decrypt(String content, String private_key, String input_charset) throws Exception {
PrivateKey prikey = getPrivateKey(private_key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, prikey);
InputStream ins = new ByteArrayInputStream(Base64.decode(content));
ByteArrayOutputStream writer = new ByteArrayOutputStream();
//rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
byte[] buf = new byte[128];
int bufl;
while ((bufl = ins.read(buf)) != -1) {
byte[] block = null;
if (buf.length == bufl) {
block = buf;
} else {
block = new byte[bufl];
for (int i = 0; i < bufl; i++) {
block[i] = buf[i];
}
}
writer.write(cipher.doFinal(block));
}
return new String(writer.toByteArray(), input_charset);
}
/**
* 得到私钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
/*public static void main(String[] args) {
System.out.println(RSA.sign(
"_input_charset=utf-8&app_pay=Y&body=VV直播下单测试&it_b_pay=60m&notify_url=${pay.url}/notify/aliPayNotifyRes.htm&out_trade_no=1494684553763&partner=2088521108562983&payment_type=1&seller_id=2088521108562983&service=alipay.wap.create.direct.pay.by.user&show_url=http://www.xxpay.org&subject=null&total_fee=0.01",
"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKOuhY6LYZBMiRrvRw2s71CjPW7OPCvapjZdJJNPt5x471E3kDCb9A7kQTyqFIIVcUNKDlKRNztKBhhlxAiI7d95UkN5pAMK+XUItjyA9nj9cqK/ajHjwC4AlIRUZhlsPvj6lt1Oj1Kf1sNDJMM/NZL9IR8EXr7HlIsCjJNVHFPvAgMBAAECgYBY1S7G3f5lQiRm6dW2JlT7fpyotmURp+jtOD/Rc0JDOZ8ohO9McldSfa6qLeRTdS+zRU3goc9H7jTAqPprZ2UxNTUwJ4uMh+2bCtXkvUPwoWF4fb095xGtEUdbKMFkv+yKpCQASrjDhqzVq5xD/uc796wd7HOHwr8xPNOrKKSGAQJBANfgcaiIyFeo8KK4vIUWtqSiqLgG6gp7ABx2WpMWX3wsjbiCBQGVbJbnFcCkB+bofCuKYj7BGLjEEqc3c6y+Ph8CQQDCGprovroKw09dOzqFFPpkMrZvkOpO2e+RhDhhLYq2e5lRLVePtB/ZX2iy2yKQEp/7VWbNFzobqYR6KPXEH5AxAkBx3oD1XhkXLBSqMHm4Ve/HTcljMLp5BsJbQQ6rsUxyimnC3kpXuILL4l61+4/ze8Qrj1YdNeudYkdYjsZkYwEPAkBoWedIEylvmdqz86CdZU7LyVu9FPpyk8WwxJWO4O3+9unQ84BseFjbAukFprupGuo5M4uF3OPXdUYMarLd0l4xAkAMjec0KXp15a93I5y/vfIEAMQ+CQj/LwOxyAM6tTSPVGJHu70pXFQVWtwY+ycMuzbxTdSLuQYxITstHnV3mu76", "utf-8"));
}*/
}
package org.xxpay.service.channel.alipay.util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.methods.multipart.FilePartSource;
import org.apache.commons.httpclient.methods.multipart.PartSource;
import java.io.File;
import java.io.IOException;
import java.util.*;
/* *
*类名:AlipayFunction
*功能:支付宝接口公用函数类
*详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件,不需要修改
*版本:3.3
*日期:2012-08-14
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class AlipayCore {
/**
* 除去数组中的空值和签名参数
* @param sArray 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
public static Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<String, String>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
return result;
}
/**
* 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param params 需要排序并参与字符拼接的参数组
* @return 拼接后字符串
*/
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
/**
* 生成文件摘要
* @param strFilePath 文件路径
* @param file_digest_type 摘要算法
* @return 文件摘要结果
*/
public static String getAbstract(String strFilePath, String file_digest_type) throws IOException {
PartSource file = new FilePartSource(new File(strFilePath));
if(file_digest_type.equals("MD5")){
return DigestUtils.md5Hex(file.createInputStream());
}
else if(file_digest_type.equals("SHA")) {
return DigestUtils.sha256Hex(file.createInputStream());
}
else {
return "";
}
}
}
package org.xxpay.service.channel.alipay.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.xxpay.service.channel.alipay.config.AlipayConfig;
import org.xxpay.service.channel.alipay.sign.RSA;
import org.xxpay.common.util.MyLog;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/* *
*类名:AlipayNotify
*功能:支付宝通知处理类
*详细:处理支付宝各接口通知返回
*版本:3.3
*日期:2012-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考
*************************注意*************************
*调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常
*/
@Component
public class AlipayNotify {
private static final MyLog _log = MyLog.getLog(AlipayNotify.class);
/**
* 支付宝消息验证地址
*/
private static final String HTTPS_VERIFY_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&";
/**
* 验证消息是否是支付宝发出的合法消息
* @param params 通知返回来的参数数组
* @return 验证结果
*/
public static boolean verify(AlipayConfig alipayConfig, Map<String, String> params) {
//判断responsetTxt是否为true,isSign是否为true
//responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
//isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
String responseTxt = "true";
if(alipayConfig.is_verify_notify_url()) {
responseTxt = "false";
if(params.get("notify_id") != null) {
String notify_id = params.get("notify_id");
responseTxt = verifyResponse(alipayConfig, notify_id);
}
_log.info("验证支付宝请求地址,结果responseTxt={}", responseTxt);
}
String sign = "";
if(params.get("sign") != null) {sign = params.get("sign");}
boolean isSign = getSignVeryfy(params, sign);
_log.info("验证支付宝通知签名,isSign={}", isSign);
//写日志记录(若要调试,请取消下面两行注释)
//String sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign + "\n 返回回来的参数:" + AlipayCore.createLinkString(params);
//AlipayCore.logResult(sWord);
if (isSign && responseTxt.equals("true")) {
return true;
} else {
return false;
}
}
/**
* 根据反馈回来的信息,生成签名结果
* @param Params 通知返回来的参数数组
* @param sign 比对的签名结果
* @return 生成的签名结果
*/
private static boolean getSignVeryfy(Map<String, String> Params, String sign) {
//过滤空值、sign与sign_type参数
Map<String, String> sParaNew = AlipayCore.paraFilter(Params);
//获取待签名字符串
String preSignStr = AlipayCore.createLinkString(sParaNew);
//获得签名验证结果
boolean isSign = false;
if(AlipayConfig.sign_type.equals("RSA")){
isSign = RSA.verify(preSignStr, sign, AlipayConfig.ali_public_key, AlipayConfig.input_charset);
}
return isSign;
}
/**
* 获取远程服务器ATN结果,验证返回URL
* @param notify_id 通知校验ID
* @return 服务器ATN结果
* 验证结果集:
* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
* true 返回正确信息
* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
*/
private static String verifyResponse(AlipayConfig alipayConfig, String notify_id) {
//获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
String partner = alipayConfig.getPartner();
String veryfy_url = HTTPS_VERIFY_URL + "partner=" + partner + "&notify_id=" + notify_id;
_log.info("请求支付宝URL={}", veryfy_url);
return checkUrl(veryfy_url);
}
/**
* 获取远程服务器ATN结果
* @param urlvalue 指定URL路径地址
* @return 服务器ATN结果
* 验证结果集:
* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
* true 返回正确信息
* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
*/
private static String checkUrl(String urlvalue) {
String inputLine = "";
try {
URL url = new URL(urlvalue);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
.getInputStream()));
inputLine = in.readLine().toString();
} catch (Exception e) {
_log.error(e, "验证支付宝通知请求地址异常.URL=%s", urlvalue);
inputLine = "";
}
return inputLine;
}
}
package org.xxpay.service.channel.alipay.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
/* *
*类名:UtilDate
*功能:自定义订单类
*详细:工具类,可以用作获取系统日期、订单编号等
*版本:3.3
*日期:2012-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class UtilDate {
/** 年月日时分秒(无下划线) yyyyMMddHHmmss */
public static final String dtLong = "yyyyMMddHHmmss";
/** 完整时间 yyyy-MM-dd HH:mm:ss */
public static final String simple = "yyyy-MM-dd HH:mm:ss";
/** 年月日(无下划线) yyyyMMdd */
public static final String dtShort = "yyyyMMdd";
/**
* 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
* @return
* 以yyyyMMddHHmmss为格式的当前系统时间
*/
public static String getOrderNum(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(dtLong);
return df.format(date);
}
/**
* 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
* @return
*/
public static String getDateFormatter(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(simple);
return df.format(date);
}
/**
* 获取系统当期年月日(精确到天),格式:yyyyMMdd
* @return
*/
public static String getDate(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(dtShort);
return df.format(date);
}
/**
* 产生随机的三位数
* @return
*/
public static String getThree(){
Random rad=new Random();
return rad.nextInt(1000)+"";
}
}
package org.xxpay.service.channel.alipay.util.httpClient;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;
import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/* *
*类名:HttpProtocolHandler
*功能:HttpClient方式访问
*详细:获取远程HTTP数据
*版本:3.3
*日期:2012-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class HttpProtocolHandler {
private static String DEFAULT_CHARSET = "GBK";
/** 连接超时时间,由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);
}
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();
}
}
package org.xxpay.service.channel.alipay.util.httpClient;
import org.apache.commons.httpclient.NameValuePair;
/* *
*类名:HttpRequest
*功能:Http请求对象的封装
*详细:封装Http请求
*版本:3.3
*日期:2011-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class HttpRequest {
/** HTTP GET method */
public static final String METHOD_GET = "GET";
/** HTTP POST method */
public static final String METHOD_POST = "POST";
/**
* 待请求的url
*/
private String url = null;
/**
* 默认的请求方式
*/
private String method = METHOD_POST;
private int timeout = 0;
private int connectionTimeout = 0;
/**
* Post方式请求时组装好的参数值对
*/
private NameValuePair[] parameters = null;
/**
* Get方式请求时对应的参数
*/
private String queryString = null;
/**
* 默认的请求编码方式
*/
private String charset = "GBK";
/**
* 请求发起方的ip地址
*/
private String clientIp;
/**
* 请求返回的方式
*/
private HttpResultType resultType = HttpResultType.BYTES;
public HttpRequest(HttpResultType resultType) {
super();
this.resultType = resultType;
}
/**
* @return Returns the clientIp.
*/
public String getClientIp() {
return clientIp;
}
/**
* @param clientIp The clientIp to set.
*/
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
public NameValuePair[] getParameters() {
return parameters;
}
public void setParameters(NameValuePair[] parameters) {
this.parameters = parameters;
}
public String getQueryString() {
return queryString;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
/**
* @return Returns the charset.
*/
public String getCharset() {
return charset;
}
/**
* @param charset The charset to set.
*/
public void setCharset(String charset) {
this.charset = charset;
}
public HttpResultType getResultType() {
return resultType;
}
public void setResultType(HttpResultType resultType) {
this.resultType = resultType;
}
}
package org.xxpay.service.channel.alipay.util.httpClient;
import org.apache.commons.httpclient.Header;
import org.xxpay.service.channel.alipay.config.AlipayConfig;
import java.io.UnsupportedEncodingException;
/* *
*类名:HttpResponse
*功能:Http返回对象的封装
*详细:封装Http返回信息
*版本:3.3
*日期:2011-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class HttpResponse {
/**
* 返回中的Header信息
*/
private Header[] responseHeaders;
/**
* String类型的result
*/
private String stringResult;
/**
* btye类型的result
*/
private byte[] byteResult;
public Header[] getResponseHeaders() {
return responseHeaders;
}
public void setResponseHeaders(Header[] responseHeaders) {
this.responseHeaders = responseHeaders;
}
public byte[] getByteResult() {
if (byteResult != null) {
return byteResult;
}
if (stringResult != null) {
return stringResult.getBytes();
}
return null;
}
public void setByteResult(byte[] byteResult) {
this.byteResult = byteResult;
}
public String getStringResult() throws UnsupportedEncodingException {
if (stringResult != null) {
return stringResult;
}
if (byteResult != null) {
return new String(byteResult, AlipayConfig.input_charset);
}
return null;
}
public void setStringResult(String stringResult) {
this.stringResult = stringResult;
}
}
/*
* Alipay.com Inc.
* Copyright (c) 2004-2005 All Rights Reserved.
*/
package org.xxpay.service.channel.alipay.util.httpClient;
/* *
*类名:HttpResultType
*功能:表示Http返回的结果字符方式
*详细:表示Http返回的结果字符方式
*版本:3.3
*日期:2012-08-17
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public enum HttpResultType {
/**
* 字符串方式
*/
STRING,
/**
* 字节数组方式
*/
BYTES
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment