要求某接口的请求参数有一个字段不要在日志中打印
前端传参和后端使用公钥密钥进行加密以后传输,后端业务执行的时候再解密;
自定义注解在日志打印的时候屏蔽
偷懒这里就不定义三种了准备这一个用到底了
/**
* 跳过Body请求参数日志打印
*/
@Target({ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SkipBodyParamLogPrint {
}
MethodSignature signature = (MethodSignature) pjp.getSignature();
SkipBodyParamLogPrint skipBodyParamLog = signature.getMethod().getDeclaredAnnotation(SkipBodyParamLogPrint.class);
if (ObjectUtil.isNotEmpty(skipBodyParamLog)) {
// 如果有需要跳过的请求参数就执行检查
args = paramSkipFilter(args);
}
/**
* 检查是否需要跳过请求参数打印
*
* @return
*/
public Object[] paramSkipFilter(Object[] args) {
Object[] objects = Arrays.stream(args)
.map(
arg -> {
// 获取所有字段
Field[] fields = arg.getClass().getDeclaredFields();
// 没有字段跳过
if (fields.length == 0)
return arg;
for (Field field : fields) {
// 字段如果有这注解就表示这个字段需要处理为空
SkipBodyParamLogPrint[] annotationsByType = field.getDeclaredAnnotationsByType(SkipBodyParamLogPrint.class);
if (annotationsByType.length != 0){
try {
// 拼接方法名
String methodName = "set" + StringUtils.capitalize(field.getName());
// 这里知道只有一个参数并且参数就是字段本身的类型就手动写了,其他地方需要用建议直接从数组匹配名称获得参数
Method method = arg.getClass().getDeclaredMethod(methodName, field.getType());
// 关闭安全检查
field.setAccessible(true);
// 执行方法,参数用字段类型进行实例化一个空对象,同样的如果其他地方需要用类似的方法,就从数组里获取方法然后取参数拼接数组传入
method.invoke(arg,field.getType().newInstance());
field.setAccessible(false);
} catch (IllegalAccessException |InvocationTargetException e) {
log.error("请求参数过滤时set方法调用失败",e);
break;
} catch (NoSuchMethodException | InstantiationException e) {
log.error("请求参数过滤时set方法实例化失败",e);
break;
}
}
}
// 返回处理以后的参数
return arg;
}
)
.toArray();
return objects;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "购买请求参数-purchase vip request parameters")
public class BuyGoodsParam {
@NotNull
@ApiModelProperty(value = "商品类型,1音频课程,2直播课程,3vip订阅-Commodity type, 1 audio course, 2 live course, 3 vip subscription")
private Integer goodsType;
@NotNull
@ApiModelProperty(value = "商品id-goods id")
private Long goodsId;
@NotBlank
@ApiModelProperty(value = "交易类型,wechatPay:微信支付;aliPay:支付宝,stripe:Stripe",required = true)
private String paymentType;
@NotNull
@ApiModelProperty(value = "是否使用积分 0不使用,1使用-WHETHER TO USE POINTS 0 DO NOT USE 1 USE")
private Integer useScore;
@ApiModelProperty(value = "信用卡信息")
@SkipBodyParamLogPrint
private CreditCardInfo creditCardInfo;
}
@ApiModelProperty("获取app支付参数")
@SkipBodyParamLogPrint
public void getPayOrderToApp(@RequestBody BuyGoodsParam buyGoodsParam) throws IOException {
orderService.getGoodsOrderFromApp(buyGoodsParam);
}