關(guān)注common wx: CodingTechWork
引言
??在開發(fā)過程中,會(huì)有一些需求將controller層的一些方法入?yún)⑦M(jìn)行全量轉(zhuǎn)換,最容易想到的可能是在調(diào)用下層service方法時(shí),調(diào)用公共的方法進(jìn)行入?yún)⑥D(zhuǎn)換,這時(shí)帶來的唯一問題就是代碼不雅觀,比較冗余。那還有什么方法可以更優(yōu)雅的解決這個(gè)問題嗎?答案是有的:切面。
??我們實(shí)現(xiàn)一個(gè)AOP切面程序,對(duì)入?yún)⒅械男柁D(zhuǎn)換的參數(shù)進(jìn)行專項(xiàng)轉(zhuǎn)換,而無需在各個(gè)controller層的各個(gè)方法中進(jìn)行轉(zhuǎn)換處理。
實(shí)踐
controller類
package com.test.selfcoding.controller;
import com.test.selfcoding.bean.PersonBean;
import com.test.selfcoding.service.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Description controller
* @Author Liao Jy
* @Date 2023/6/28
*/
@RestController
@RequestMapping("/hello/world")
public class HelloWorldController {
@Autowired
private HelloWorldService helloWorldService;
@GetMapping("/test1")
public String testGetHelloWorld() {
return helloWorldService.getHelloWolrd();
}
@PostMapping("/test2")
public String testPostHelloWord(@RequestBody PersonBean personBean) {
return helloWorldService.postHelloWorld(personBean);
}
@GetMapping("/test3")
public String testPostHelloWord(@RequestParam String personName) {
return personName + ", hi world!";
}
}
切面類
package com.test.selfcoding.aspect;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* @Description DefaultArgumentsAspect
* @Author LiaoJy
* @Date 2023/6/28
*/
@Component
@Aspect
@Slf4j
public class DefaultArgumentsAspect {
@Before(value = "execution(* com.test.selfcoding.controller..*(..))")
public void doBefore(JoinPoint joinPoint) {
try {
//獲取入?yún)⒘斜?/span>
Object[] args = joinPoint.getArgs();
log.info("args: {}", JSON.toJSONString(args));
//入?yún)⑴锌?/span>
if (null == args || args.length == 0) {
log.info("no fields!");
return;
}
//獲取第一個(gè)入?yún)ⅲㄖ饕槍?duì)@RequestBody,一般只會(huì)有一個(gè)入?yún)?,若遇到多個(gè)@RequestParam,需循環(huán)處理)
Object arg = args[0];
//獲取字段域
Field[] fields = arg.getClass().getDeclaredFields();
log.info("getDeclaredFields: {}", JSON.toJSONString(fields));
//判斷入?yún)⒅惺欠裼?name"
if (Arrays.stream(fields).noneMatch(item -> "name".equals(item.getName()))) {
log.info("no name field!");
return;
}
//入?yún)⒅杏?name",獲取該字段
Field field = arg.getClass().getDeclaredField("name");
//判斷是否可使用
boolean accessible = ((!Modifier.isPublic(field.getModifiers())
|| !Modifier.isPublic(field.getDeclaringClass().getModifiers())
|| Modifier.isFinal(field.getModifiers())) && !field.isAccessible());
//若不可用,則需要進(jìn)行setAccessible
if (accessible) {
ServletRequestAttributes attributes
= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 獲取request對(duì)象
HttpServletRequest request = attributes.getRequest();
log.info("method name: {}", request.getRequestURI());
field.setAccessible(true);
//將name參數(shù)替換為system
field.set(arg, "system");
}
} catch (Exception e) {
log.error("切面參數(shù)設(shè)置異常", e);
}
}
}
驗(yàn)證
無參測(cè)試接口1
- 接口調(diào)用
- 控制臺(tái)日志
2023-06-28 18:06:06.060 INFO 6495 --- [nio-8001-exec-1] c.t.s.aspect.DefaultArgumentsAspect : args: []
2023-06-28 18:06:06.061 INFO 6495 --- [nio-8001-exec-1] c.t.s.aspect.DefaultArgumentsAspect : no fields!
2023-06-28 18:06:06.066 INFO 6495 --- [nio-8001-exec-1] c.t.s.s.impl.HelloWorldServiceImpl : getHelloWolrd() get str success.
result: hugh, hello world!
- 結(jié)果分析
未獲取到參數(shù),正常走接口。打印no fields!
,無需轉(zhuǎn)換參數(shù)。
不包含指定參數(shù)測(cè)試接口2
-
接口調(diào)用
-
控制臺(tái)日志文章來源地址http://www.zghlxwxcb.cn/news/detail-820435.html
2023-06-28 18:08:04.040 INFO 6495 --- [nio-8001-exec-5] c.t.s.aspect.DefaultArgumentsAspect : args: ["xiaowang"]
2023-06-28 18:08:04.055 INFO 6495 --- [nio-8001-exec-5] c.t.s.aspect.DefaultArgumentsAspect : getDeclaredFields: [{"accessible":false,"annotatedType":{"annotatedGenericComponentType":{"annotations":[],"declaredAnnotations":[],"type":"char"},"annotations":[],"declaredAnnotations":[],"type":"[C"},"annotations":[],"declaringClass":"java.lang.String","enumConstant":false,"genericType":"[C","modifiers":18,"name":"value","synthetic":false,"type":"[C"},{"accessible":false,"annotatedType":{"annotations":[],"declaredAnnotations":[],"type":"int"},"annotations":[],"declaringClass":"java.lang.String","enumConstant":false,"genericType":"int","modifiers":2,"name":"hash","synthetic":false,"type":"int"},{"accessible":false,"annotatedType":{"annotations":[],"declaredAnnotations":[],"type":"long"},"annotations":[],"declaringClass":"java.lang.String","enumConstant":false,"genericType":"long","modifiers":26,"name":"serialVersionUID","synthetic":false,"type":"long"},{"accessible":false,"annotatedType":{"annotatedGenericComponentType":{"annotations":[],"declaredAnnotations":[],"type":"java.io.ObjectStreamField"},"annotations":[],"declaredAnnotations":[],"type":"[Ljava.io.ObjectStreamField;"},"annotations":[],"declaringClass":"java.lang.String","enumConstant":false,"genericType":"[Ljava.io.ObjectStreamField;","modifiers":26,"name":"serialPersistentFields","synthetic":false,"type":"[Ljava.io.ObjectStreamField;"},{"accessible":false,"annotatedType":{"annotatedActualTypeArguments":[{"annotations":[],"declaredAnnotations":[],"type":"java.lang.String"}],"annotations":[],"declaredAnnotations":[],"type":{"actualTypeArguments":["java.lang.String"],"rawType":"java.util.Comparator","typeName":"java.util.Comparator<java.lang.String>"}},"annotations":[],"declaringClass":"java.lang.String","enumConstant":false,"genericType":{"$ref":"$[4].annotatedType.type"},"modifiers":25,"name":"CASE_INSENSITIVE_ORDER","synthetic":false,"type":"java.util.Comparator"}]
2023-06-28 18:08:04.056 INFO 6495 --- [nio-8001-exec-5] c.t.s.aspect.DefaultArgumentsAspect : no name field!
- 結(jié)果分析
未獲取到指定的參數(shù),正常走接口。打印no name field!
,無需轉(zhuǎn)換參數(shù)。
包含指定參數(shù)測(cè)試接口3
-
接口調(diào)用
文章來源:http://www.zghlxwxcb.cn/news/detail-820435.html
-
控制臺(tái)日志
2023-06-28 18:10:15.481 INFO 6495 --- [nio-8001-exec-9] c.t.s.aspect.DefaultArgumentsAspect : args: [{"age":1,"name":"xiaohong"}]
2023-06-28 18:10:15.482 INFO 6495 --- [nio-8001-exec-9] c.t.s.aspect.DefaultArgumentsAspect : getDeclaredFields: [{"accessible":false,"annotatedType":{"annotations":[],"declaredAnnotations":[],"type":"java.lang.String"},"annotations":[],"declaringClass":"com.test.selfcoding.bean.PersonBean","enumConstant":false,"genericType":"java.lang.String","modifiers":2,"name":"name","synthetic":false,"type":"java.lang.String"},{"accessible":false,"annotatedType":{"annotations":[],"declaredAnnotations":[],"type":"int"},"annotations":[],"declaringClass":"com.test.selfcoding.bean.PersonBean","enumConstant":false,"genericType":"int","modifiers":2,"name":"age","synthetic":false,"type":"int"}]
2023-06-28 18:10:15.482 INFO 6495 --- [nio-8001-exec-9] c.t.s.aspect.DefaultArgumentsAspect : method name: /hello/world/test2
- 結(jié)果分析
獲取到指定的參數(shù),進(jìn)行name值替換為system
,切面轉(zhuǎn)換參數(shù)成功。
到了這里,關(guān)于Java | 使用切面AOP攔截并修改Controller接口請(qǐng)求參數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!