diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 8935bc32..7c3db11f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,18 +1,22 @@ package me.chanjar.weixin.common.util; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.thoughtworks.xstream.annotations.XStreamAlias; + import me.chanjar.weixin.common.annotation.Required; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - /** *
  * bean操作的一些工具类
@@ -21,6 +25,7 @@ import java.util.Map;
  * 
*/ public class BeanUtils { + private static Logger log = LoggerFactory.getLogger(BeanUtils.class); /** * 检查bean里标记为@Required的field是否为空,为空则抛异常 @@ -48,41 +53,42 @@ public class BeanUtils { } if (!nullFields.isEmpty()) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("必填字段 " + nullFields + " 必须提供值").build()); + String msg = "必填字段 " + nullFields + " 必须提供值"; + log.debug(msg); + throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build()); } } - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map xmlBean2Map(Object bean) { - Map result = Maps.newHashMap(); - List fields = new ArrayList<>( Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.get(bean) == null) { - field.setAccessible(isAccessible); - continue; - } + /** + * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 + * + * @param bean 包含@XStreamAlias的xml bean对象 + * @return map对象 + */ + public static Map xmlBean2Map(Object bean) { + Map result = Maps.newHashMap(); + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.get(bean) == null) { + field.setAccessible(isAccessible); + continue; + } - if (field.isAnnotationPresent(XStreamAlias.class)) { - result.put(field.getAnnotation(XStreamAlias.class).value(), - field.get(bean).toString()); - } + if (field.isAnnotationPresent(XStreamAlias.class)) { + result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); + } - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException - | IllegalAccessException e) { - e.printStackTrace(); - } + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } - } + } - return result; - } + return result; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index df4c5a5e..84655a86 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -73,11 +73,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { "REFUND_SOURCE_UNSETTLED_FUNDS"}; protected final Logger log = LoggerFactory.getLogger(this.getClass()); private WxMpService wxMpService; - private WxMpConfigStorage config; + private WxMpConfigStorage config = null; public WxMpPayServiceImpl(WxMpService wxMpService) { this.wxMpService = wxMpService; - this.config = wxMpService.getWxMpConfigStorage(); + } + + private WxMpConfigStorage getConfig(){ + if(config == null){ + this.config = wxMpService.getWxMpConfigStorage(); + } + return this.config; } @Override @@ -89,8 +95,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxPayRefundRequest.class); xstream.processAnnotations(WxPayRefundResult.class); - request.setAppid(this.config.getAppId()); - String partnerId = this.config.getPartnerId(); + request.setAppid(getConfig().getAppId()); + String partnerId = getConfig().getPartnerId(); request.setMchId(partnerId); request.setNonceStr(System.currentTimeMillis() + ""); request.setOpUserId(partnerId); @@ -120,8 +126,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); request.setRefundId(StringUtils.trimToNull(refundId)); - request.setAppid(this.config.getAppId()); - request.setMchId(this.config.getPartnerId()); + request.setAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); @@ -138,17 +144,20 @@ public class WxMpPayServiceImpl implements WxMpPayService { private void checkResult(WxPayBaseResult result) throws WxErrorException { //校验返回结果签名 if(!checkSign(result.toMap())){ + log.debug("校验结果签名失败,参数:{}",result.toMap()); throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); } //校验结果是否成功 if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1) - .setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: " - + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " - + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) - .build()); + WxError error = WxError.newBuilder().setErrorCode(-1) + .setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: " + + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " + + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) + .build(); + log.debug("结果校验失败,参数:{},详细:{}",result.toMap(),error); + throw new WxErrorException(error); } } @@ -157,7 +166,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { if (StringUtils.isNotBlank(request.getRefundAccount())) { if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) { - throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一"); + throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一,实际值:"+ request.getRefundAccount()); } } @@ -169,10 +178,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { try { + log.trace("微信支付回调参数详细:{}", xmlData); XStream xstream = XStreamInitializer.getInstance(); - xstream.autodetectAnnotations(true); + xstream.processAnnotations(WxPayOrderNotifyResult.class); xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(),xstream.getReflectionProvider())); WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlData); + log.debug("微信支付回调结果对象:{}",result); this.checkResult(result); return result; }catch (WxErrorException e) { @@ -192,8 +203,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxPaySendRedpackRequest.class); xstream.processAnnotations(WxPaySendRedpackResult.class); - request.setWxAppid(this.config.getAppId()); - String mchId = this.config.getPartnerId(); + request.setWxAppid(getConfig().getAppId()); + String mchId = getConfig().getPartnerId(); request.setMchId(mchId); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); @@ -220,8 +231,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setMchBillNo(mchBillNo); request.setBillType("MCHT"); - request.setAppid(this.config.getAppId()); - String mchId = this.config.getPartnerId(); + request.setAppid(getConfig().getAppId()); + String mchId = getConfig().getPartnerId(); request.setMchId(mchId); request.setNonceStr(System.currentTimeMillis() + ""); @@ -237,7 +248,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public String createSign(Object xmlBean) { - return createSign(BeanUtils.xmlBean2Map(xmlBean),this.config.getPartnerKey()); + return createSign(BeanUtils.xmlBean2Map(xmlBean),getConfig().getPartnerKey()); } @Override @@ -247,7 +258,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public String createSign(Map params) { - return createSign(params,this.config.getPartnerKey()); + return createSign(params,getConfig().getPartnerKey()); } @Override @@ -268,7 +279,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public boolean checkSign(Object xmlBean) { - return checkSign(BeanUtils.xmlBean2Map(xmlBean) , this.config.getPartnerKey()); + return checkSign(BeanUtils.xmlBean2Map(xmlBean) , getConfig().getPartnerKey()); } @Override @@ -278,7 +289,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public boolean checkSign(Map params) { - return checkSign(params , this.config.getPartnerKey()); + return checkSign(params , getConfig().getPartnerKey()); } @Override @@ -302,8 +313,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setTransactionId(StringUtils.trimToNull(transactionId)); - request.setAppid(this.config.getAppId()); - request.setMchId(this.config.getPartnerId()); + request.setAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); @@ -328,8 +339,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); - request.setAppid(this.config.getAppId()); - request.setMchId(this.config.getPartnerId()); + request.setAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); @@ -345,37 +356,27 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException { - checkParameters(request); XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxPayUnifiedOrderRequest.class); xstream.processAnnotations(WxPayUnifiedOrderResult.class); - WxMpConfigStorage config = this.config; + request.setAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); + request.setNotifyURL(getConfig().getNotifyURL()); + request.setTradeType(getConfig().getTradeType()); + request.setNonceStr(System.currentTimeMillis() + ""); + + checkParameters(request);//校验参数 - //如果没有设置,则使用配置中默认值 - if(StringUtils.isBlank(request.getAppid())){ - request.setAppid(config.getAppId()); - } - if(StringUtils.isBlank(request.getMchId())){ - request.setMchId(config.getPartnerId()); - } - if(StringUtils.isBlank(request.getNotifyURL())){ - request.setNotifyURL(config.getNotifyURL()); - } - if(StringUtils.isBlank(request.getTradeType())){ - request.setTradeType(config.getTradeType()); - } - if(StringUtils.isBlank(request.getNonceStr())){ - request.setNonceStr(System.currentTimeMillis() + ""); - } request.setSign(this.createSign(request)); - String url = PAY_BASE_URL + "/pay/unifiedorder"; + String xmlParam = xstream.toXML(request); + log.debug("微信统一下单接口,URL:{},参数:{}",url, xmlParam); - String responseContent = this.executeRequest(url, xstream.toXML(request)); - WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream - .fromXML(responseContent); + String responseContent = this.executeRequest(url, xmlParam); + log.debug("微信统一下单接口,URL:{},结果:{}",url, responseContent); + WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream.fromXML(responseContent); this.checkResult(result); return result; } @@ -384,7 +385,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { BeanUtils.checkRequiredFields(request); if (!ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) { - throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一"); + throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一,实际值:"+request.getTradeType()); } if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) { @@ -406,7 +407,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { } Map payInfo = new HashMap<>(); - payInfo.put("appId", this.config.getAppId()); + payInfo.put("appId", getConfig().getAppId()); // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); payInfo.put("nonceStr", System.currentTimeMillis() + ""); @@ -427,8 +428,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxEntPayRequest.class); xstream.processAnnotations(WxEntPayResult.class); - request.setMchAppid(this.config.getAppId()); - request.setMchId(this.config.getPartnerId()); + request.setMchAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); @@ -447,8 +448,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxEntPayQueryResult.class); WxEntPayQueryRequest request = new WxEntPayQueryRequest(); - request.setAppid(this.config.getAppId()); - request.setMchId(this.config.getPartnerId()); + request.setAppid(getConfig().getAppId()); + request.setMchId(getConfig().getPartnerId()); request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java index 7cea57ba..60b3f688 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java @@ -13,47 +13,52 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * 支付异步通知代金券详细 */ public class WxPayOrderNotifyCoupon implements Serializable { - /** - * @fields serialVersionUID - */ - private static final long serialVersionUID = -4165343733538156097L; - - @XStreamAlias("coupon_id") - private String couponId; - @XStreamAlias("coupon_type") - private String couponType; - @XStreamAlias("coupon_fee") - private Integer couponFee; - - public String getCouponId() { - return couponId; - } - public void setCouponId(String couponId) { - this.couponId = couponId; - } - public String getCouponType() { - return couponType; - } - public void setCouponType(String couponType) { - this.couponType = couponType; - } - public Integer getCouponFee() { - return couponFee; - } - public void setCouponFee(Integer couponFee) { - this.couponFee = couponFee; - } - - public Map toMap(int index){ - Map map = new HashMap<>(); - map.put("coupon_id_"+index, this.getCouponId()); - map.put("coupon_type_"+index, this.getCouponType()); - map.put("coupon_fee_"+index, this.getCouponFee()+""); - return map; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE); - } + /** + * @fields serialVersionUID + */ + private static final long serialVersionUID = -4165343733538156097L; + + @XStreamAlias("coupon_id") + private String couponId; + @XStreamAlias("coupon_type") + private String couponType; + @XStreamAlias("coupon_fee") + private Integer couponFee; + + public String getCouponId() { + return couponId; + } + + public void setCouponId(String couponId) { + this.couponId = couponId; + } + + public String getCouponType() { + return couponType; + } + + public void setCouponType(String couponType) { + this.couponType = couponType; + } + + public Integer getCouponFee() { + return couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public Map toMap(int index) { + Map map = new HashMap<>(); + map.put("coupon_id_" + index, this.getCouponId()); + map.put("coupon_type_" + index, this.getCouponType()); + map.put("coupon_fee_" + index, this.getCouponFee() + ""); + return map; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java index 54f4fc56..a1313ea0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java @@ -1,6 +1,5 @@ package me.chanjar.weixin.mp.bean.pay; - import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamOmitField; @@ -9,53 +8,53 @@ import me.chanjar.weixin.common.util.xml.XStreamInitializer; @XStreamAlias("xml") public class WxPayOrderNotifyResponse { - @XStreamOmitField - private transient static final String FAIL ="FAIL"; - @XStreamOmitField - private transient static final String SUCCESS ="SUCCESS"; - - @XStreamAlias("return_code") - private String returnCode; - @XStreamAlias("return_msg") - private String returnMsg; - - - public String getReturnCode() { - return returnCode; - } - public void setReturnCode(String returnCode) { - this.returnCode = returnCode; - } - public String getReturnMsg() { - return returnMsg; - } - public void setReturnMsg(String returnMsg) { - this.returnMsg = returnMsg; - } - - - public WxPayOrderNotifyResponse() { - super(); - } - public WxPayOrderNotifyResponse(String returnCode, String returnMsg) { - super(); - this.returnCode = returnCode; - this.returnMsg = returnMsg; - } - - - public static String fail(String msg){ - WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL,msg); - XStream xstream = XStreamInitializer.getInstance(); - xstream.autodetectAnnotations(true); - return xstream.toXML(response); - } - - - public static String success(String msg){ - WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS,msg); - XStream xstream = XStreamInitializer.getInstance(); - xstream.autodetectAnnotations(true); - return xstream.toXML(response); - } + @XStreamOmitField + private transient static final String FAIL = "FAIL"; + @XStreamOmitField + private transient static final String SUCCESS = "SUCCESS"; + + @XStreamAlias("return_code") + private String returnCode; + @XStreamAlias("return_msg") + private String returnMsg; + + public String getReturnCode() { + return returnCode; + } + + public void setReturnCode(String returnCode) { + this.returnCode = returnCode; + } + + public String getReturnMsg() { + return returnMsg; + } + + public void setReturnMsg(String returnMsg) { + this.returnMsg = returnMsg; + } + + public WxPayOrderNotifyResponse() { + super(); + } + + public WxPayOrderNotifyResponse(String returnCode, String returnMsg) { + super(); + this.returnCode = returnCode; + this.returnMsg = returnMsg; + } + + public static String fail(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } + + public static String success(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java index 1f90f0b9..bdd440b9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java @@ -24,107 +24,107 @@ import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult; public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter { - public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) { - super(mapper, reflectionProvider); - } - - @Override - @SuppressWarnings("rawtypes") - public boolean canConvert(Class type) { - return type.equals(WxPayOrderNotifyResult.class); - } - - @Override - public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) { - super.marshal(original, writer, context); - WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original; - List list = obj.getCouponList(); - if (list == null || list.size() == 0) { - return; - } - for (int i = 0; i < list.size(); i++) { - WxPayOrderNotifyCoupon coupon = list.get(i); - writer.startNode("coupon_id_" + i); - writer.setValue(coupon.getCouponId()); - writer.endNode(); - writer.startNode("coupon_type_" + i); - writer.setValue(coupon.getCouponType()); - writer.endNode(); - writer.startNode("coupon_fee_" + i); - writer.setValue(coupon.getCouponFee() + ""); - writer.endNode(); - } - } - - @Override - protected void marshallField(MarshallingContext context, Object newObj, Field field) { - if (field.getName().equals("couponList")) { - return; - } else { - super.marshallField(context, newObj, field); - } - } - - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult(); - - List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); - Map fieldMap = getFieldMap(fields); - - List coupons = new ArrayList<>(10); - while (reader.hasMoreChildren()) { - reader.moveDown(); - if (fieldMap.containsKey(reader.getNodeName())) { - Field field = fieldMap.get(reader.getNodeName()); - setFieldValue(context, obj, field); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) { - String id = (String) context.convertAnother(obj, String.class); - getIndex(coupons, reader.getNodeName()).setCouponId(id); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) { - String type = (String) context.convertAnother(obj, String.class); - getIndex(coupons, reader.getNodeName()).setCouponType(type); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) { - Integer fee = (Integer) context.convertAnother(obj, Integer.class); - getIndex(coupons, reader.getNodeName()).setCouponFee(fee); - } - reader.moveUp(); - } - - obj.setCouponList(coupons); - return obj; - } - - private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) { - Object val = context.convertAnother(obj, field.getType()); - try { - if (val != null) { - PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); - pd.getWriteMethod().invoke(obj, val); - } - } catch (Exception e) { - } - } - - private Map getFieldMap(List fields) { - Map fieldMap = Maps.uniqueIndex(fields, new Function() { - @Override - public String apply(Field field) { - if (field.isAnnotationPresent(XStreamAlias.class)) { - return field.getAnnotation(XStreamAlias.class).value(); - } - return field.getName(); - } - }); - return fieldMap; - } - - private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) { - Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1)); - if (index >= coupons.size() || coupons.get(index) == null) { - coupons.add(index, new WxPayOrderNotifyCoupon()); - } - return coupons.get(index); - } + public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + + @Override + @SuppressWarnings("rawtypes") + public boolean canConvert(Class type) { + return type.equals(WxPayOrderNotifyResult.class); + } + + @Override + public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) { + super.marshal(original, writer, context); + WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original; + List list = obj.getCouponList(); + if (list == null || list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + WxPayOrderNotifyCoupon coupon = list.get(i); + writer.startNode("coupon_id_" + i); + writer.setValue(coupon.getCouponId()); + writer.endNode(); + writer.startNode("coupon_type_" + i); + writer.setValue(coupon.getCouponType()); + writer.endNode(); + writer.startNode("coupon_fee_" + i); + writer.setValue(coupon.getCouponFee() + ""); + writer.endNode(); + } + } + + @Override + protected void marshallField(MarshallingContext context, Object newObj, Field field) { + if (field.getName().equals("couponList")) { + return; + } else { + super.marshallField(context, newObj, field); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult(); + + List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); + Map fieldMap = getFieldMap(fields); + + List coupons = new ArrayList<>(10); + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (fieldMap.containsKey(reader.getNodeName())) { + Field field = fieldMap.get(reader.getNodeName()); + setFieldValue(context, obj, field); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) { + String id = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponId(id); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) { + String type = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponType(type); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) { + Integer fee = (Integer) context.convertAnother(obj, Integer.class); + getIndex(coupons, reader.getNodeName()).setCouponFee(fee); + } + reader.moveUp(); + } + + obj.setCouponList(coupons); + return obj; + } + + private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) { + Object val = context.convertAnother(obj, field.getType()); + try { + if (val != null) { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); + pd.getWriteMethod().invoke(obj, val); + } + } catch (Exception e) { + } + } + + private Map getFieldMap(List fields) { + Map fieldMap = Maps.uniqueIndex(fields, new Function() { + @Override + public String apply(Field field) { + if (field.isAnnotationPresent(XStreamAlias.class)) { + return field.getAnnotation(XStreamAlias.class).value(); + } + return field.getName(); + } + }); + return fieldMap; + } + + private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) { + Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1)); + if (index >= coupons.size() || coupons.get(index) == null) { + coupons.add(index, new WxPayOrderNotifyCoupon()); + } + return coupons.get(index); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java index 0a6815d8..60a25c19 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java @@ -388,7 +388,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializ @Override public Map toMap(){ Map resultMap = BeanUtils.xmlBean2Map(this); - if(this.getCouponCount() > 0){ + if(this.getCouponCount() != null && this.getCouponCount() > 0){ for (int i = 0; i < this.getCouponCount(); i++) { WxPayOrderNotifyCoupon coupon = couponList.get(i); resultMap.putAll(coupon.toMap(i));