Java | Utiliser l'aspect AOP pour intercepter et modifier les paramètres de requête de l'interface du contrôleur

Suivre wx commun : CodingTechWork

introduction

  Au cours du processus de développement, il y aura des exigences pour convertir complètement certains paramètres d'entrée de méthode de la couche contrôleur. La chose la plus simple à laquelle penser peut être que lors de l'appel de la méthode de service de la couche inférieure, la méthode publique est appelée pour effectuer le paramètre d'entrée conversion Le seul problème apporté à ce moment Le code est disgracieux et redondant. Existe-t-il donc un moyen de résoudre ce problème de manière plus élégante? La réponse est oui : les facettes.
  Nous implémentons un programme d'aspect AOP pour effectuer une conversion spéciale sur les paramètres qui doivent être convertis dans les paramètres d'entrée, sans qu'il soit nécessaire d'effectuer un traitement de conversion dans chaque méthode de chaque couche de contrôleur.

pratique

classe contrôleur

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!";
    }

}

Nouilles

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 {
    
    
        	//获取入参列表
            Object[] args = joinPoint.getArgs();
            log.info("args: {}", JSON.toJSONString(args));
            //入参判空
            if (null == args || args.length == 0) {
    
    
                log.info("no fields!");
                return;
            }
            //获取第一个入参(主要针对@RequestBody,一般只会有一个入参,若遇到多个@RequestParam,需循环处理)
            Object arg = args[0];
            //获取字段域
            Field[] fields = arg.getClass().getDeclaredFields();
            log.info("getDeclaredFields: {}", JSON.toJSONString(fields));
			//判断入参中是否有"name"
            if (Arrays.stream(fields).noneMatch(item -> "name".equals(item.getName()))) {
    
    
                log.info("no name field!");
                return;
            }
            //入参中有"name",获取该字段
            Field field = arg.getClass().getDeclaredField("name");
            //判断是否可使用
            boolean accessible = ((!Modifier.isPublic(field.getModifiers())
                    || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                    || Modifier.isFinal(field.getModifiers())) && !field.isAccessible());
            //若不可用,则需要进行setAccessible
            if (accessible) {
    
    
                ServletRequestAttributes attributes
                        = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                // 获取request对象
                HttpServletRequest request = attributes.getRequest();
                log.info("method name: {}", request.getRequestURI());
                field.setAccessible(true);
                //将name参数替换为system
                field.set(arg, "system");
            }
        } catch (Exception e) {
    
    
            log.error("切面参数设置异常", e);
        }
    }
}

vérifier

Pas d'interface de test de paramètres 1

  1. appel d'interface
    insérez la description de l'image ici
  2. journal de la console
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!
  1. Analyse des résultats
    Aucun paramètre n'est obtenu et l'interface est utilisée normalement. Imprimer no fields!sans convertir les arguments.

Ne contient pas l'interface de test de paramètre spécifiée 2

  1. appel d'interface
    insérez la description de l'image ici

  2. journal de la console

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!
  1. Analyse du résultat
    Les paramètres spécifiés ne sont pas obtenus et l'interface est utilisée normalement. Imprimer no name field!sans convertir les arguments.

Contient l'interface de test de paramètre spécifiée 3

  1. appel d'interface
    insérez la description de l'image ici

  2. journal de la console

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
  1. Analyse du résultat
    Le paramètre spécifié est obtenu, la valeur du nom est remplacée par system, et le paramètre de conversion d'aspect est réussi.

Je suppose que tu aimes

Origine blog.csdn.net/Andya_net/article/details/131442326
conseillé
Classement