3 changed files with 116 additions and 84 deletions
@ -0,0 +1,111 @@ |
|||||
|
package com.gxwebsoft.common.core.utils; |
||||
|
|
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
/** |
||||
|
* 微信支付工具类 |
||||
|
* 处理微信支付API的字段限制和格式要求 |
||||
|
* |
||||
|
* @author 科技小王子 |
||||
|
* @since 2025-01-11 |
||||
|
*/ |
||||
|
public class WechatPayUtils { |
||||
|
|
||||
|
/** |
||||
|
* 微信支付description字段的最大字节数限制 |
||||
|
*/ |
||||
|
public static final int DESCRIPTION_MAX_BYTES = 127; |
||||
|
|
||||
|
/** |
||||
|
* 微信支付attach字段的最大字节数限制 |
||||
|
*/ |
||||
|
public static final int ATTACH_MAX_BYTES = 127; |
||||
|
|
||||
|
/** |
||||
|
* 截断字符串以确保字节数不超过指定限制 |
||||
|
* 主要用于微信支付API的字段限制处理 |
||||
|
* |
||||
|
* @param text 原始文本 |
||||
|
* @param maxBytes 最大字节数 |
||||
|
* @return 截断后的文本,确保UTF-8字符完整性 |
||||
|
*/ |
||||
|
public static String truncateToByteLimit(String text, int maxBytes) { |
||||
|
if (text == null || text.isEmpty()) { |
||||
|
return text; |
||||
|
} |
||||
|
|
||||
|
byte[] bytes = text.getBytes(StandardCharsets.UTF_8); |
||||
|
if (bytes.length <= maxBytes) { |
||||
|
return text; |
||||
|
} |
||||
|
|
||||
|
// 截断字节数组,但要确保不会截断UTF-8字符的中间
|
||||
|
int truncateLength = maxBytes; |
||||
|
while (truncateLength > 0) { |
||||
|
byte[] truncated = new byte[truncateLength]; |
||||
|
System.arraycopy(bytes, 0, truncated, 0, truncateLength); |
||||
|
|
||||
|
try { |
||||
|
String result = new String(truncated, StandardCharsets.UTF_8); |
||||
|
// 检查是否有无效字符(被截断的UTF-8字符)
|
||||
|
if (!result.contains("\uFFFD")) { |
||||
|
return result; |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
// 继续尝试更短的长度
|
||||
|
} |
||||
|
truncateLength--; |
||||
|
} |
||||
|
|
||||
|
return ""; // 如果无法安全截断,返回空字符串
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理微信支付商品描述字段 |
||||
|
* 确保字节数不超过127字节 |
||||
|
* |
||||
|
* @param description 商品描述 |
||||
|
* @return 处理后的描述,符合微信支付要求 |
||||
|
*/ |
||||
|
public static String processDescription(String description) { |
||||
|
return truncateToByteLimit(description, DESCRIPTION_MAX_BYTES); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理微信支付附加数据字段 |
||||
|
* 确保字节数不超过127字节 |
||||
|
* |
||||
|
* @param attach 附加数据 |
||||
|
* @return 处理后的附加数据,符合微信支付要求 |
||||
|
*/ |
||||
|
public static String processAttach(String attach) { |
||||
|
return truncateToByteLimit(attach, ATTACH_MAX_BYTES); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证字符串是否符合微信支付字段的字节限制 |
||||
|
* |
||||
|
* @param text 待验证的文本 |
||||
|
* @param maxBytes 最大字节数限制 |
||||
|
* @return true如果符合限制,false如果超出限制 |
||||
|
*/ |
||||
|
public static boolean isWithinByteLimit(String text, int maxBytes) { |
||||
|
if (text == null) { |
||||
|
return true; |
||||
|
} |
||||
|
return text.getBytes(StandardCharsets.UTF_8).length <= maxBytes; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取字符串的UTF-8字节数 |
||||
|
* |
||||
|
* @param text 文本 |
||||
|
* @return 字节数 |
||||
|
*/ |
||||
|
public static int getByteLength(String text) { |
||||
|
if (text == null) { |
||||
|
return 0; |
||||
|
} |
||||
|
return text.getBytes(StandardCharsets.UTF_8).length; |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue