javacodeadmin/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayUtil.java

787 lines
31 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.system.ControllerUtil;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 微信支付工具类
*
* 提供微信支付相关的完整功能实现
* 主要功能:
* 1. 统一下单支付
* 2. 订单状态查询
* 3. 找朋友代付功能
* 4. 支付结果回调处理
* 5. 退款申请和查询
* 6. 签名生成和验证
* 7. 支付安全验证
*
* @author Mr. Zhang Pan
* @date 2025-01-03
* @version 1.0
*/
public class WechatPayUtil {
/**
* 微信支付配置常量
* 注意:实际使用时需要在配置文件中配置这些值
*/
private static final String WECHAT_APP_ID = "your_wechat_appid";
private static final String WECHAT_MCH_ID = "your_merchant_id";
private static final String WECHAT_API_KEY = "your_api_key";
private static final String WECHAT_CERT_PATH = "/path/to/cert.p12"; // 微信支付证书路径
/**
* 微信支付API地址
*/
private static final String WECHAT_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
private static final String WECHAT_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
private static final String WECHAT_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
/**
* 其他配置常量
*/
private static final String TRADE_TYPE_JSAPI = "JSAPI";
private static final String CURRENCY = "CNY"; // 货币类型
private static final String SUCCESS_CODE = "SUCCESS";
private static final String FAIL_CODE = "FAIL";
/**
* RestTemplate实例
*/
private static final RestTemplate restTemplate = new RestTemplate();
/**
* 统一下单 - 微信小程序支付
*
* @param orderInfo 订单信息
* @return 支付参数Map
*/
public static Map<String, Object> unifiedOrder(Map<String, Object> orderInfo) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 参数验证
String validationError = validateOrderParams(orderInfo);
if (validationError != null) {
result.put("success", false);
result.put("message", validationError);
return result;
}
// 2. 构建统一下单参数
Map<String, String> params = buildUnifiedOrderParams(orderInfo);
// 3. 生成签名
String sign = generateSign(params, WECHAT_API_KEY);
params.put("sign", sign);
// 4. 发送请求
String xmlRequest = mapToXml(params);
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_PAY_URL, xmlRequest, String.class);
// 5. 解析响应
Map<String, String> responseMap = xmlToMap(response.getBody());
if (SUCCESS_CODE.equals(responseMap.get("return_code")) &&
SUCCESS_CODE.equals(responseMap.get("result_code"))) {
// 6. 构建小程序支付参数
Map<String, Object> payParams = buildMiniProgramPayParams(responseMap.get("prepay_id"));
result.put("success", true);
result.put("payParams", payParams);
result.put("prepayId", responseMap.get("prepay_id"));
result.put("message", "统一下单成功");
} else {
result.put("success", false);
result.put("message", "统一下单失败:" +
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
responseMap.get("return_msg")));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "统一下单异常:" + e.getMessage());
}
return result;
}
/**
* 查询订单状态
*
* @param orderNo 订单号
* @param transactionId 微信订单号可选与orderNo二选一
* @return 查询结果
*/
public static Map<String, Object> queryOrder(String orderNo, String transactionId) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 参数验证
if ((orderNo == null || orderNo.trim().isEmpty()) &&
(transactionId == null || transactionId.trim().isEmpty())) {
result.put("success", false);
result.put("message", "订单号和微信订单号不能同时为空");
return result;
}
// 2. 构建查询参数
Map<String, String> params = new HashMap<>();
params.put("appid", WECHAT_APP_ID);
params.put("mch_id", WECHAT_MCH_ID);
params.put("nonce_str", generateNonceStr());
if (orderNo != null && !orderNo.trim().isEmpty()) {
params.put("out_trade_no", orderNo.trim());
}
if (transactionId != null && !transactionId.trim().isEmpty()) {
params.put("transaction_id", transactionId.trim());
}
// 3. 生成签名
String sign = generateSign(params, WECHAT_API_KEY);
params.put("sign", sign);
// 4. 发送请求
String xmlRequest = mapToXml(params);
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_QUERY_URL, xmlRequest, String.class);
// 5. 解析响应
Map<String, String> responseMap = xmlToMap(response.getBody());
if (SUCCESS_CODE.equals(responseMap.get("return_code")) &&
SUCCESS_CODE.equals(responseMap.get("result_code"))) {
Map<String, Object> orderInfo = new HashMap<>();
orderInfo.put("tradeState", responseMap.get("trade_state"));
orderInfo.put("tradeStateDesc", responseMap.get("trade_state_desc"));
orderInfo.put("transactionId", responseMap.get("transaction_id"));
orderInfo.put("outTradeNo", responseMap.get("out_trade_no"));
orderInfo.put("totalFee", responseMap.get("total_fee"));
orderInfo.put("cashFee", responseMap.get("cash_fee"));
orderInfo.put("timeEnd", responseMap.get("time_end"));
result.put("success", true);
result.put("orderInfo", orderInfo);
result.put("message", "查询订单成功");
} else {
result.put("success", false);
result.put("message", "查询订单失败:" +
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
responseMap.get("return_msg")));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "查询订单异常:" + e.getMessage());
}
return result;
}
/**
* 找朋友代付功能 - 生成代付订单
*
* @param payForInfo 代付信息
* @return 代付订单结果
*/
public static Map<String, Object> createPayForOrder(Map<String, Object> payForInfo) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 参数验证
String validationError = validatePayForParams(payForInfo);
if (validationError != null) {
result.put("success", false);
result.put("message", validationError);
return result;
}
// 2. 生成代付订单号
String payForOrderNo = generatePayForOrderNo((String) payForInfo.get("orderNo"));
// 3. 构建代付订单信息
Map<String, Object> payForOrderInfo = new HashMap<>();
payForOrderInfo.put("orderNo", payForOrderNo);
payForOrderInfo.put("openid", payForInfo.get("payerOpenid"));
payForOrderInfo.put("totalFee", payForInfo.get("totalFee"));
payForOrderInfo.put("body", "代付-" + payForInfo.get("body"));
payForOrderInfo.put("notifyUrl", payForInfo.get("notifyUrl"));
payForOrderInfo.put("attach", buildPayForAttach(payForInfo));
// 4. 设置30分钟过期时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 30);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
payForOrderInfo.put("timeExpire", sdf.format(calendar.getTime()));
// 5. 调用统一下单
Map<String, Object> unifiedResult = unifiedOrder(payForOrderInfo);
if ((Boolean) unifiedResult.get("success")) {
result.put("success", true);
result.put("payForOrderNo", payForOrderNo);
result.put("payParams", unifiedResult.get("payParams"));
result.put("prepayId", unifiedResult.get("prepayId"));
result.put("expireTime", payForOrderInfo.get("timeExpire"));
result.put("message", "代付订单创建成功");
} else {
result.put("success", false);
result.put("message", "代付订单创建失败:" + unifiedResult.get("message"));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "创建代付订单异常:" + e.getMessage());
}
return result;
}
/**
* 支付结果通知回调处理
*
* @param request HTTP请求对象
* @return 处理结果
*/
public static Map<String, Object> handlePayNotify(HttpServletRequest request) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 读取请求数据
StringBuilder xmlData = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = reader.readLine()) != null) {
xmlData.append(line);
}
reader.close();
// 2. 解析XML数据
Map<String, String> notifyData = xmlToMap(xmlData.toString());
// 3. 验证签名
if (!verifySign(notifyData, WECHAT_API_KEY)) {
result.put("success", false);
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "签名验证失败"));
result.put("message", "签名验证失败");
return result;
}
// 4. 检查支付结果
if (!SUCCESS_CODE.equals(notifyData.get("return_code")) ||
!SUCCESS_CODE.equals(notifyData.get("result_code"))) {
result.put("success", false);
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "支付失败"));
result.put("message", "支付失败:" + notifyData.get("err_code_des"));
return result;
}
// 5. 构建支付信息
Map<String, Object> paymentInfo = new HashMap<>();
paymentInfo.put("transactionId", notifyData.get("transaction_id"));
paymentInfo.put("outTradeNo", notifyData.get("out_trade_no"));
paymentInfo.put("totalFee", notifyData.get("total_fee"));
paymentInfo.put("cashFee", notifyData.get("cash_fee"));
paymentInfo.put("timeEnd", notifyData.get("time_end"));
paymentInfo.put("attach", notifyData.get("attach"));
paymentInfo.put("openid", notifyData.get("openid"));
// 6. 判断是否为代付订单
String orderNo = notifyData.get("out_trade_no");
boolean isPayFor = isPayForOrder(orderNo);
result.put("success", true);
result.put("responseXml", buildNotifyResponse(SUCCESS_CODE, "OK"));
result.put("paymentInfo", paymentInfo);
result.put("isPayFor", isPayFor);
result.put("message", "支付通知处理成功");
} catch (Exception e) {
result.put("success", false);
result.put("responseXml", buildNotifyResponse(FAIL_CODE, "处理异常"));
result.put("message", "处理支付通知异常:" + e.getMessage());
}
return result;
}
/**
* 申请退款
*
* @param refundInfo 退款信息
* @return 退款结果
*/
public static Map<String, Object> refund(Map<String, Object> refundInfo) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 参数验证
String validationError = validateRefundParams(refundInfo);
if (validationError != null) {
result.put("success", false);
result.put("message", validationError);
return result;
}
// 2. 构建退款参数
Map<String, String> params = buildRefundParams(refundInfo);
// 3. 生成签名
String sign = generateSign(params, WECHAT_API_KEY);
params.put("sign", sign);
// 4. 发送请求(需要证书)
String xmlRequest = mapToXml(params);
// 注意:退款接口需要使用客户端证书,这里简化处理
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_REFUND_URL, xmlRequest, String.class);
// 5. 解析响应
Map<String, String> responseMap = xmlToMap(response.getBody());
if (SUCCESS_CODE.equals(responseMap.get("return_code")) &&
SUCCESS_CODE.equals(responseMap.get("result_code"))) {
Map<String, Object> refundResult = new HashMap<>();
refundResult.put("refundId", responseMap.get("refund_id"));
refundResult.put("outRefundNo", responseMap.get("out_refund_no"));
refundResult.put("refundFee", responseMap.get("refund_fee"));
refundResult.put("settlementRefundFee", responseMap.get("settlement_refund_fee"));
result.put("success", true);
result.put("refundInfo", refundResult);
result.put("message", "申请退款成功");
} else {
result.put("success", false);
result.put("message", "申请退款失败:" +
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
responseMap.get("return_msg")));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "申请退款异常:" + e.getMessage());
}
return result;
}
/**
* 企业付款到零钱(用于代付完成后的资金转移)
*
* @param transferInfo 付款信息
* @return 付款结果
*/
public static Map<String, Object> transferToUser(Map<String, Object> transferInfo) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 参数验证
String validationError = validateTransferParams(transferInfo);
if (validationError != null) {
result.put("success", false);
result.put("message", validationError);
return result;
}
// 2. 构建付款参数
Map<String, String> params = buildTransferParams(transferInfo);
// 3. 生成签名
String sign = generateSign(params, WECHAT_API_KEY);
params.put("sign", sign);
// 4. 发送请求(需要证书)
String xmlRequest = mapToXml(params);
// 注意:企业付款接口需要使用客户端证书,这里简化处理
ResponseEntity<String> response = restTemplate.postForEntity(WECHAT_TRANSFER_URL, xmlRequest, String.class);
// 5. 解析响应
Map<String, String> responseMap = xmlToMap(response.getBody());
if (SUCCESS_CODE.equals(responseMap.get("return_code")) &&
SUCCESS_CODE.equals(responseMap.get("result_code"))) {
Map<String, Object> transferResult = new HashMap<>();
transferResult.put("partnerTradeNo", responseMap.get("partner_trade_no"));
transferResult.put("paymentNo", responseMap.get("payment_no"));
transferResult.put("paymentTime", responseMap.get("payment_time"));
result.put("success", true);
result.put("transferInfo", transferResult);
result.put("message", "企业付款成功");
} else {
result.put("success", false);
result.put("message", "企业付款失败:" +
(responseMap.get("err_code_des") != null ? responseMap.get("err_code_des") :
responseMap.get("return_msg")));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "企业付款异常:" + e.getMessage());
}
return result;
}
// ========== 私有工具方法 ==========
/**
* 验证统一下单参数
*/
private static String validateOrderParams(Map<String, Object> orderInfo) {
if (orderInfo == null) return "订单信息不能为空";
if (orderInfo.get("orderNo") == null || orderInfo.get("orderNo").toString().trim().isEmpty()) {
return "订单号不能为空";
}
if (orderInfo.get("openid") == null || orderInfo.get("openid").toString().trim().isEmpty()) {
return "用户openid不能为空";
}
if (orderInfo.get("totalFee") == null) {
return "支付金额不能为空";
}
if (orderInfo.get("body") == null || orderInfo.get("body").toString().trim().isEmpty()) {
return "商品描述不能为空";
}
if (orderInfo.get("notifyUrl") == null || orderInfo.get("notifyUrl").toString().trim().isEmpty()) {
return "回调地址不能为空";
}
return null;
}
/**
* 验证代付参数
*/
private static String validatePayForParams(Map<String, Object> payForInfo) {
if (payForInfo == null) return "代付信息不能为空";
if (payForInfo.get("orderNo") == null || payForInfo.get("orderNo").toString().trim().isEmpty()) {
return "原订单号不能为空";
}
if (payForInfo.get("payerOpenid") == null || payForInfo.get("payerOpenid").toString().trim().isEmpty()) {
return "代付人openid不能为空";
}
if (payForInfo.get("payeeOpenid") == null || payForInfo.get("payeeOpenid").toString().trim().isEmpty()) {
return "被代付人openid不能为空";
}
if (payForInfo.get("totalFee") == null) {
return "代付金额不能为空";
}
if (payForInfo.get("body") == null || payForInfo.get("body").toString().trim().isEmpty()) {
return "商品描述不能为空";
}
if (payForInfo.get("notifyUrl") == null || payForInfo.get("notifyUrl").toString().trim().isEmpty()) {
return "回调地址不能为空";
}
return null;
}
/**
* 验证退款参数
*/
private static String validateRefundParams(Map<String, Object> refundInfo) {
if (refundInfo == null) return "退款信息不能为空";
if (refundInfo.get("orderNo") == null || refundInfo.get("orderNo").toString().trim().isEmpty()) {
return "订单号不能为空";
}
if (refundInfo.get("refundNo") == null || refundInfo.get("refundNo").toString().trim().isEmpty()) {
return "退款单号不能为空";
}
if (refundInfo.get("totalFee") == null) {
return "订单总金额不能为空";
}
if (refundInfo.get("refundFee") == null) {
return "退款金额不能为空";
}
return null;
}
/**
* 验证企业付款参数
*/
private static String validateTransferParams(Map<String, Object> transferInfo) {
if (transferInfo == null) return "付款信息不能为空";
if (transferInfo.get("partnerTradeNo") == null || transferInfo.get("partnerTradeNo").toString().trim().isEmpty()) {
return "商户订单号不能为空";
}
if (transferInfo.get("openid") == null || transferInfo.get("openid").toString().trim().isEmpty()) {
return "用户openid不能为空";
}
if (transferInfo.get("amount") == null) {
return "付款金额不能为空";
}
if (transferInfo.get("desc") == null || transferInfo.get("desc").toString().trim().isEmpty()) {
return "付款描述不能为空";
}
return null;
}
/**
* 构建统一下单参数
*/
private static Map<String, String> buildUnifiedOrderParams(Map<String, Object> orderInfo) {
Map<String, String> params = new HashMap<>();
params.put("appid", WECHAT_APP_ID);
params.put("mch_id", WECHAT_MCH_ID);
params.put("nonce_str", generateNonceStr());
params.put("body", orderInfo.get("body").toString());
params.put("out_trade_no", orderInfo.get("orderNo").toString());
params.put("total_fee", orderInfo.get("totalFee").toString());
params.put("spbill_create_ip", "127.0.0.1");
params.put("notify_url", orderInfo.get("notifyUrl").toString());
params.put("trade_type", TRADE_TYPE_JSAPI);
params.put("openid", orderInfo.get("openid").toString());
if (orderInfo.get("attach") != null) {
params.put("attach", orderInfo.get("attach").toString());
}
if (orderInfo.get("timeExpire") != null) {
params.put("time_expire", orderInfo.get("timeExpire").toString());
}
return params;
}
/**
* 构建退款参数
*/
private static Map<String, String> buildRefundParams(Map<String, Object> refundInfo) {
Map<String, String> params = new HashMap<>();
params.put("appid", WECHAT_APP_ID);
params.put("mch_id", WECHAT_MCH_ID);
params.put("nonce_str", generateNonceStr());
params.put("out_trade_no", refundInfo.get("orderNo").toString());
params.put("out_refund_no", refundInfo.get("refundNo").toString());
params.put("total_fee", refundInfo.get("totalFee").toString());
params.put("refund_fee", refundInfo.get("refundFee").toString());
if (refundInfo.get("refundDesc") != null) {
params.put("refund_desc", refundInfo.get("refundDesc").toString());
}
if (refundInfo.get("notifyUrl") != null) {
params.put("notify_url", refundInfo.get("notifyUrl").toString());
}
return params;
}
/**
* 构建企业付款参数
*/
private static Map<String, String> buildTransferParams(Map<String, Object> transferInfo) {
Map<String, String> params = new HashMap<>();
params.put("mch_appid", WECHAT_APP_ID);
params.put("mchid", WECHAT_MCH_ID);
params.put("nonce_str", generateNonceStr());
params.put("partner_trade_no", transferInfo.get("partnerTradeNo").toString());
params.put("openid", transferInfo.get("openid").toString());
params.put("check_name", transferInfo.get("checkName") != null ?
transferInfo.get("checkName").toString() : "NO_CHECK");
params.put("amount", transferInfo.get("amount").toString());
params.put("desc", transferInfo.get("desc").toString());
params.put("spbill_create_ip", "127.0.0.1");
if (transferInfo.get("reUserName") != null) {
params.put("re_user_name", transferInfo.get("reUserName").toString());
}
return params;
}
/**
* 构建小程序支付参数
*/
private static Map<String, Object> buildMiniProgramPayParams(String prepayId) {
Map<String, Object> payParams = new HashMap<>();
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonceStr = generateNonceStr();
String packageStr = "prepay_id=" + prepayId;
String signType = "MD5";
// 构建签名参数
Map<String, String> signParams = new HashMap<>();
signParams.put("appId", WECHAT_APP_ID);
signParams.put("timeStamp", timeStamp);
signParams.put("nonceStr", nonceStr);
signParams.put("package", packageStr);
signParams.put("signType", signType);
String paySign = generateSign(signParams, WECHAT_API_KEY);
payParams.put("timeStamp", timeStamp);
payParams.put("nonceStr", nonceStr);
payParams.put("package", packageStr);
payParams.put("signType", signType);
payParams.put("paySign", paySign);
return payParams;
}
/**
* 构建代付附加数据
*/
private static String buildPayForAttach(Map<String, Object> payForInfo) {
JSONObject attach = new JSONObject();
attach.put("type", "payfor");
attach.put("originalOrderNo", payForInfo.get("orderNo"));
attach.put("payerOpenid", payForInfo.get("payerOpenid"));
attach.put("payeeOpenid", payForInfo.get("payeeOpenid"));
if (payForInfo.get("remark") != null) {
attach.put("remark", payForInfo.get("remark"));
}
return attach.toString();
}
/**
* 生成代付订单号
*/
private static String generatePayForOrderNo(String originalOrderNo) {
return "PF" + originalOrderNo + System.currentTimeMillis();
}
/**
* 判断是否为代付订单
*/
private static boolean isPayForOrder(String orderNo) {
return orderNo != null && orderNo.startsWith("PF");
}
/**
* 构建通知响应XML
*/
private static String buildNotifyResponse(String returnCode, String returnMsg) {
StringBuilder xml = new StringBuilder();
xml.append("<xml>");
xml.append("<return_code><![CDATA[").append(returnCode).append("]]></return_code>");
xml.append("<return_msg><![CDATA[").append(returnMsg).append("]]></return_msg>");
xml.append("</xml>");
return xml.toString();
}
/**
* 生成随机字符串
*/
private static String generateNonceStr() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
}
/**
* 生成签名
*/
private static String generateSign(Map<String, String> params, String key) {
try {
// 1. 排序参数
Map<String, String> sortedParams = new TreeMap<>(params);
// 2. 拼接参数
StringBuilder stringBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
if (entry.getValue() != null && !entry.getValue().isEmpty() && !"sign".equals(entry.getKey())) {
stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
stringBuilder.append("key=").append(key);
// 3. MD5加密
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digest = md5.digest(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
// 4. 转换为大写16进制字符串
StringBuilder result = new StringBuilder();
for (byte b : digest) {
result.append(String.format("%02X", b));
}
return result.toString();
} catch (Exception e) {
throw new RuntimeException("生成签名失败", e);
}
}
/**
* 验证签名
*/
private static boolean verifySign(Map<String, String> params, String key) {
String sign = params.get("sign");
if (sign == null || sign.isEmpty()) {
return false;
}
Map<String, String> paramsWithoutSign = new HashMap<>(params);
paramsWithoutSign.remove("sign");
String generatedSign = generateSign(paramsWithoutSign, key);
return sign.equals(generatedSign);
}
/**
* Map转XML
*/
private static String mapToXml(Map<String, String> params) {
StringBuilder xml = new StringBuilder();
xml.append("<xml>");
for (Map.Entry<String, String> entry : params.entrySet()) {
xml.append("<").append(entry.getKey()).append("><![CDATA[")
.append(entry.getValue()).append("]]></").append(entry.getKey()).append(">");
}
xml.append("</xml>");
return xml.toString();
}
/**
* XML转Map简化实现
*/
private static Map<String, String> xmlToMap(String xml) {
Map<String, String> map = new HashMap<>();
try {
// 简化的XML解析实现
xml = xml.replaceAll("<xml>", "").replaceAll("</xml>", "");
String[] elements = xml.split("</\\w+>");
for (String element : elements) {
if (element.trim().isEmpty()) continue;
int startTag = element.indexOf("<");
int endTag = element.indexOf(">");
if (startTag >= 0 && endTag > startTag) {
String key = element.substring(startTag + 1, endTag);
String value = element.substring(endTag + 1);
// 处理CDATA
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
value = value.substring(9, value.length() - 3);
}
map.put(key, value);
}
}
} catch (Exception e) {
throw new RuntimeException("XML解析失败", e);
}
return map;
}
}