榆林网站建设熊掌号百度推广费2800元每年都有吗
文章目录
- 结论
- 举例子
- 原因
- 外传
结论
最近要搞脱敏信息,所以,想了几种方案,最后使用全局的接口拦截,但是,又不能用注解的方式,毕竟是几年的老产品,有很多限制。
中间尝试过使用Spring AOP 的 @afterReturing,但是发现返回值不能修改,就查了查源码。
答案来了:可以改变返回值,但是分情况,
不能改变:
第一种情况:如果返回的对象,改变了对象的引用地址,这种情况,是不能改变返回对象中的值的
第二种情况:如果返回的对象是一个基本数据类型,或者是String的值,是不能改变返回值的,尤其是String这种final类型的。
可以改变:
直接使用传入的object对象,改变其中的值,是可以的。
举例子
不能改变,例子只是简便,方便理解
package com.domes.common.restful.filter;import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.domes.common.api.dto.WebResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;/*** @Description: 脱敏拦截* @Author: weidong* @Time: 2023/8/10 15:23*/@Order(1)
@Aspect
@Slf4j
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DesensitizationAspect {@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || "+ "@annotation(org.springframework.web.bind.annotation.GetMapping)")public void desensitizationLog() {}@AfterReturning(value = "desensitizationLog()", returning = "obj")public Object doAfterReturning(JoinPoint joinPoint, Object obj) {//这种情况不能改变,返回的对象,改变了对象的引用地址,这种情况,是不能改变返回对象中的值的/*String objString = JSON.toJSONString(obj);JSONObject object = JSONObject.parseObject(objString);if(objString.contains("mobile")){dealObject(object);obj = object;}*///返回的对象是String等final修饰的值,是不能改变返回值的。//String returnStr = (String)obj;//returnStr = "改变数据";// 正常情况下,我们想要修改obj,只需要强转为对应的对象,再重新设置值即可,如下//这种情况可以改变WebResult webResult = (WebResult)obj;webResult.setMessage("改变");return obj;}private void dealObject(JSONObject object){object.forEach((key,val) ->{if(val instanceof JSONObject){dealObject((JSONObject) val);}else if(val instanceof JSONArray){dealArray((JSONArray) val);}else {if(key.equals("mobile")){object.put(key, DesensitizedUtil.mobilePhone(String.valueOf(val)));}}});}private void dealArray(JSONArray array){array.forEach(item ->{if(item instanceof JSONObject){dealObject((JSONObject) item);}else if(item instanceof JSONArray){dealArray((JSONArray) item);}});}}
原因
既然知道了答案了,我们看下源码为什么?
AfterReturningAdviceInterceptor看下这个类
/** Copyright 2002-2018 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.aop.framework.adapter;import java.io.Serializable;import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.util.Assert;/*** Interceptor to wrap an {@link org.springframework.aop.AfterReturningAdvice}.* Used internally by the AOP framework; application developers should not need* to use this class directly.** @author Rod Johnson* @see MethodBeforeAdviceInterceptor* @see ThrowsAdviceInterceptor*/
@SuppressWarnings("serial")
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {private final AfterReturningAdvice advice;/*** Create a new AfterReturningAdviceInterceptor for the given advice.* @param advice the AfterReturningAdvice to wrap*/public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {Assert.notNull(advice, "Advice must not be null");this.advice = advice;}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {//执行具体的接口controller层实现的方法Object retVal = mi.proceed();//调用DesensitizationAspect的afterReturning注解的doAfterReturning方法//大家仔细看,这个是个void方法,是没有接收返回值的this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());//返回值,同样是mi.proceed()执行后的对象return retVal;}}
外传
😜 原创不易,如若本文能够帮助到您的同学
🎉 支持我:关注我+点赞👍+收藏⭐️
📝 留言:探讨问题,看到立马回复
💬 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!🔥