|
@@ -1,13 +1,19 @@
|
|
package com.zzys.qhyscredit.wxpay.service.impl;
|
|
package com.zzys.qhyscredit.wxpay.service.impl;
|
|
|
|
|
|
-import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
|
+import cn.hutool.core.date.DateUnit;
|
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonObject;
|
|
|
|
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
|
|
|
+import com.zzys.qhyscredit.channel.invitation.dao.model.LinkEntity;
|
|
|
|
+import com.zzys.qhyscredit.channel.invitation.service.LinkService;
|
|
import com.zzys.qhyscredit.channel.order.dao.model.OrderEntity;
|
|
import com.zzys.qhyscredit.channel.order.dao.model.OrderEntity;
|
|
import com.zzys.qhyscredit.channel.order.service.OrderService;
|
|
import com.zzys.qhyscredit.channel.order.service.OrderService;
|
|
import com.zzys.qhyscredit.enums.OrderStatus;
|
|
import com.zzys.qhyscredit.enums.OrderStatus;
|
|
import com.zzys.qhyscredit.enums.wxpay.WxTradeState;
|
|
import com.zzys.qhyscredit.enums.wxpay.WxTradeState;
|
|
import com.zzys.qhyscredit.utils.Constant;
|
|
import com.zzys.qhyscredit.utils.Constant;
|
|
|
|
+import com.zzys.qhyscredit.utils.DateUtil;
|
|
import com.zzys.qhyscredit.utils.OrderNoUtil;
|
|
import com.zzys.qhyscredit.utils.OrderNoUtil;
|
|
import com.zzys.qhyscredit.wxpay.service.PaymentInfoService;
|
|
import com.zzys.qhyscredit.wxpay.service.PaymentInfoService;
|
|
import com.zzys.qhyscredit.wxpay.service.WxPayService;
|
|
import com.zzys.qhyscredit.wxpay.service.WxPayService;
|
|
@@ -20,6 +26,7 @@ import org.apache.http.entity.StringEntity;
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
import org.apache.http.util.EntityUtils;
|
|
import org.apache.http.util.EntityUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.util.Base64Utils;
|
|
import org.springframework.util.Base64Utils;
|
|
@@ -31,9 +38,11 @@ import java.io.InputStream;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.security.GeneralSecurityException;
|
|
import java.security.GeneralSecurityException;
|
|
import java.security.KeyPair;
|
|
import java.security.KeyPair;
|
|
|
|
+import java.security.PrivateKey;
|
|
import java.security.Signature;
|
|
import java.security.Signature;
|
|
import java.util.Base64;
|
|
import java.util.Base64;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
@@ -62,6 +71,14 @@ public class WxPayServiceImpl implements WxPayService {
|
|
@Autowired
|
|
@Autowired
|
|
private WXUtils wxUtils;
|
|
private WXUtils wxUtils;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private LinkService linkService;
|
|
|
|
+
|
|
|
|
+ @Value("${weixin.payDomain}")
|
|
|
|
+ private String payDomain;
|
|
|
|
+
|
|
|
|
+ @Value("${weixin.mchid}")
|
|
|
|
+ private String mchid;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 处理订单
|
|
* 处理订单
|
|
@@ -96,8 +113,16 @@ public class WxPayServiceImpl implements WxPayService {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
orderEntity.setPayStatus(OrderStatus.SUCCESS.getType());
|
|
orderEntity.setPayStatus(OrderStatus.SUCCESS.getType());
|
|
|
|
+ orderEntity.setUpdateTime(DateUtil.getNowTime());
|
|
//更新订单状态
|
|
//更新订单状态
|
|
this.orderService.save(orderEntity);
|
|
this.orderService.save(orderEntity);
|
|
|
|
+
|
|
|
|
+ //更新邀请链接状态
|
|
|
|
+ LinkEntity linkEntity = this.linkService.findByOrderNo(orderNo);
|
|
|
|
+ if(linkEntity != null){
|
|
|
|
+ linkEntity.setStatus(Constant.ONE);
|
|
|
|
+ this.linkService.save(linkEntity);
|
|
|
|
+ }
|
|
//记录支付日志
|
|
//记录支付日志
|
|
paymentInfoService.createPaymentInfo(plainText);
|
|
paymentInfoService.createPaymentInfo(plainText);
|
|
} finally {
|
|
} finally {
|
|
@@ -121,6 +146,13 @@ public class WxPayServiceImpl implements WxPayService {
|
|
order.setPayStatus(OrderStatus.CANCEL.getType());
|
|
order.setPayStatus(OrderStatus.CANCEL.getType());
|
|
this.orderService.save(order);
|
|
this.orderService.save(order);
|
|
}
|
|
}
|
|
|
|
+ //更新邀请连接状态
|
|
|
|
+ LinkEntity link = this.linkService.findByOrderNo(orderNo);
|
|
|
|
+ if(link != null){
|
|
|
|
+ link.setStatus(Constant.ZERO);
|
|
|
|
+ this.linkService.save(link);
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -130,6 +162,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
public Map queryOrder(String orderNo) throws IOException {
|
|
public Map queryOrder(String orderNo) throws IOException {
|
|
|
|
+
|
|
try (CloseableHttpResponse response = wxUtils.queryCode(orderNo)) {
|
|
try (CloseableHttpResponse response = wxUtils.queryCode(orderNo)) {
|
|
Map resultMap = new HashMap();
|
|
Map resultMap = new HashMap();
|
|
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
|
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
|
@@ -143,11 +176,19 @@ public class WxPayServiceImpl implements WxPayService {
|
|
Map<String, String> resultBody = gson.fromJson(body, HashMap.class);
|
|
Map<String, String> resultBody = gson.fromJson(body, HashMap.class);
|
|
//获取微信支付端的订单状态
|
|
//获取微信支付端的订单状态
|
|
String tradeState = resultBody.get("trade_state");
|
|
String tradeState = resultBody.get("trade_state");
|
|
|
|
+
|
|
//判断订单状态
|
|
//判断订单状态
|
|
if (WxTradeState.SUCCESS.getType().equals(tradeState)) {
|
|
if (WxTradeState.SUCCESS.getType().equals(tradeState)) {
|
|
//如果确认订单已支付则更新本地订单状态
|
|
//如果确认订单已支付则更新本地订单状态
|
|
|
|
+ this.orderService.updateOrderStatus(orderNo,OrderStatus.SUCCESS);
|
|
//记录支付日志
|
|
//记录支付日志
|
|
paymentInfoService.createPaymentInfo(body);
|
|
paymentInfoService.createPaymentInfo(body);
|
|
|
|
+ //更新邀请连接状态
|
|
|
|
+ LinkEntity link = this.linkService.findByOrderNo(orderNo);
|
|
|
|
+ if(link != null){
|
|
|
|
+ link.setStatus(Constant.ONE);
|
|
|
|
+ this.linkService.save(link);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// log.info("成功200");
|
|
// log.info("成功200");
|
|
@@ -193,32 +234,41 @@ public class WxPayServiceImpl implements WxPayService {
|
|
// }
|
|
// }
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public String aspiPay(JSONObject paramObject) throws Exception {
|
|
|
|
|
|
+ public String aspiPay(JSONObject paramObject, String linkId) throws Exception {
|
|
log.info("aspi预下单订单");
|
|
log.info("aspi预下单订单");
|
|
//生成订单
|
|
//生成订单
|
|
- return pay(paramObject);
|
|
|
|
|
|
+ return pay(paramObject,linkId);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public String aspiPay(JSONObject paramObject) throws IOException {
|
|
|
|
+ log.info("aspi预下单订单--信用等级");
|
|
|
|
+ return pay(paramObject);
|
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public List<OrderEntity> findByChannelIdAndTitle(String channelId, String title) {
|
|
|
|
+ return this.orderService.findByChannelIdAndTitle(channelId,title);
|
|
|
|
+ }
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
- String pay(JSONObject paramData) throws Exception {
|
|
|
|
|
|
+ String pay(JSONObject paramData) throws IOException {
|
|
String userId = paramData.getString("userId");
|
|
String userId = paramData.getString("userId");
|
|
OrderEntity orderEntity = new OrderEntity();
|
|
OrderEntity orderEntity = new OrderEntity();
|
|
OrderNoUtil orderNoUtil = new OrderNoUtil(1,1);
|
|
OrderNoUtil orderNoUtil = new OrderNoUtil(1,1);
|
|
- orderEntity.setOrderNo(String.valueOf(orderNoUtil.nextId()));
|
|
|
|
|
|
+ orderEntity.setOrderNo("Order_s_"+orderNoUtil.nextId());
|
|
paramData.put("orderNo",orderEntity.getOrderNo());
|
|
paramData.put("orderNo",orderEntity.getOrderNo());
|
|
orderEntity.setPayStatus(Constant.ZERO);//待支付状态
|
|
orderEntity.setPayStatus(Constant.ZERO);//待支付状态
|
|
orderEntity.setCreateDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setCreateDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setStatus(Constant.ZERO);//未结算
|
|
orderEntity.setStatus(Constant.ZERO);//未结算
|
|
- orderEntity.setAmount(paramData.getInteger("amount"));
|
|
|
|
|
|
+ orderEntity.setAmount(paramData.getDoubleValue("amount"));
|
|
orderEntity.setChannelId(paramData.getString("channelId"));
|
|
orderEntity.setChannelId(paramData.getString("channelId"));
|
|
orderEntity.setTitle(paramData.getString("title"));
|
|
orderEntity.setTitle(paramData.getString("title"));
|
|
//订单起始日期和订单截止日期作用未知
|
|
//订单起始日期和订单截止日期作用未知
|
|
orderEntity.setEffectiveDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setEffectiveDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setExpirationDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setExpirationDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
orderEntity.setUserId(userId);
|
|
orderEntity.setUserId(userId);
|
|
|
|
+ orderEntity.setType("1");
|
|
orderEntity = this.orderService.save(orderEntity);
|
|
orderEntity = this.orderService.save(orderEntity);
|
|
CloseableHttpResponse response = wxUtils.jsapiPay(paramData);
|
|
CloseableHttpResponse response = wxUtils.jsapiPay(paramData);
|
|
//获取响应
|
|
//获取响应
|
|
@@ -227,8 +277,6 @@ public class WxPayServiceImpl implements WxPayService {
|
|
int statusCode = response.getStatusLine().getStatusCode();//获取状态码
|
|
int statusCode = response.getStatusLine().getStatusCode();//获取状态码
|
|
if (statusCode == 200){//成功
|
|
if (statusCode == 200){//成功
|
|
log.info("成功,返回结果 = "+bodyAsString);
|
|
log.info("成功,返回结果 = "+bodyAsString);
|
|
- }else if (statusCode == 204){//成功 无返回body
|
|
|
|
- log.info("成功");
|
|
|
|
}else {
|
|
}else {
|
|
log.info("下单失败,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
|
|
log.info("下单失败,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
|
|
throw new IOException("request failed"+bodyAsString);
|
|
throw new IOException("request failed"+bodyAsString);
|
|
@@ -242,6 +290,56 @@ public class WxPayServiceImpl implements WxPayService {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
+ String pay(JSONObject paramData,String linkId) throws Exception {
|
|
|
|
+ String userId = paramData.getString("userId");
|
|
|
|
+ OrderEntity orderEntity = new OrderEntity();
|
|
|
|
+ OrderNoUtil orderNoUtil = new OrderNoUtil(1,1);
|
|
|
|
+ orderEntity.setOrderNo("Order_s_"+orderNoUtil.nextId());
|
|
|
|
+ paramData.put("orderNo",orderEntity.getOrderNo());
|
|
|
|
+ orderEntity.setPayStatus(Constant.ZERO);//待支付状态
|
|
|
|
+ orderEntity.setCreateDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
|
|
+ orderEntity.setStatus(Constant.ZERO);//未结算
|
|
|
|
+ orderEntity.setAmount(paramData.getDoubleValue("amount"));
|
|
|
|
+ orderEntity.setChannelId(paramData.getString("channelId"));
|
|
|
|
+ orderEntity.setTitle(paramData.getString("title"));
|
|
|
|
+ //订单起始日期和订单截止日期作用未知
|
|
|
|
+ orderEntity.setEffectiveDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
|
|
+ orderEntity.setExpirationDate(com.zzys.qhyscredit.utils.DateUtil.getNowTime());
|
|
|
|
+ orderEntity.setUserId(userId);
|
|
|
|
+ orderEntity.setType("3");
|
|
|
|
+ orderEntity = this.orderService.save(orderEntity);
|
|
|
|
+ LinkEntity link = this.linkService.findById(linkId);
|
|
|
|
+ link.setOrderNo(orderEntity.getOrderNo());
|
|
|
|
+ this.linkService.save(link);
|
|
|
|
+ if(orderEntity.getAmount() == 0d){
|
|
|
|
+ log.info("金额为0 ,不调用微信支付");
|
|
|
|
+ orderEntity.setPayStatus(Constant.ONE);
|
|
|
|
+ this.orderService.save(orderEntity);
|
|
|
|
+ return "0000";
|
|
|
|
+ }
|
|
|
|
+ CloseableHttpResponse response = wxUtils.jsapiPay(paramData);
|
|
|
|
+ //获取响应
|
|
|
|
+ try {
|
|
|
|
+ String bodyAsString = EntityUtils.toString(response.getEntity());//获取响应体
|
|
|
|
+ int statusCode = response.getStatusLine().getStatusCode();//获取状态码
|
|
|
|
+ if (statusCode == 200){//成功
|
|
|
|
+ log.info("成功,返回结果 = "+bodyAsString);
|
|
|
|
+ }else {
|
|
|
|
+ log.info("下单失败,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
|
|
|
|
+ throw new IOException("request failed"+bodyAsString);
|
|
|
|
+ }
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ //响应结果
|
|
|
|
+ return gson.fromJson(bodyAsString,HashMap.class).get("prepay_id").toString();
|
|
|
|
+ }finally {
|
|
|
|
+ response.close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* V3 SHA256withRSA 签名.
|
|
* V3 SHA256withRSA 签名.
|
|
*
|
|
*
|
|
@@ -330,5 +428,121 @@ public class WxPayServiceImpl implements WxPayService {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public PrivateKey getPrivateKey(String privateKeyPath) {
|
|
|
|
+ try {
|
|
|
|
+ String path = this.getClass().getClassLoader().getResource(privateKeyPath).getPath();
|
|
|
|
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(privateKeyPath);
|
|
|
|
+ log.info(path);
|
|
|
|
+ return PemUtil.loadPrivateKey(is);//new ByteArrayInputStream(fileName.getBytes("utf-8"))
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new RuntimeException("私钥文件不存在",e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void checkOrderStatus() {
|
|
|
|
+ DateTime nowDate = cn.hutool.core.date.DateUtil.date();
|
|
|
|
+ //获取未支付订单
|
|
|
|
+ List<OrderEntity> infos = orderService.findByPayStatus(Constant.ZERO);
|
|
|
|
+ if(infos == null || infos.size() ==0){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (OrderEntity info : infos){
|
|
|
|
+ try {
|
|
|
|
+ String orderNo = info.getOrderNo();
|
|
|
|
+ //log.warn("根据订单号核实订单状态 ===> {}", orderNo);
|
|
|
|
+ //调用微信支付查单接口
|
|
|
|
+ Map queryResult = this.queryOrder(orderNo);
|
|
|
|
+ String result = queryResult.get("body").toString();
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ Map<String, String> resultMap = gson.fromJson(result, HashMap.class);
|
|
|
|
+ //获取微信支付端的订单状态
|
|
|
|
+ String tradeState = resultMap.get("trade_state");
|
|
|
|
+ //判断订单状态
|
|
|
|
+ if(WxTradeState.SUCCESS.getType().equals(tradeState)){
|
|
|
|
+ // log.warn("核实订单已支付 ===> {}", orderNo);
|
|
|
|
+ //如果确认订单已支付则更新本地订单状态
|
|
|
|
+ orderService.updateOrderStatus(orderNo,OrderStatus.SUCCESS);
|
|
|
|
+ //记录支付日志
|
|
|
|
+ paymentInfoService.createPaymentInfo(result);
|
|
|
|
+ }
|
|
|
|
+ //判断url是否有效 两小时内有效
|
|
|
|
+ long betweenMinute = cn.hutool.core.date.DateUtil.between(nowDate, cn.hutool.core.date.DateUtil.parseDateTime(info.getCreateDate()), DateUnit.MINUTE);
|
|
|
|
+ if(WxTradeState.NOTPAY.getType().equals(tradeState) && betweenMinute >= 5 ){
|
|
|
|
+ //log.warn("核实订单未支付 ===> {}", orderNo);
|
|
|
|
+ //如果订单未支付,则调用关单接口
|
|
|
|
+ this.closeOrder(orderNo);
|
|
|
|
+ //更新本地订单状态
|
|
|
|
+ orderService.updateOrderStatus(orderNo, OrderStatus.CLOSED);
|
|
|
|
+ //更新邀请连接状态
|
|
|
|
+
|
|
|
|
+ LinkEntity link = this.linkService.findByOrderNo(orderNo);
|
|
|
|
+ if(link != null){
|
|
|
|
+ link.setStatus(Constant.ZERO);
|
|
|
|
+ this.linkService.save(link);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if(WxTradeState.CLOSED.getType().equals(tradeState)){
|
|
|
|
+ //更新本地订单状态
|
|
|
|
+ orderService.updateOrderStatus(orderNo, OrderStatus.CLOSED);
|
|
|
|
+ //更新邀请连接状态
|
|
|
|
+ LinkEntity link = this.linkService.findByOrderNo(orderNo);
|
|
|
|
+ if(link != null){
|
|
|
|
+ link.setStatus(Constant.ZERO);
|
|
|
|
+ this.linkService.save(link);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private void closeOrder(String orderNo) throws Exception {
|
|
|
|
+ log.info("关单接口的调用,订单号 ===> {}", orderNo);
|
|
|
|
+
|
|
|
|
+ //创建远程请求对象
|
|
|
|
+ String url = String.format("/v3/pay/transactions/out-trade-no/%s/close", orderNo);
|
|
|
|
+ url = payDomain.concat(url);
|
|
|
|
+ HttpPost httpPost = new HttpPost(url);
|
|
|
|
+
|
|
|
|
+ //组装json请求体
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ Map<String, String> paramsMap = new HashMap<>();
|
|
|
|
+ paramsMap.put("mchid", mchid);
|
|
|
|
+ String jsonParams = gson.toJson(paramsMap);
|
|
|
|
+ log.info("请求参数 ===> {}", jsonParams);
|
|
|
|
+
|
|
|
|
+ //将请求参数设置到请求对象中
|
|
|
|
+ StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
|
|
|
+ entity.setContentType("application/json");
|
|
|
|
+ httpPost.setEntity(entity);
|
|
|
|
+ httpPost.setHeader("Accept", "application/json");
|
|
|
|
+
|
|
|
|
+ //完成签名并执行请求
|
|
|
|
+ CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
|
|
|
+ if (statusCode == 200) { //处理成功
|
|
|
|
+ log.info("成功200");
|
|
|
|
+ } else if (statusCode == 204) { //处理成功,无返回Body
|
|
|
|
+ log.info("成功204");
|
|
|
|
+ } else {
|
|
|
|
+ log.info("取消订单失败,响应码 = " + statusCode);
|
|
|
|
+ throw new IOException("request failed");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } finally {
|
|
|
|
+ response.close();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|