• 自定义XStream -Converter解析微信支付结果


    上周开发微信代扣,微信代扣结果通知的平面XML非常复杂,
     
    对于子节点,需要使用者实现ComplexConvert接口进行解析...
    * 总代金券退款金额 coupon_refund_fee_$n 否 Int 100 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
    * 退款代金券使用数量 coupon_refund_count_$n 否 Int 1 退款代金券使用数量 ,$n为下标,从0开始编号
    * 退款代金券ID coupon_refund_id_$n_$m 否 String(20) 10000 退款代金券ID, $n为下标,$m为下标,从0开始编号
    * 单个代金券退款金额 coupon_refund_fee_$n_$m 否 Int 100 单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号
    * @see <a herf="https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_7&index=8">微信支付结果通知</a>
    public class WeixinHttpExecutor implements HttpExecutor {
    private static final Logger LOG= LoggerFactory.getLogger(WeixinHttpExecutor.class);
    @Resource(name = "httpClient")
    HttpClient httpClient;
    private static Map<Class,XStream> xStreamMap =new ConcurrentHashMap<Class,XStream>();
    @Override
    public <ExecuteResult extends Object> ExecuteResult post(Object parameter, String url, Class returnClass) {
    XStream requestXStream=getXStream(parameter.getClass());
    String xml=requestXStream.toXML(parameter);
    HttpPost httpPost=new HttpPost(url);
    httpPost.setEntity(new StringEntity(xml,"UTF-8"));
    HttpResponse response=null;
    try{
    response= httpClient.execute(httpPost);
    String responseXml= EntityUtils.toString(response.getEntity(),"UTF-8");
    XStream returnStream=getXStream(returnClass);
    return (ExecuteResult)returnStream.fromXML(responseXml);
    }catch (Throwable throwable){
    LOG.error(url);
    LOG.error(GsonUtils.defaultGson().toJson(parameter));
    LOG.error(throwable.getMessage(),throwable);
    throw new RuntimeException(throwable);
    }
    finally {
    if(null!=response&&null!=response.getEntity()) {
    EntityUtils.consumeQuietly(response.getEntity());
    }
    }
    }
    private final XStream getXStream(Class clazz){
    XStream stream=xStreamMap.get(clazz);
    if(null==stream){
    synchronized (WeixinHttpExecutor.class) {
    if(null==stream) {
    stream= NoNameCoderWithCDataFacotry.Instance().createWithRootXml(clazz);
    if(clazz.getInterfaces().length>0){
    for (Class c:clazz.getInterfaces()) {
    if(c.equals(Converter.class)){
    try {
    stream.registerConverter((Converter) clazz.newInstance());
    }catch (Throwable thrower){
    LOG.error(thrower.getMessage(),thrower);
    throw new RuntimeException(thrower);
    }
    }
    }
    }
    xStreamMap.put(clazz,stream);
    }
    }
    }
    return stream;
    }
    }
     
    public class WxPayCompletedResult extends BaseWeixinResult implements WeixinReturnParameter,ComplexConverter {
    @Override
    public void unmarshal(Map<String, String> xmlNodeValue) {
    if(this.couponCount>0) {
    couponPays = new ArrayList<>(this.couponCount);
    for (int index=0;index<this.couponCount;++index){
    CouponPay pay=new CouponPay();
    pay.couponId=xmlNodeValue.get("coupon_id_"+String.valueOf(index));
    pay.couponFee=Integer.valueOf(xmlNodeValue.get("coupon_fee_"+String.valueOf(index)));
    couponPays.add(index,pay);
    }
    }
    }
    private List<CouponPay> couponPays;
     
    private static Map<String,Field> FIELD_LIST=new HashMap<>();
    static {
    XStreamUtils.loadFields(FIELD_LIST,WxPayCompletedResult.class);
    }
    @Override
    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
     
    }
     
    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    try {
    WxPayCompletedResult result = new WxPayCompletedResult();
    Map<String, String> itemsMap = new HashMap<>();
    if (reader.getNodeName().equalsIgnoreCase("xml")) {
    while (reader.hasMoreChildren()) {
    reader.moveDown();
    String nodeName = reader.getNodeName().trim();
    Field field;
    if (FIELD_LIST.containsKey(nodeName)) {
    field = FIELD_LIST.get(nodeName);
    if (field.getType().equals(String.class)) {
    field.set(result, reader.getValue());
    } else if (field.getType().equals(int.class)||field.getType().equals(Integer.class)) {
    field.set(result, Integer.valueOf(reader.getValue()).intValue());
    }
    }
    itemsMap.put(nodeName, reader.getValue());
    reader.moveUp();
    }
    }
    result.unmarshal(Collections.unmodifiableMap(itemsMap));
    return result;
    }catch (Throwable throwable){
    throw new RuntimeException(throwable);
    }
    }
     
     
    @Override
    public boolean canConvert(Class type) {
    return type.equals(WxPayCompletedResult.class);
    }
    }
     
    /**
    * 复杂XML解析接口,实现者可以从映射中查找相应的VALUE,并自行构建复杂对象..
    * 以适应微信支付结果复杂对象,形如下面例子...
    * @see <a herf="https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_10&index=11">微信代扣订单查询</a>
    * Created by wangtingwei on 2018/1/25.
    */
    public interface ComplexConverter extends Converter{
     
    void unmarshal(Map<String,String> xmlNodeValue);
    }
    
    
  • 相关阅读:
    客户细分那点事_实践1
    和各种人去交流_好玩的事
    客户细分那点事_理论篇
    模型持久化
    天赋是积累出来的——转载自周鸿祎博客
    Pytorch——torch.nn.Sequential()详解
    第2章 Python序列
    Pytorch将数据打包
    线性回归的从零开始实现
    plt.scatter 各参数详解
  • 原文地址:https://www.cnblogs.com/hhbk/p/8377254.html
Copyright © 2020-2023  润新知