This commit is contained in:
lihongbiao 2025-01-20 12:00:11 +08:00
parent 971dcf885c
commit 0a17381dc2
10 changed files with 740 additions and 328 deletions

10
pom.xml
View File

@ -26,6 +26,16 @@
</properties>
<dependencies>
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
<dependency>
<groupId>com.volcengine</groupId>
<artifactId>volc-sdk-java</artifactId>

View File

@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
@ -33,6 +34,7 @@ import java.util.Locale;
* @desc
*/
@Configuration
@ComponentScan(basePackages = "com.wechat.pay.java.service.payments.h5")
public class AppConfiguration extends WebMvcConfigurationSupport {
private static final Logger LOG = LoggerFactory.getLogger(AppConfiguration.class);
@Autowired

View File

@ -0,0 +1,148 @@
package com.pixelai.api.domain.apy;
import com.pixelai.api.pa.entity.PaConsumption;
import com.pixelai.api.pa.entity.PaOrder;
import com.pixelai.api.pa.entity.PaVipCurrency;
import com.pixelai.api.pa.entity.enums.PayState;
import com.pixelai.api.pa.service.PaConsumptionService;
import com.pixelai.api.pa.service.PaOrderService;
import com.pixelai.api.pa.service.PaVipCurrencyService;
import com.pixelai.api.pa.service.PaVipService;
import com.pixelai.config.WeChatConfig;
import com.pixelai.utils.WeChatUtil;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.http.*;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.util.GsonUtil;
import com.wechat.pay.java.service.partnerpayments.h5.model.Transaction;
import com.wechat.pay.java.service.payments.h5.H5Service;
import com.wechat.pay.java.service.payments.h5.model.*;
import eu.bitwalker.useragentutils.UserAgent;
import io.undertow.util.MalformedMessageException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Objects;
@Service
public class OrderPayAppService {
@Autowired
private WeChatConfig weChatConfig;
@Resource
private NotificationParser notificationParser;
@Resource
private H5Service h5Service;
@Resource
private PaOrderService paOrderService;
@Resource
private PaVipCurrencyService paVipCurrencyService;
@Resource
private PaConsumptionService paConsumptionService;
public String h5Pay(PaOrder order,HttpServletRequest request) {
List<String> buyTypes = new ArrayList<>(Arrays.asList("1","2","3","4","5","6"));
if (order.getBuyType()==null||!buyTypes.contains(order.getBuyType())) {
return "购买类型错误";
}
// request.setXxx(val)设置所需参数具体参数可见Request定义
PrepayRequest prepayRequest = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal((order.getAmount().multiply(new BigDecimal("100"))).intValue());
prepayRequest.setAmount(amount);
prepayRequest.setAppid(weChatConfig.getAppId());
prepayRequest.setMchid(weChatConfig.getMerchantId());
prepayRequest.setDescription("钻石购买");
prepayRequest.setNotifyUrl(weChatConfig.getNotifyUrl());
String tradeNo = WeChatUtil.generateTradeNumber();
prepayRequest.setOutTradeNo(tradeNo);
SceneInfo sceneInfo = new SceneInfo();
sceneInfo.setPayerClientIp(weChatConfig.getAddressIp());
H5Info h5Info = new H5Info();
h5Info.setType(UserAgent.parseUserAgentString(request.getHeader("User-Agent")).getOperatingSystem().getName());
sceneInfo.setH5Info(h5Info);
prepayRequest.setSceneInfo(sceneInfo);
// 调用下单方法得到应答
PrepayResponse response;
try {
response = h5Service.prepay(prepayRequest);
//预支付成功创建预支付订单
order.setOrderNum(tradeNo);
order.setPayStatus(PayState.TO_BE_PAID);
order.setCreateTime(new Date());
order.setState("t");
paOrderService.save(order);
return response.getH5Url();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Transactional
public void payNotify(HttpServletRequest request) throws Exception{
Transaction transaction;
try {
transaction = notificationParser.parse(WeChatUtil.handleNodifyRequestParam(request), Transaction.class);
if (transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
PaOrder order = paOrderService.getOrderByTradeNo(transaction.getOutTradeNo());
if (Objects.isNull(order)) {
return;
}
//校验订单状态若订单已支付则直接返回成功
if (Objects.equals(order.getPayStatus(), PayState.HAVE_TO_PAY)) {
return;
}
//支付成功-修改订单状态
order.setPayStatus(PayState.TO_BE_PAID);
order.setResult(transaction.getTradeStateDesc());
paOrderService.updateById(order);
//支付成功-充值钻石
PaVipCurrency currency = new PaVipCurrency();
currency.setState("t");
if (order.getBuyType().equals("1")){
currency.setNumerical(5);
}else if (order.getBuyType().equals("2")){
currency.setNumerical(10);
}else if (order.getBuyType().equals("3")){
currency.setNumerical(20);
}else if (order.getBuyType().equals("4")){
currency.setNumerical(30);
}else if (order.getBuyType().equals("5")){
currency.setNumerical(50);
}else if (order.getBuyType().equals("6")){
currency.setNumerical(100);
}else {
return;
}
currency.setUserid(order.getMemberId());
paVipCurrencyService.save(currency);
// 添加日志
PaConsumption consumption = new PaConsumption();
consumption.setAddOrSub("add");
consumption.setUserid(order.getMemberId());
consumption.setValue(currency.getNumerical());
consumption.setCreatetime(new Date());
paConsumptionService.save(consumption);
}
} catch (ValidationException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,30 @@
package com.pixelai.api.pa.entity.enums;
/**
* 支付状态
*
* @Author mzl.
*/
public enum PayState {
/**
* 待支付
*/
TO_BE_PAID,
/**
* 已支付
*/
HAVE_TO_PAY,
/**
* 待退款
*/
FOR_A_REFUND,
/**
* 已退款
*/
HAVE_TO_REFUND;
}

View File

@ -13,7 +13,6 @@ import com.pixelai.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.xml.ws.Action;
import java.util.List;
/**

View File

@ -0,0 +1,82 @@
package com.pixelai.config;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import lombok.Getter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import com.wechat.pay.java.service.payments.h5.H5Service;
/**
* @desc: 微信config
* @author: shy
* @date: 2024/4/9 10:06
*/
@Configuration
@Getter
public class WeChatConfig {
/**
* 商户号
*/
@Value("${wechat.pay.merchantId}")
public String merchantId;
/**
* 商户API私钥路径
*/
@Value("${wechat.pay.privateKeyPath}")
public String privateKeyPath;
/**
* 商户证书序列号
*/
@Value("${wechat.pay.merchantSerialNumber}")
public String merchantSerialNumber;
/**
* 商户APIV3密钥
*/
@Value("${wechat.pay.apiV3Key}")
public String apiV3Key;
/**
* AppId
*/
@Value("${wechat.pay.appId}")
public String appId;
@Value("${wechat.pay.addressIp}")
public String addressIp;
@Value("${wechat.pay.notifyUrl}")
public String notifyUrl;
private Config config;
@PostConstruct
public void initConfig() {
// 使用自动更新平台证书的RSA配置
// 一个商户号只能初始化一个配置否则会因为重复的下载任务报错
config = new RSAAutoCertificateConfig.Builder()
.merchantId(merchantId)
.privateKeyFromPath(privateKeyPath)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3Key)
.build();
}
@Primary
@Bean()
public H5Service h5Service() {
return new H5Service.Builder()
.config(config)
.build();
}
@Primary
@Bean
public NotificationParser notificationParser() {
return new NotificationParser((NotificationConfig) config);
}
}

View File

@ -1,99 +1,104 @@
package com.pixelai.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.base.helper.Result;
import com.pixelai.utils.XssUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
@Component
@Aspect
@Order(2)
public class XssParamAspect {
private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
private ThreadLocal<Long> startTime = new ThreadLocal<>();
@Pointcut("execution(public * com.pixelai.api.*.controller.*.*(..))")
public void xssPoint() {
}
@Before("xssPoint()")
public void paramValid(JoinPoint point) throws Throwable {
logger.info("--------进入xss切点-------------");
Object[] args = point.getArgs();
for (Object o : args) {
if (o instanceof HttpServletResponse) {
// 如果参数类型是 HttpServletResponse则不做过滤转义处理
break;
}
else if (o instanceof Number) {
continue;
} else if (o instanceof String) {
XssUtils.stripXSS(o.toString());
} else if (o instanceof BindingResult) {
// 如果参数类型是 BindingResult则直接跳过
continue;
} else if (o instanceof MultipartFile) {
// 如果参数类型是 MultipartFile则直接跳过
continue;
}else if (o instanceof ArrayList) {
// 如果参数类型是 MultipartFile则直接跳过
continue;
}else if (o == null) {
// 如果参数类型是 null则直接跳过
continue;
}
else {
Class clazz = o.getClass();
String paramStr = JSON.toJSONString(o);
// System.out.println("未处理:" + paramStr);
// 使用fastjson将请求的参数转换为map
HashMap<String, Object> map = JSONObject.parseObject(paramStr, new TypeReference<HashMap<String, Object>>() {
});
map.forEach((k, v) -> {
if (!"token".equals(k) && v instanceof String) {
map.put(k, XssUtils.stripXSS(k, v.toString()));
}
});
//System.out.println(map);
// 将map转为json
String json = JSONObject.toJSONString(map);
// System.out.println("转义过滤之后:" + json);
// 将JSON字符串转换为对象
Object o1 = JSON.parseObject(json, clazz);
// System.out.println(o1);
BeanUtils.copyProperties(o1, o);
}
}
// 将参数覆盖到到原方法
// Object proceed = point.proceed(args);
// return proceed;
}
@AfterReturning(returning = "result", pointcut = "xssPoint()")
public void doAfterReturning(JoinPoint joinPoint, Result result) throws IllegalAccessException {
// 在返回请求之前对返回的内容进行过滤转义
logger.info("过滤之前 : " + result.toString());
XssUtils.encodeHtml(result);
// BeanUtils.copyProperties(result1, result);
}
}
//package com.pixelai.config;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.alibaba.fastjson.TypeReference;
//import com.base.helper.Result;
//import com.pixelai.utils.XssUtils;
//import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.annotation.AfterReturning;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Before;
//import org.aspectj.lang.annotation.Pointcut;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.BeanUtils;
//import org.springframework.core.annotation.Order;
//import org.springframework.stereotype.Component;
//import org.springframework.validation.BindingResult;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.util.ArrayList;
//import java.util.HashMap;
//
//@Component
//@Aspect
//@Order(2)
//public class XssParamAspect {
//
// private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
//
// private ThreadLocal<Long> startTime = new ThreadLocal<>();
//
// @Pointcut("execution(public * com.pixelai.api.*.controller.*.*(..))")
// public void xssPoint() {
// }
//
// @Before("xssPoint()")
// public void paramValid(JoinPoint point) throws Throwable {
// logger.info("--------进入xss切点-------------");
// Object[] args = point.getArgs();
// for (Object o : args) {
// if (o instanceof HttpServletResponse) {
// // 如果参数类型是 HttpServletResponse则不做过滤转义处理
// break;
// }
// if (o instanceof HttpServletRequest) {
// // 如果参数类型是 HttpServletResponse则不做过滤转义处理
// break;
// }
// else if (o instanceof Number) {
// continue;
// } else if (o instanceof String) {
// XssUtils.stripXSS(o.toString());
// } else if (o instanceof BindingResult) {
// // 如果参数类型是 BindingResult则直接跳过
// continue;
// } else if (o instanceof MultipartFile) {
// // 如果参数类型是 MultipartFile则直接跳过
// continue;
// }else if (o instanceof ArrayList) {
// // 如果参数类型是 MultipartFile则直接跳过
// continue;
// }else if (o == null) {
// // 如果参数类型是 null则直接跳过
// continue;
// }
// else {
// Class clazz = o.getClass();
// String paramStr = JSON.toJSONString(o);
//// System.out.println("未处理:" + paramStr);
// // 使用fastjson将请求的参数转换为map
// HashMap<String, Object> map = JSONObject.parseObject(paramStr, new TypeReference<HashMap<String, Object>>() {
// });
// map.forEach((k, v) -> {
// if (!"token".equals(k) && v instanceof String) {
// map.put(k, XssUtils.stripXSS(k, v.toString()));
// }
// });
// //System.out.println(map);
// // 将map转为json
// String json = JSONObject.toJSONString(map);
//// System.out.println("转义过滤之后:" + json);
// // 将JSON字符串转换为对象
// Object o1 = JSON.parseObject(json, clazz);
//// System.out.println(o1);
// BeanUtils.copyProperties(o1, o);
// }
// }
// // 将参数覆盖到到原方法
//// Object proceed = point.proceed(args);
//// return proceed;
// }
//
// @AfterReturning(returning = "result", pointcut = "xssPoint()")
// public void doAfterReturning(JoinPoint joinPoint, Result result) throws IllegalAccessException {
// // 在返回请求之前对返回的内容进行过滤转义
// logger.info("过滤之前 : " + result.toString());
// XssUtils.encodeHtml(result);
//// BeanUtils.copyProperties(result1, result);
// }
//}
//

View File

@ -0,0 +1,127 @@
package com.pixelai.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.util.Date;
import java.util.Random;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import com.base.helper.DateUtils;
import com.wechat.pay.java.core.cipher.RSASigner;
import com.wechat.pay.java.core.cipher.SignatureResult;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.core.util.NonceUtil;
import com.wechat.pay.java.core.util.PemUtil;
/**
* @desc: 微信工具类
* @author: shy
* @date: 2024/4/8 16:10
*/
public class WeChatUtil {
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
/**
* 生成订单号
*
* @param
* @return String
* @author shy
* @date 2024/4/8 16:15
*/
public static String generateTradeNumber() {
// 定义订单号前缀
String prefix = "shy";
// 当前年月日
String currentTimeStr = DateUtils.date(new Date(), "yyyyMMddHHmmss");
// 获取当前时间戳
long timestamp = System.currentTimeMillis();
// 构造订单号
return prefix + currentTimeStr + timestamp;
}
/**
* 获取随机字符串 Nonce Str
*
* @param
* @return String
* @author shy
* @date 2024/4/16 17:07
*/
public static String generateNonceStr() {
return NonceUtil.createNonce(32);
}
/**
* 获取当前时间戳单位秒
* @param
* @return long
* @author shy
* @date 2024/4/16 17:10
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000;
}
public static String getSign(String signatureStr, String privateKeyPath, String merchantSerialNumber) {
PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(privateKeyPath);
RSASigner rsaSigner = new RSASigner(merchantSerialNumber, privateKey);
SignatureResult signatureResult = rsaSigner.sign(signatureStr);
return signatureResult.getSign();
}
/**
* 构造 RequestParam
*
* @param request
* @return RequestParam
* @author shy
* @date 2024/4/9 11:16
*/
public static RequestParam handleNodifyRequestParam(HttpServletRequest request) throws IOException {
// 请求头Wechatpay-Signature
String signature = request.getHeader("Wechatpay-Signature");
// 请求头Wechatpay-nonce
String nonce = request.getHeader("Wechatpay-Nonce");
// 请求头Wechatpay-Timestamp
String timestamp = request.getHeader("Wechatpay-Timestamp");
// 微信支付证书序列号
String serial = request.getHeader("Wechatpay-Serial");
// 签名方式
String signType = request.getHeader("Wechatpay-Signature-Type");
// 构造 RequestParam
return new RequestParam.Builder().serialNumber(serial).nonce(nonce).signature(signature).timestamp(timestamp).signType(signType).body(getRequestBody(request)).build();
}
public static String getRequestBody(HttpServletRequest request) throws IOException {
ServletInputStream stream;
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
stream = request.getInputStream();
// 获取响应
reader = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
throw new IOException("读取返回支付接口数据流出现异常!");
} finally {
if (reader != null) {
reader.close();
}
}
return sb.toString();
}
}

View File

@ -1,251 +1,251 @@
package com.pixelai.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.base.helper.Result;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class XssUtils {
private XssUtils() {
}
// private static final Pattern[] PATTERNS = {
// // Avoid anything in a <script> type of expression
// Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
// // Avoid anything in a src='...' type of expression
// Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// // Remove any lonesome </script> tag
// Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
// // Avoid anything in a <iframe> type of expression
// Pattern.compile("<iframe>(.*?)</iframe>", Pattern.CASE_INSENSITIVE),
// // Remove any lonesome <script ...> tag
// Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// // Remove any lonesome <img ...> tag
// Pattern.compile("<img(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// // Avoid eval(...) expressions
// Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// // Avoid expression(...) expressions
// Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// // Avoid javascript:... expressions
// Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
// // Avoid vbscript:... expressions
// Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
// // Avoid οnlοad= expressions
// Pattern.compile("on(load|error|mouseover|submit|reset|focus|click)(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
// };
public static String stripXSS(String value) {
return stripXSS(null, value);
}
//package com.pixelai.utils;
//
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.base.helper.Result;
//import org.apache.commons.lang3.StringUtils;
//
//import java.io.Serializable;
//import java.lang.reflect.Field;
//import java.util.ArrayList;
//import java.util.Collection;
//import java.util.List;
//
//public class XssUtils {
//
// private XssUtils() {
// }
//
//// private static final Pattern[] PATTERNS = {
//// // Avoid anything in a <script> type of expression
//// Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
//// // Avoid anything in a src='...' type of expression
//// Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// // Remove any lonesome </script> tag
//// Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
//// // Avoid anything in a <iframe> type of expression
//// Pattern.compile("<iframe>(.*?)</iframe>", Pattern.CASE_INSENSITIVE),
//// // Remove any lonesome <script ...> tag
//// Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// // Remove any lonesome <img ...> tag
//// Pattern.compile("<img(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// // Avoid eval(...) expressions
//// Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// // Avoid expression(...) expressions
//// Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//// // Avoid javascript:... expressions
//// Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
//// // Avoid vbscript:... expressions
//// Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
//// // Avoid οnlοad= expressions
//// Pattern.compile("on(load|error|mouseover|submit|reset|focus|click)(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
//// };
//
// public static String stripXSS(String value) {
// return stripXSS(null, value);
// }
//
//// public static String stripXSS(String key, String value) {
//// if (StringUtils.isEmpty(value)) {
//// return value;
//// }
//// value = htmlEncode(value);
//// System.out.println("value = " + value);
//// return value;
//// }
//
// public static String stripXSS(String key, String value) {
// if (StringUtils.isEmpty(value)) {
// return value;
// if (value != null) {
// // 如果是时间格式的字符串仅过滤其中的数字部分
// if (value.matches("\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}")) {
// // 提取数字部分
// String digitsOnly = value.replaceAll("\\D", "");
// // 只对数字部分进行XSS过滤
// value = value.replace(digitsOnly, stripXSS(digitsOnly));
// } else {
// value = value;
//// .replaceAll("&", "&amp;")
//// .replaceAll("<", "&lt;")
//// .replaceAll(">", "&gt;")
//// .replaceAll("\"", "&quot;")
//// .replaceAll("'", "&#39;")
//// .replaceAll("\\(", "&#40;")
//// .replaceAll("\\)", "&#41;")
//// .replaceAll("eval\\((.*)\\)", "")
//// .replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
// // 过滤空格
//// value = value.replaceAll("\\s", "");
// }
// }
// value = htmlEncode(value);
// System.out.println("value = " + value);
// return value;
// }
public static String stripXSS(String key, String value) {
if (value != null) {
// 如果是时间格式的字符串仅过滤其中的数字部分
if (value.matches("\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}")) {
// 提取数字部分
String digitsOnly = value.replaceAll("\\D", "");
// 只对数字部分进行XSS过滤
value = value.replace(digitsOnly, stripXSS(digitsOnly));
} else {
value = value;
// .replaceAll("&", "&amp;")
// .replaceAll("<", "&lt;")
// .replaceAll(">", "&gt;")
// .replaceAll("\"", "&quot;")
// .replaceAll("'", "&#39;")
// .replaceAll("\\(", "&#40;")
// .replaceAll("\\)", "&#41;")
// .replaceAll("eval\\((.*)\\)", "")
// .replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
// 过滤空格
// value = value.replaceAll("\\s", "");
}
}
return value;
}
private static String htmlEncode(char c) {
switch(c) {
case '&':
return "&amp;";
case '<':
return "&lt;";
case '>':
return "&gt;";
case '"':
return "&quot;";
case ' ':
return "&nbsp;";
default:
return c + "";
}
}
/** 对传入的字符串str进行Html encode转换 */
public static String htmlEncode(String str) {
if (str ==null || str.trim().equals("")) return str;
StringBuilder encodeStrBuilder = new StringBuilder();
for (int i = 0, len = str.length(); i < len; i++) {
encodeStrBuilder.append(htmlEncode(str.charAt(i)));
}
return encodeStrBuilder.toString();
}
// 该方法包含两个重载方法第一个方法用来处理整个Result对象
// 第二个方法用来处理单个对象中的属性如果数据是集合类型先将集合中的对象逐一处理否则直接处理数据对象本身
// 对于每个属性值使用反射机制获取其值如果是字符串类型则使用StringEscapeUtils类进行HTML编码然后将编码后的值设置回属性中
// 这样就可以对返回值中的所有字符串类型的属性进行HTML编码了
// 注意这种方式仅处理字符串类型的属性值如果还有其他类型的属性需要处理或者有其他的HTML编码需求可以根据实际情况进行调整
public static <T extends Serializable> Result<T> encodeHtml(Result<T> result) throws IllegalAccessException {
if (result == null || result.getData() == null) {
return result;
}
Object data = result.getData();
if (data instanceof IPage<?>) {
// 如果数据是IPage类型则对分页结果进行HTML编码
IPage<T> page = (IPage<T>) data;
encodeHtml(page.getRecords());
} else if (data instanceof Collection<?>) {
// 如果数据是集合类型先将集合中的对象逐一处理
Collection<T> dataList = (Collection<T>) data;
encodeHtml(dataList);
} else {
// 否则直接处理数据对象本身
encodeHtmlForObject(data);
}
// if (result.getData() instanceof Collection) {
//
// private static String htmlEncode(char c) {
//
// switch(c) {
//
// case '&':
//
// return "&amp;";
//
// case '<':
//
// return "&lt;";
//
// case '>':
//
// return "&gt;";
//
// case '"':
//
// return "&quot;";
//
// case ' ':
//
// return "&nbsp;";
//
// default:
//
// return c + "";
//
// }
//
// }
//
// /** 对传入的字符串str进行Html encode转换 */
// public static String htmlEncode(String str) {
// if (str ==null || str.trim().equals("")) return str;
//
// StringBuilder encodeStrBuilder = new StringBuilder();
// for (int i = 0, len = str.length(); i < len; i++) {
// encodeStrBuilder.append(htmlEncode(str.charAt(i)));
// }
// return encodeStrBuilder.toString();
// }
//
// // 该方法包含两个重载方法第一个方法用来处理整个Result对象
// // 第二个方法用来处理单个对象中的属性如果数据是集合类型先将集合中的对象逐一处理否则直接处理数据对象本身
// // 对于每个属性值使用反射机制获取其值如果是字符串类型则使用StringEscapeUtils类进行HTML编码然后将编码后的值设置回属性中
// // 这样就可以对返回值中的所有字符串类型的属性进行HTML编码了
// // 注意这种方式仅处理字符串类型的属性值如果还有其他类型的属性需要处理或者有其他的HTML编码需求可以根据实际情况进行调整
//
// public static <T extends Serializable> Result<T> encodeHtml(Result<T> result) throws IllegalAccessException {
// if (result == null || result.getData() == null) {
// return result;
// }
//
// Object data = result.getData();
// if (data instanceof IPage<?>) {
// // 如果数据是IPage类型则对分页结果进行HTML编码
// IPage<T> page = (IPage<T>) data;
// encodeHtml(page.getRecords());
// } else if (data instanceof Collection<?>) {
// // 如果数据是集合类型先将集合中的对象逐一处理
// Collection<T> dataList = (Collection<T>) result.getData();
// for (T data : dataList) {
// encodeHtmlForObject(data);
// }
// Collection<T> dataList = (Collection<T>) data;
// encodeHtml(dataList);
// } else {
// // 否则直接处理数据对象本身
// encodeHtmlForObject(result.getData());
// encodeHtmlForObject(data);
// }
return result;
}
/**
* 对集合中的所有对象进行HTML编码
* @param dataList
* @param <T>
* @throws IllegalAccessException
*/
private static <T> void encodeHtml(Collection<T> dataList) throws IllegalAccessException {
for (T data : dataList) {
encodeHtmlForObject(data);
}
}
/**
* 对对象的所有字符串类型属性进行HTML编码
* @param object
* @param <T>
* @throws IllegalAccessException
*/
private static <T> void encodeHtmlForObject(T object) throws IllegalAccessException {
if (object == null) {
return;
}
// 获取对象的所有属性
List<Field> fields = new ArrayList<>();
getAllFields(object.getClass(), fields);
// Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object fieldValue = field.get(object);
// 如果属性值是字符串类型对其进行HTML编码
if (fieldValue instanceof String && !"token".equals(field.getName())) {
String originalValue = (String) fieldValue;
if (StringUtils.isNotEmpty(originalValue)) {
//注释不知道为何报错
// String encodedValue = stripXSS(originalValue);
// field.set(object, encodedValue);
}
}
}
}
/**
* 获取当前类所有的属性包含父类
* @param clazz
* @param fields
*/
public static void getAllFields(Class clazz, List<Field> fields) {
if (clazz != null && !clazz.equals(Object.class)) {
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
fields.add(field);
}
getAllFields(clazz.getSuperclass(), fields);
}
}
// 对对象的所有字符串类型属性进行HTML编码
//
//// if (result.getData() instanceof Collection) {
//// // 如果数据是集合类型先将集合中的对象逐一处理
//// Collection<T> dataList = (Collection<T>) result.getData();
//// for (T data : dataList) {
//// encodeHtmlForObject(data);
//// }
//// } else {
//// // 否则直接处理数据对象本身
//// encodeHtmlForObject(result.getData());
//// }
// return result;
// }
//
// /**
// * 对集合中的所有对象进行HTML编码
// * @param dataList
// * @param <T>
// * @throws IllegalAccessException
// */
// private static <T> void encodeHtml(Collection<T> dataList) throws IllegalAccessException {
// for (T data : dataList) {
// encodeHtmlForObject(data);
// }
// }
//
// /**
// * 对对象的所有字符串类型属性进行HTML编码
// * @param object
// * @param <T>
// * @throws IllegalAccessException
// */
// private static <T> void encodeHtmlForObject(T object) throws IllegalAccessException {
// if (object == null) {
// return;
// }
//
// // 获取对象的所有属性
// Field[] fields = object.getClass().getDeclaredFields();
// List<Field> fields = new ArrayList<>();
// getAllFields(object.getClass(), fields);
//// Field[] fields = object.getClass().getDeclaredFields();
// for (Field field : fields) {
// field.setAccessible(true);
// Object fieldValue = field.get(object);
//
// // 如果属性名是"token"则跳过
// if ("token".equals(field.getName())) {
// continue;
// }
//
// // 如果属性值是字符串类型对其进行HTML编码
// if (fieldValue instanceof String) {
// if (fieldValue instanceof String && !"token".equals(field.getName())) {
// String originalValue = (String) fieldValue;
// if (StringUtils.isNotEmpty(originalValue)) {
// String encodedValue = StringEscapeUtils.escapeHtml4(originalValue);
// field.set(object, encodedValue);
// //注释不知道为何报错
//// String encodedValue = stripXSS(originalValue);
//// field.set(object, encodedValue);
// }
// }
// }
// }
}
//
// /**
// * 获取当前类所有的属性包含父类
// * @param clazz
// * @param fields
// */
// public static void getAllFields(Class clazz, List<Field> fields) {
// if (clazz != null && !clazz.equals(Object.class)) {
// Field[] declaredFields = clazz.getDeclaredFields();
// for (Field field : declaredFields) {
// field.setAccessible(true);
// fields.add(field);
// }
// getAllFields(clazz.getSuperclass(), fields);
// }
// }
//
// // 对对象的所有字符串类型属性进行HTML编码
//// private static <T> void encodeHtmlForObject(T object) throws IllegalAccessException {
//// if (object == null) {
//// return;
//// }
////
//// // 获取对象的所有属性
//// Field[] fields = object.getClass().getDeclaredFields();
//// for (Field field : fields) {
//// field.setAccessible(true);
//// Object fieldValue = field.get(object);
////
//// // 如果属性名是"token"则跳过
//// if ("token".equals(field.getName())) {
//// continue;
//// }
////
//// // 如果属性值是字符串类型对其进行HTML编码
//// if (fieldValue instanceof String) {
//// String originalValue = (String) fieldValue;
//// if (StringUtils.isNotEmpty(originalValue)) {
//// String encodedValue = StringEscapeUtils.escapeHtml4(originalValue);
//// field.set(object, encodedValue);
//// }
//// }
//// }
//// }
//
//}
//
//

View File

@ -94,6 +94,15 @@ external:
ip: "http:\\8.138.171.103\\"
wechat:
pay:
merchantId: 1702829541
privateKeyPath: D:\chromeDown\WXCertUtil\cert\apiclient_key.pem # D:\chromeDown\WXCertUtil\cert\apiclient_key.pem D:\cert\apiclient_key.pem
merchantSerialNumber: 1729D576BA6419FB50FB39436581D6AA98DF931D
apiV3Key: APOsmG7Ry5i2z5264M8d7zfFMs3hY7h1
appId: wx2a3ff6e1a0e4f093
addressIp: 8.138.171.103 #120.235.233.15
notifyUrl: http://localhost:8081/paOrder/payNotify #http://localhost:8081/paOrder/payNotify http://8.138.171.103/pixelApi/paOrder/payNotify
# 静态资源图片路径
picture:
fail: "https://guojunjie.oss-cn-hangzhou.aliyuncs.com/fail.jpg"