商品秒杀系统-支付模块的开发【https://github.com/XCXCXCXCX/KillSystem】

一、沙箱环境配置

我使用的是测试沙箱环境,使用沙箱测试版的支付宝进行测试,如果需要上线部署,要申请接入哦

APPID

阿里提供的,后面流程中需要把这个APPID复制粘贴到项目配置中

支付宝网关

直接使用图中测试环境的网关地址

RSA2/RSA密钥

这里我使用的是RSA2密钥,需要配置RSA2该栏目,先是生成RSA2的公钥密钥对(在阿里开发文档中有提供生成密钥对的工具,下载后按照文档生成密钥对并进行后续配置,这里我直接贴链接,就不照搬操作了)

用来验证开发者身份

应用网关

填入如上支付宝网关

授权回调地址

填入项目中对外暴露的alipayCallback.do接口

ps:这个接口地址一定要提供能在外网环境下能访问的地址

AES密钥

直接点生成就可以了,AES是对称加密算法,用于加密报文

二、引入所需jar包及alipaydemo的整合

pom.xml

<!-- alipay -->
    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.10</version>
    </dependency>
    <dependency>
      <groupId>commons-configuration</groupId>
      <artifactId>commons-configuration</artifactId>
      <version>1.10</version>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.6</version>
    </dependency>
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-core</artifactId>
      <version>1.3</version>
    </dependency>

另外还需要引入其他jar包,可以在我的git项目中找到,或者直接在开发文档中下载DEMO,DEMO中有这些包

整合时,先将demo中的java代码和zfbinfo.properties复制到自己开发项目中,然后将zfbinfo.properties修改成应用自己项目的配置:

# 支付宝网关名、partnerId和appId
# 前面沙箱配置中的支付宝网关
open_api_domain = https://openapi.alipaydev.com/gateway.do

mcloud_api_domain = http://mcloudmonitor.com/gateway.do

# 前面沙箱配置中的商户uid
pid = 2088102175224611

# 前面沙箱配置中的appid
appid = 2016091200490386

# RSA私钥、公钥和支付宝公钥
# 前面生成RSA2密钥对的私钥,我贴出来隐藏一下我的私钥0.0
private_key = *************************************************************************************************

# 前面生成RSA2密钥对的公钥
public_key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkVHcHYP+6H+b4Md0desMNG0akCh1yMbLlR3OWjXG292gL4lfQLhjxs7tDw+6anLC+wBl/0TEV5F2McxgLxH5AGMkc3f4wA1/lNm85NxHEdtWlZ36cCSFb5eznBXwiFfWBXerT/YE9da6T34KS1cc5aEq0OJGRZ9o8rOr4+lwXbPETarWIqDT0kJqVmGeEZsa+FMn9ZBesGbenV2qEpvAE5Q8QP6GQTFeVEVlUbDc2CDocF+xFsjPFQq13zTNEm7MmVyrEWGvNp0bBEJsbkh9/FZfCbo1lzYSVGS+U6UPjccimNYYJOMcIgP6EtKpNb0HB/nSsgf8TZfCBgUaQ6U3ZwIDAQAB
#SHA1withRsa对应支付宝公钥
#alipay_public_key = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB

#SHA256withRsa对应支付宝公钥
# 前面沙箱配置中的支付宝公钥,点击RSA2栏目的{查看支付宝公钥}查看,不要与前面的public_key弄混淆了
alipay_public_key =MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4WxgxuWD7mHzv3fN2cVrXw6SOwyIsK2f6lSD4z1buO97HhFla7rQIIxfTmiR6B6ygVDRDN7T3HzAPH1s1wYp4tXUBdhcDoZlydNIrGDeJ8PeW96TcaLPjQgnZNFkUpNAlHULi0S3fBfuPBB/w9WM15O6r4CasyOyckJ3/v/fHFaTyxD52Ym6x94Obs2HrxJ6OW+WQp77192Dk9h+VCvNtbyVH00XDUiWveCv2yIa5ZbS0o+713O4irp7KTsAxXfGUQohYfO1QtF1e2KTCon/7gCFQCUGV++HM0UINJFfPAgNf6hu7mdFqk95u/SqkEDsmyHnnVdmakLHsxQy8yZcwIDAQAB
# 签名类型: RSA->SHA1withRsa,RSA2->SHA256withRsa
sign_type = RSA2
# 当面付最大查询次数和查询间隔(毫秒)
max_query_retry = 5
query_duration = 5000

# 当面付最大撤销次数和撤销间隔(毫秒)
max_cancel_retry = 3
cancel_duration = 2000

# 交易保障线程第一次调度延迟和调度间隔(秒)
heartbeat_delay = 5
heartbeat_duration = 900

然后就可以按照api调用使用了,我只使用了二维码当面付的功能,后续慢慢介绍

三、支付模块的开发

1.前台web页面代码

(1)页面效果介绍

用户创建订单成功后,进入alipay.jsp页面,如图:


预支付成功后,页面如图:



支付成功后,直接返回“支付成功”页面,这个页面太丑了就不贴图了。。

(2)jsp文件代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
<script type="text/javascript">

$(function(){
		$("#qrCodeDiv").hide();
		window.setTimeout(toPay,3000);
	});

function toPay(){
	var order_id = $("#order_id").val();
	var tel_num = $("#tel_num").val();
	var address = $("#address").val();
	var goods_id = $("#goods_id").val();
	$.post("/KillSystem/pay.do", { order_id: order_id, tel_num: tel_num, address: address, goods_id: goods_id },  
	            function (response) {  
					alert(response.msg);
	                if (response.status == "0") { 
						$("#qrCode").attr("src",response.data.qrUrl);
						$("#qrCodeDiv").show();
						window.setInterval(getPayState,5000);
						window.setTimeout(back,36000);
	                }else{
	                	alert('生成二维码失败!');
	                }
	            }, 'json');  
}

function getPayState(){
	var order_id = $("#order_id").val();
	var tel_num = $("#tel_num").val();
	var address = $("#address").val();
	var goods_id = $("#goods_id").val();
	$.post("/KillSystem/payIsSuccess.do", { order_id: order_id, tel_num: tel_num, address: address, goods_id: goods_id },  
            function (response) {  
                if (response.status == "0") { 
					if (response.data == true){
						window.location.href="/paySuccess.html";
					}
                }
            }, 'json');
}
</script>
<title>alipay</title>
</head>
<body>
5秒后自动跳转,支付宝正在努力的生成二维码...
<input id="order_id" type="hidden" name="order_id" value="${order.getOrder_id()}" />
<input id="tel_num" type="hidden" name="tel_num" value="${order.getTel_num()}" />
<input id="address" type="hidden" name="address" value="${order.getAddress()}" />
<input id="goods_id" type="hidden" name="goods_id" value="${order.getGoods_id()}" />

<div id="qrCodeDiv" class="align-center">
	<img id="qrCode" class="top" src="" height="400" width="400" /> 
	二维码5分钟后失效,支付成功后自动跳转...
</div>


</body>
</html>

(3)所需后台服务接口

pay.do

发起支付宝预支付,向支付宝发起支付请求,支付宝处理成功后,返回一个用于支付的二维码

alipayCallback.do 

当二维码扫描后支付成功,支付宝会回调该接口,用于处理1.订单信息的验证2.支付信息的更新,结合项目需求实现代码

payIsSuccess.do

前台轮询调用该接口,当订单支付成功,跳转至“支付成功”页面。

2.后台开发

(1)controller层

OrderController.java

@RequestMapping("/pay.do")
	@ResponseBody
	public ServerResponse pay(Order order,HttpServletRequest request,HttpSession session) {
		if (session.getAttribute("tel_num") == null || session.getAttribute("passwd") == null) {
			return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用户登录已过期");
		}
		//hasPay = true;
		
		if(!orderService.orderIsExistInRedis(order)) {
			//撤回库存减一的操作
			goodsService.incrGoodsStock(order);
			return ServerResponse.createByErrorMessage(order.getOrder_id() + "订单已失效,请重新创建订单");
		}
		//todo
		//1.在redis中创建支付订单,若失败,返回“订单已存在”
		if(orderService.createPayInRedis(order)==0) {
			return ServerResponse.createByErrorMessage(order.getOrder_id() + "_pay订单已存在");
		}
		//2.收到支付宝回调后,在redis中更新支付订单,若失败,返回“订单支付失败,取消支付并删除订单和删除订单支付”
		String path = request.getSession().getServletContext().getRealPath("upload");
        return orderService.pay(order,path);
	
	}
	
	@RequestMapping("/alipayCallback.do")
	@ResponseBody
	public Object alipayCallback(HttpServletRequest request) {
		//todo
		//在request中取到支付宝回调的params
		Map<String,String> params = Maps.newHashMap();

        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for(int i = 0 ; i <values.length;i++){

                valueStr = (i == values.length -1)?valueStr + values[i]:valueStr + values[i]+",";
            }
            params.put(name,valueStr);
        }
        log.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());

        //由于使用的是RSA2,看源码可以知道默认是使用RSA的,所以这里要进行处理,使用RSA2

        params.remove("sign_type");
        try {
            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());

            if(!alipayRSACheckedV2){
                return ServerResponse.createByErrorMessage("非法请求,验证不通过,再恶意请求我就报警找网警了");
            }
        } catch (AlipayApiException e) {
            log.error("支付宝验证回调异常",e);
        }

        ServerResponse serverResponse = orderService.aliCallback(params);
        if(serverResponse.isSuccess()){
            return "success";
        }
        return "failed";
		
	}
	
	@RequestMapping("/payIsSuccess.do")
	@ResponseBody
	public ServerResponse payIsSuccess(Order order,HttpServletRequest request,HttpSession session) {
		if (session.getAttribute("tel_num") == null || session.getAttribute("passwd") == null) {
			return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用户登录已过期");
		}
		//查询该订单是否支付成功:在redis中查询key{订单号+pay}的value值是否为1,若为1,返回支付成功,若为0,返回未支付。
		String flag = orderService.getPayState(order);
		if(flag == null) {
			return ServerResponse.createByErrorMessage("该支付订单不存在!");
		}
		boolean data = ("0".equals(flag) ? false : true);
		return ServerResponse.createBySuccess("订单状态:data",data);

	}
	

(2)service层

接口类

public interface OrderService extends BaseService<Order>{
	int updateOrderState(Order order);
	PageInfo<Map<String,Order>> select(Order order,int pageNum,int pageSize);
	long createOrderInRedis(Order order);
	long createPayInRedis(Order order);
	String updateOrderPayInRedis(Order order);
	boolean orderIsExist(Order order);
	boolean orderIsExistInRedis(Order order);
	String getPayState(Order order);
	ServerResponse pay(Order order,String path);
	ServerResponse aliCallback(Map<String, String> params);
}

实现类相关方法

//获取订单是否支付
	@Override
	public String getPayState(Order order) {
		String flag = orderDao.getPayState(order);
		return flag;
	}
	
	//在demo中的Main.java中直接复制粘贴过来的
	//按照注释修改成自己的业务所适应的代码
	@Override
	public ServerResponse pay(Order order,String path) {
		Map<String ,String> resultMap = Maps.newHashMap();
        resultMap.put("orderNo",order.getOrder_id());
		
		// (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
        // 需保证商户系统端不能重复,建议通过数据库sequence生成,
        String outTradeNo = order.getOrder_id();

        // (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店消费”
        String subject = new StringBuilder().append("KillSystemx系统当面付消费,订单号:").append(outTradeNo).toString();

        // (必填) 订单总金额,单位为元,不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        Goods goods = new Goods();
        goods.setGoods_id(order.getGoods_id());
        goods = goodsDao.getGoodsById(goods);
        String totalAmount = String.valueOf(goods.getGoods_price());

        // (必填) 付款条码,用户支付宝钱包手机app点击“付款”产生的付款条码
        String authCode = "用户自己的支付宝付款码"; // 条码示例,286648048691290423
        // (可选,根据需要决定是否使用) 订单可打折金额,可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折
        // 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
        //        String discountableAmount = "1.00"; //

        // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0.0";

        // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号)
        // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID
        String sellerId = "";

        // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品3件共20.00元"
        String body = new StringBuilder().append("购买商品1件共").append(totalAmount).append("元").toString();

        // 商户操作员编号,添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");

        // 支付超时,线下扫码交易定义为5分钟
        String timeoutExpress = "5m";

        // 商品明细列表,需填写购买商品详细信息,
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail
        GoodsDetail goods1 = GoodsDetail.newInstance(String.valueOf(goods.getGoods_id()), goods.getGoods_name(), Integer.valueOf(totalAmount), 1);
        // 创建好一个商品后添加至商品明细列表
        goodsDetailList.add(goods1);

        // 继续创建并添加第一条商品信息,用户购买的产品为“黑人牙刷”,单价为5.00元,购买了两件
        //GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
        //goodsDetailList.add(goods2);

        //String appAuthToken = "应用授权令牌";//根据真实值填写

        // 创建扫码支付请求builder,设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
            //            .setAppAuthToken(appAuthToken)
            .setOutTradeNo(outTradeNo).setSubject(subject)
            .setTotalAmount(totalAmount).setStoreId(storeId)
            .setUndiscountableAmount(undiscountableAmount).setBody(body).setOperatorId(operatorId)
            .setExtendParams(extendParams).setSellerId(sellerId)
            .setGoodsDetailList(goodsDetailList).setTimeoutExpress(timeoutExpress)
        	.setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url"));

        // 调用tradePay方法获取当面付应答
        //AlipayF2FPayResult result = service.tradePay(builder);
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝预支付成功: )");
                
                AlipayTradePrecreateResponse response = result.getResponse();
                dumpResponse(response);
                File folder = new File(path);
                if(!folder.exists()){
                    folder.setWritable(true);
                    folder.mkdirs();
                }

                // 需要修改为运行机器上的路径
                //细节细节细节
                String qrPath = String.format(path+"/qr-%s.png",response.getOutTradeNo());
                String qrFileName = String.format("qr-%s.png",response.getOutTradeNo());
                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath);

                File targetFile = new File(path,qrFileName);
                try {
                    FTPUtil.uploadFile(Lists.newArrayList(targetFile));
                } catch (IOException e) {
                    log.error("上传二维码异常",e);
                }
                log.info("qrPath:" + qrPath);
                String qrUrl = PropertiesUtil.getProperty("ftp.server.http.prefix")+targetFile.getName();
                resultMap.put("qrUrl",qrUrl);
                
                //直接测试回调中的代码
                //String flag = orderDao.updateOrderPayInRedis(order);
            	//InitFIFOListener.queue.offer(order);
                
                return ServerResponse.createBySuccess("支付宝预下单成功!!!",resultMap);

            case FAILED:
                log.error("支付宝预下单失败!!!");
                
                //库存加一
                goodsDao.setBackGoodsStock(order);
                //删除订单
                
                //删除支付订单
                
                return ServerResponse.createByErrorMessage("支付宝预下单失败!!!");

            case UNKNOWN:
                log.error("系统异常,预下单状态未知!!!");
              
                //库存加一
                goodsDao.setBackGoodsStock(order);
                //删除订单

                //删除支付订单
                
                return ServerResponse.createByErrorMessage("系统异常,预下单状态未知!!!");

            default:
                log.error("不支持的交易状态,交易返回异常!!!");
                
                //库存加一
                goodsDao.setBackGoodsStock(order);
                //删除订单

                //删除支付订单
                
                return ServerResponse.createByErrorMessage("不支持的交易状态,交易返回异常!!!");
        }
    }
    
    // 简单打印应答
	//在demo中的Main.java中直接复制粘贴过来的
    private void dumpResponse(AlipayResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                        response.getSubMsg()));
            }
            log.info("body:" + response.getBody());
        }
    }
    
    @Override
    public ServerResponse aliCallback(Map<String,String> params){
    	log.debug("支付宝回调啦!");
    	//pay.do中提交过去的订单号
        String orderNo = params.get("out_trade_no");
        //支付宝中的订单支付状态
        String tradeStatus = params.get("trade_status");
        log.debug(tradeStatus);
        //判断订单是否存在在本服务器
        Order order = new Order();
        order.setOrder_id(orderNo);
        order = orderDao.selectByorderIdInRedis(order);
        //在redis中查找不到订单支付信息,返回支付订单失效 ps.支付订单存在在redis中是有过期时间的
        if(orderDao.getPayState(order) == null){
        	goodsDao.setBackGoodsStock(order);
            return ServerResponse.createByErrorMessage("该支付订单已失效,请重新下单!");
        }
        //回调时发现本机服务器上的订单支付状态已经是支付成功状态了,返回支付宝重复调用,但是是成功的回调
        if("1".equals(orderDao.getPayState(order))){
        	return ServerResponse.createBySuccessMessage("支付宝重复调用");
        }
        //当回调订单状态是“TRADE_SUCCESS”时,返回订单支付成功
        if("TRADE_SUCCESS".equals(tradeStatus)){
        	String flag = orderDao.updateOrderPayInRedis(order);
        	InitFIFOListener.queue.offer(order);
            return ServerResponse.createBySuccessMessage("订单支付成功");
        }else {
        	return ServerResponse.createByErrorMessage("订单支付失败");
        }

(3)dao层相关代码

接口类

public interface OrderDao extends BaseDao<Order>{

	int updateOrderState(Order order);

	long createOrderInRedis(Order order);

	long createPayInRedis(Order order);

	String updateOrderPayInRedis(Order order);

	boolean orderIsExist(Order order);

	boolean orderIsExistInRedis(Order order);

	String getPayState(Order order);

	int createOrder(Order order);

	Order selectByorderIdInRedis(Order order);

	boolean createOrderAndupdateGoodsStock(Order order, Goods goods);
	
}

实现类相关方法

//redis操作:订单是否存在
@Override
	public boolean orderIsExistInRedis(Order order) {
		try {
			jedis = JedisUtil.getConn();
			return jedis.get(order.getOrder_id()) == null ? false : true;
		}finally {
			if(jedis == null) {
				jedis.close();
			}else {
				JedisUtil.returnConn(jedis);
			}
		}
	}

//redis操作:创建订单支付信息
	@Override
	public long createPayInRedis(Order order) {
		try {
			jedis = JedisUtil.getConn();
			return jedis.setnx(order.getOrder_id() + "_pay", "0");
		}finally {
			if(jedis.expire(order.getOrder_id() + "_pay", 600) != 1) {
				log.error("支付订单设置有效时间失败!");
			}
			if(jedis == null) {
				jedis.close();
			}else {
				JedisUtil.returnConn(jedis);
			}
			
		}
	}
	
	//redis操作:更新订单支付信息
	@Override
	public String updateOrderPayInRedis(Order order) {
		try {
			jedis = JedisUtil.getConn();
			String obj = jedis.getSet(order.getOrder_id() + "_pay", "1");
			return "支付成功"; 
		} finally { 
			if(jedis == null) {
				jedis.close();
			}else {
				JedisUtil.returnConn(jedis);
			}
		}
	}
	
	//redis操作:查看订单支付信息
	@Override
	public String getPayState(Order order) {
		try {
			jedis = JedisUtil.getConn();
			return jedis.get(order.getOrder_id() + "_pay");
		}finally { 
			if(jedis == null) {
				jedis.close();
			}else {
				JedisUtil.returnConn(jedis);
			}
		}
	}

	//redis操作:在redis中查询该订单号的订单信息
	@Override
	public Order selectByorderIdInRedis(Order order) {
		// TODO Auto-generated method stub
		try {
			jedis = JedisUtil.getConn();
			Order obj = new Order();
			String result = jedis.get(order.getOrder_id());
			String[] arrayResult = result.split(",");
			obj.setOrder_id(order.getOrder_id());
			obj.setTel_num(arrayResult[0]);
			obj.setAddress(arrayResult[1]+","+arrayResult[2]+","+arrayResult[3]);
			obj.setGoods_id(Integer.parseInt(arrayResult[4]));
			return obj;
		}finally { 
			if(jedis == null) {
				jedis.close();
			}else {
				JedisUtil.returnConn(jedis);
			}
		}
		
	}

项目详细代码请进入我的gitHub下载

有问题请指出,欢迎相互学习交流


版权声明:本文为xc1158840657原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>