优化了xml消息包含$n节点的序列化操作

This commit is contained in:
jinyu 2015-06-13 22:39:45 +08:00
parent 4f52c5e08b
commit 5ffc7f2a98
4 changed files with 82 additions and 88 deletions

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.mp.payment.conver; package com.foxinmy.weixin4j.xml;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
@ -24,11 +24,8 @@ import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo;
import com.foxinmy.weixin4j.util.ReflectionUtil; import com.foxinmy.weixin4j.util.ReflectionUtil;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.ListWrapper;
import com.foxinmy.weixin4j.xml.XmlStream;
/** /**
* 后缀为_$n xml节点反序列化 * 后缀为_$n xml节点反序列化
@ -47,46 +44,53 @@ public class ListsuffixResultDeserializer {
.compile("_\\d{1,}_\\d{1,}$"); .compile("_\\d{1,}_\\d{1,}$");
/** /**
* 对包含 coupon_id_$n 节点的转换 如V3订单查询接口 * 对包含$n节点的xml序列化
* *
* @param content * @param content
* xml内容
* @param clazz * @param clazz
* @param listPropertyName
* 转换为list的属性名称
* @return * @return
*/ */
public static <T> T containCouponDeserialize(String content, Class<T> clazz) { public static <T> T deserialize(String content, Class<T> clazz,
return deserialize(content, clazz, "couponList"); String listPropertyName) {
}
/**
* 对包含 refund_id_$n 节点的转换 如V2退款查询接口
*
* @param content
* @param clazz
* @return
*/
public static <T> T containRefundDeserialize(String content, Class<T> clazz) {
return deserialize(content, clazz, "refundList");
}
/**
* 对同时包含 refund_id_$n coupon_refund_id_$n_$m 节点的转换 如V3退款查询接口
*
* @param content
* @param clazz
* @return
*/
public static <T> T containRefundDetailDeserialize(String content,
Class<T> clazz) {
T t = XmlStream.fromXML(content, clazz); T t = XmlStream.fromXML(content, clazz);
Class<?> wrapperClazz = ReflectionUtil.getFieldGenericType(t, Class<?> wrapperClazz = ReflectionUtil.getFieldGenericType(t,
"refundList"); listPropertyName);
ListWrapper<?> listWrapper = deserializeToListWrapper(content,
wrapperClazz);
if (listWrapper != null) {
ReflectionUtil.invokeSetterMethod(t, listPropertyName,
listWrapper.getItems(), List.class);
}
return t;
}
/**
* 对同时包含$n和$n_$m的xml序列化 refund_id_$n coupon_refund_id_$n_$m V3退款查询接口
*
* @param content
* xml内容
* @param clazz
* @param mainlistPropertyName
* $n结尾转换为list的属性名称
* @param subListPropertyName
* $n_$m结尾转换为list的熟悉名称
* @return
*/
public static <T> T deserializeHasTwoSuffix(String content, Class<T> clazz,
String mainlistPropertyName, String subListPropertyName) {
T t = XmlStream.fromXML(content, clazz);
Class<?> wrapperClazz = ReflectionUtil.getFieldGenericType(t,
mainlistPropertyName);
XMLStreamReader xr = null; XMLStreamReader xr = null;
try { try {
xr = XMLInputFactory.newInstance().createXMLStreamReader( xr = XMLInputFactory.newInstance().createXMLStreamReader(
new StringReader(content)); new StringReader(content));
Matcher matcher = null; Matcher matcher = null;
Map<String, Map<String, String>> refundMap = new HashMap<String, Map<String, String>>(); Map<String, Map<String, String>> mainMap = new HashMap<String, Map<String, String>>();
Map<String, StringBuilder> couponMap = new HashMap<String, StringBuilder>(); Map<String, StringBuilder> subMap = new HashMap<String, StringBuilder>();
while (true) { while (true) {
int event = xr.next(); int event = xr.next();
if (event == XMLStreamConstants.END_DOCUMENT) { if (event == XMLStreamConstants.END_DOCUMENT) {
@ -107,9 +111,9 @@ public class ListsuffixResultDeserializer {
key = matcher.group().replaceFirst( key = matcher.group().replaceFirst(
SUFFIX_PATTERN.pattern(), ""); SUFFIX_PATTERN.pattern(), "");
StringBuilder sb = null; StringBuilder sb = null;
if ((sb = couponMap.get(key)) == null) { if ((sb = subMap.get(key)) == null) {
sb = new StringBuilder(); sb = new StringBuilder();
couponMap.put(key, sb); subMap.put(key, sb);
} }
String reverserName = new StringBuffer( String reverserName = new StringBuffer(
new StringBuilder(name) new StringBuilder(name)
@ -124,9 +128,9 @@ public class ListsuffixResultDeserializer {
.append(">"); .append(">");
} else { } else {
Map<String, String> innerMap = null; Map<String, String> innerMap = null;
if ((innerMap = refundMap.get(key)) == null) { if ((innerMap = mainMap.get(key)) == null) {
innerMap = new HashMap<String, String>(); innerMap = new HashMap<String, String>();
refundMap.put(key, innerMap); mainMap.put(key, innerMap);
} }
innerMap.put(name.replace(key, ""), innerMap.put(name.replace(key, ""),
xr.getText()); xr.getText());
@ -136,7 +140,7 @@ public class ListsuffixResultDeserializer {
} }
} }
} }
if (!refundMap.isEmpty()) { if (!mainMap.isEmpty()) {
String itemName = StringUtil.uncapitalize(wrapperClazz String itemName = StringUtil.uncapitalize(wrapperClazz
.getSimpleName()); .getSimpleName());
XmlRootElement rootElement = wrapperClazz XmlRootElement rootElement = wrapperClazz
@ -153,18 +157,18 @@ public class ListsuffixResultDeserializer {
; ;
} }
} }
List<Object> refundList = new ArrayList<Object>(); List<Object> mainList = new ArrayList<Object>();
StringBuilder xmlBuilder = new StringBuilder(); StringBuilder xmlBuilder = new StringBuilder();
for (Iterator<Entry<String, Map<String, String>>> refundIt = refundMap for (Iterator<Entry<String, Map<String, String>>> refundIt = mainMap
.entrySet().iterator(); refundIt.hasNext();) { .entrySet().iterator(); refundIt.hasNext();) {
xmlBuilder.delete(0, xmlBuilder.length()); xmlBuilder.delete(0, xmlBuilder.length());
xmlBuilder.append("<").append(itemName).append(">"); xmlBuilder.append("<").append(itemName).append(">");
Entry<String, Map<String, String>> refundEntry = refundIt Entry<String, Map<String, String>> mainEntry = refundIt
.next(); .next();
for (Iterator<Entry<String, String>> refundInnerIt = refundEntry for (Iterator<Entry<String, String>> mainInnerIt = mainEntry
.getValue().entrySet().iterator(); refundInnerIt .getValue().entrySet().iterator(); mainInnerIt
.hasNext();) { .hasNext();) {
Entry<String, String> entry = refundInnerIt.next(); Entry<String, String> entry = mainInnerIt.next();
xmlBuilder.append("<").append(entry.getKey()) xmlBuilder.append("<").append(entry.getKey())
.append(">"); .append(">");
xmlBuilder.append(entry.getValue()); xmlBuilder.append(entry.getValue());
@ -172,24 +176,25 @@ public class ListsuffixResultDeserializer {
.append(">"); .append(">");
} }
xmlBuilder.append("</").append(itemName).append(">"); xmlBuilder.append("</").append(itemName).append(">");
Object refund = XmlStream.fromXML(xmlBuilder.toString(), Object main = XmlStream.fromXML(xmlBuilder.toString(),
wrapperClazz); wrapperClazz);
StringBuilder couponXml = couponMap.get(refundEntry StringBuilder subXml = subMap.get(mainEntry.getKey());
.getKey()); if (subXml != null) {
if (couponXml != null) { ListWrapper<?> listWrapper = deserializeToListWrapper(
ListWrapper<?> listWrapper = toListWrapper(
String.format("<xml>%s</xml>", String.format("<xml>%s</xml>",
couponXml.toString()), CouponInfo.class); subXml.toString()),
ReflectionUtil.getFieldGenericType(main,
subListPropertyName));
if (listWrapper != null) { if (listWrapper != null) {
ReflectionUtil.invokeSetterMethod(refund, ReflectionUtil.invokeSetterMethod(main,
"couponList", listWrapper.getItems(), subListPropertyName,
List.class); listWrapper.getItems(), List.class);
} }
} }
refundList.add(refund); mainList.add(main);
} }
ReflectionUtil.invokeSetterMethod(t, "refundList", refundList, ReflectionUtil.invokeSetterMethod(t, mainlistPropertyName,
List.class); mainList, List.class);
} }
} catch (XMLStreamException e) { } catch (XMLStreamException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
@ -205,21 +210,8 @@ public class ListsuffixResultDeserializer {
return t; return t;
} }
public static <T> T deserialize(String content, Class<T> clazz,
String listPropertyName) {
T t = XmlStream.fromXML(content, clazz);
Class<?> wrapperClazz = ReflectionUtil.getFieldGenericType(t,
listPropertyName);
ListWrapper<?> listWrapper = toListWrapper(content, wrapperClazz);
if (listWrapper != null) {
ReflectionUtil.invokeSetterMethod(t, listPropertyName,
listWrapper.getItems(), List.class);
}
return t;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> ListWrapper<T> toListWrapper(String content, public static <T> ListWrapper<T> deserializeToListWrapper(String content,
Class<T> clazz) { Class<T> clazz) {
XMLStreamReader xr = null; XMLStreamReader xr = null;
XMLStreamWriter xw = null; XMLStreamWriter xw = null;

View File

@ -34,7 +34,6 @@ import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.mp.payment.v2.Order; import com.foxinmy.weixin4j.mp.payment.v2.Order;
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord; import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord;
import com.foxinmy.weixin4j.mp.payment.v2.RefundResult; import com.foxinmy.weixin4j.mp.payment.v2.RefundResult;
@ -49,6 +48,7 @@ import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
import com.foxinmy.weixin4j.util.MapUtil; import com.foxinmy.weixin4j.util.MapUtil;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
/** /**
* V2支付API * V2支付API
@ -442,8 +442,8 @@ public class Pay2Api extends PayApi {
String sign = PayUtil.paysignMd5(map, weixinAccount.getPartnerKey()); String sign = PayUtil.paysignMd5(map, weixinAccount.getPartnerKey());
map.put("sign", sign.toLowerCase()); map.put("sign", sign.toLowerCase());
WeixinResponse response = weixinClient.get(refundquery_uri, map); WeixinResponse response = weixinClient.get(refundquery_uri, map);
return ListsuffixResultDeserializer.containRefundDeserialize( return ListsuffixResultDeserializer.deserialize(response.getAsString(),
response.getAsString(), RefundRecord.class); RefundRecord.class, "refundList");
} }
@Override @Override

View File

@ -25,7 +25,6 @@ import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult; import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.payment.v3.Order; import com.foxinmy.weixin4j.mp.payment.v3.Order;
import com.foxinmy.weixin4j.mp.payment.v3.RefundRecord; import com.foxinmy.weixin4j.mp.payment.v3.RefundRecord;
@ -39,6 +38,7 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.xml.XmlStream; import com.foxinmy.weixin4j.xml.XmlStream;
/** /**
@ -80,8 +80,8 @@ public class Pay3Api extends PayApi {
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
String orderquery_uri = getRequestUri("orderquery_v3_uri"); String orderquery_uri = getRequestUri("orderquery_v3_uri");
WeixinResponse response = weixinClient.post(orderquery_uri, param); WeixinResponse response = weixinClient.post(orderquery_uri, param);
return ListsuffixResultDeserializer.containCouponDeserialize( return ListsuffixResultDeserializer.deserialize(response.getAsString(),
response.getAsString(), Order.class); Order.class, "couponList");
} }
/** /**
@ -394,8 +394,9 @@ public class Pay3Api extends PayApi {
map.put("sign", sign); map.put("sign", sign);
String param = XmlStream.map2xml(map); String param = XmlStream.map2xml(map);
WeixinResponse response = weixinClient.post(refundquery_uri, param); WeixinResponse response = weixinClient.post(refundquery_uri, param);
return ListsuffixResultDeserializer.containRefundDetailDeserialize( return ListsuffixResultDeserializer.deserializeHasTwoSuffix(
response.getAsString(), RefundRecord.class); response.getAsString(), RefundRecord.class, "refundList",
"couponList");
} }
/** /**

View File

@ -7,9 +7,9 @@ import java.util.Map;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord; import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord;
import com.foxinmy.weixin4j.mp.payment.v3.Order; import com.foxinmy.weixin4j.mp.payment.v3.Order;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.xml.ListsuffixResultSerializer; import com.foxinmy.weixin4j.xml.ListsuffixResultSerializer;
import com.foxinmy.weixin4j.xml.XmlStream; import com.foxinmy.weixin4j.xml.XmlStream;
@ -62,8 +62,8 @@ public class XmlstreamTest {
} catch (Exception e) { } catch (Exception e) {
} }
System.err.println(ListsuffixResultDeserializer System.err.println(ListsuffixResultDeserializer.deserialize(
.containCouponDeserialize(sb.toString(), Order.class)); sb.toString(), Order.class, "couponList"));
} }
public static RefundRecord xml2refundRecordV2() throws Exception { public static RefundRecord xml2refundRecordV2() throws Exception {
@ -79,8 +79,8 @@ public class XmlstreamTest {
} catch (Exception e) { } catch (Exception e) {
} }
return ListsuffixResultDeserializer.containRefundDeserialize( return ListsuffixResultDeserializer.deserialize(sb.toString(),
sb.toString(), RefundRecord.class); RefundRecord.class, "refundList");
} }
public static void xml2refundRecordV3() throws Exception { public static void xml2refundRecordV3() throws Exception {
@ -97,8 +97,9 @@ public class XmlstreamTest {
} }
System.err.println(ListsuffixResultDeserializer System.err.println(ListsuffixResultDeserializer
.containRefundDetailDeserialize(sb.toString(), .deserializeHasTwoSuffix(sb.toString(),
com.foxinmy.weixin4j.mp.payment.v3.RefundRecord.class)); com.foxinmy.weixin4j.mp.payment.v3.RefundRecord.class,
"refundList", "couponList"));
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -106,15 +107,15 @@ public class XmlstreamTest {
// xml2map(); // xml2map();
// xml2order(); // xml2order();
// xml2refundRecordV2(); // xml2refundRecordV2();
// xml2refundRecordV3(); xml2refundRecordV3();
// object2xmlWithoutRootElement(); // object2xmlWithoutRootElement();
RefundRecord refundRecord = xml2refundRecordV2(); RefundRecord refundRecord = xml2refundRecordV2();
System.err.println(refundRecord); System.err.println(refundRecord);
String sign = refundRecord.getSign(); String sign = refundRecord.getSign();
refundRecord.setSign(null); refundRecord.setSign(null);
String validSign = PayUtil.paysignMd5(refundRecord, String validSign = PayUtil.paysignMd5(refundRecord, "paysignkey");
"paysignkey");
System.err.println("sign=" + sign + ",validSign=" + validSign); System.err.println("sign=" + sign + ",validSign=" + validSign);
System.err.println(ListsuffixResultSerializer.serializeToXML(refundRecord)); System.err.println(ListsuffixResultSerializer
.serializeToXML(refundRecord));
} }
} }