手写DispatcherServlet中央控制器,获取参数的名字parameter.getName(),获取的名字是arg0,arg1,arg2....导致接收不到前端传过来的token,登录已过期。

            手写DispatcherServlet中央控制器,获取参数的名字parameter.getName(),获取的名字是arg0,arg1,arg2......,导致接收不到前端传过来的token。登录的时候一直显示登录已过期,当时不知道是没有接收到token,一直认为是中央控制器的代码问题,中间问过老师,老师说是中央处理器的问题,但是不太愿意帮我解决,后来又问了两次,还是不太乐意,一直在debug,最后我猜想是不是获取参数的时候,参数名字是arg0的影响,然后老师说应该是,但是没有帮我解决这个问题,然后就走了,这个时候我已经感觉到老师不想帮,然后我就自己试着就先解决arg0的问题,去网上百度怎么得到参数名字真正的名字,最后得以解决,很是开心,这个过程很是漫长,因为这个问题困扰好几天,本来高高兴兴的找老师,以为老师能帮我解决,可是老师不太乐意帮我分析我自己封装的DispatcherServlet中央处理器的代码,当时真的有点失望,很多时候我们还是得靠自己,我们所期待的救星,可能只是一阵风,写这篇博客,想记录这个时刻,自己成长的过程,自己解决的问题会让自己明白这个过程的经过,分析代码的经过,debug无数次,最终找到问题所在,也是这次经历,让我明白debug的重要性,分析代码的利器,好,下面开始总结怎么解决这个问题。

1、第一个解决思路

是在idea设置中配置-parameters,但是很不幸,我的问题没有得到解决,因为我第一次就是这么配置的,所以我在检查代码的时候,一直认为和这个参数的名字arg0没有关系,当时觉的应该不是因为这个,其实问题还是因为参数的名字的影响,只不过这个配置对于我的代码没有效果,哈哈哈哈。

手写DispatcherServlet中央控制器,获取参数的名字parameter.getName(),获取的名字是arg0,arg1,arg2....导致接收不到前端传过来的token,登录已过期。_第1张图片

2、第二个解决思路 

因为我当时在Maven环境下总结这些知识的,所以可以在pom.xml文件中,配置这个-parameters,在pom.xml中配置build,配置完这个我的问题才得以解决,第一个解决思路,对于我的代码没有效果。

  
    
      
        org.apache.maven.plugins
        maven-compiler-plugin
        3.8.0
        
          17
          17
          
            -parameters
          
        
      
    
  

手写DispatcherServlet中央控制器,获取参数的名字parameter.getName(),获取的名字是arg0,arg1,arg2....导致接收不到前端传过来的token,登录已过期。_第2张图片

3、第三个解决思路 

如果您使用的是Gradle,则可以在build.gradle文件中添加以下配置:

compileJava {
    options.compilerArgs += "-parameters"
}

4、第四个解决思路 

如果您使用的是命令行编译器,则可以使用以下命令:

javac -parameters MyClass.java

请注意,这个选项仅适用于方法参数,而不适用于局部变量或字段名称。如果您需要获取局部变量或字段名称,可以使用Java字节码库,如ASM或ByteBuddy 

手写DispatcherServlet中央控制器,获取参数的名字parameter.getName(),获取的名字是arg0,arg1,arg2....导致接收不到前端传过来的token,登录已过期。_第3张图片

parameter.getName()获取到的参数名字为形参的名称,如果没有指定形参名称,则默认为arg0arg1arg2等。要解决这个问题,有以下几种方法:

  1. 在接口方法中指定参数名称

可以使用@WebParam(name = "paramName")注解在接口方法中指定参数名称,例如:

@WebMethod
int add(@WebParam(name = "a") int num1, @WebParam(name = "b") int num2);

这样在调用parameter.getName()时,就会返回指定的参数名称。

  1. 使用反射获取方法参数名

通过使用Java 8引入的反射API中的Parameter.getName()方法获取参数名称。需要使用Java 8或更高版本,并且需要在编译时开启-parameters选项,例如:

javac -parameters MyClass.java

然后使用反射获取参数名称,例如:

Method method = MyClass.class.getMethod("add", int.class, int.class);
Parameter[] parameters = method.getParameters();
String paramName = parameters[0].getName(); // 获取第一个参数的名称

  1. 使用第三方库

可以使用一些第三方库来获取方法参数名,例如Spring Framework中的org.springframework.core.LocalVariableTableParameterNameDiscoverer类,或者Google Guava库中的com.google.common.reflect.Parameter类。这些库可以在运行时获取方法参数名称,并且不需要在编译时开启-parameters选项。

一般来说,如果 parameter.getName() 返回的参数名为 arg0arg1 等,是因为编译器不知道参数的具体名称,因此它们被命名为 arg0arg1 等。这个问题可以通过在编译时使用 -parameters 选项来解决。这个选项会告诉编译器在编译时保留参数名称,而不是将它们命名为 arg0arg1 等。例如,使用 javac -parameters MyClass.java,其中 MyClass.java 是包含您的类和方法的源代码文件。

如果您无法在编译时使用 -parameters 选项,您可以尝试使用反射来获取参数名称。使用反射需要用到 Java 8 引入的 Parameter.getName() 方法。如果您的运行时环境是 Java 8 之前的版本,您可以使用第三方库,如 Javassist 或 ASM 来实现相同的功能。需要注意的是,使用反射或第三方库来获取参数名称可能会导致性能问题,并且可能会造成代码可读性和维护性问题。

您可以尝试使用getParameterTypes()方法来获取参数类型,然后根据类型来确定参数名。例如:

Method method = ... // 获取方法对象
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
    Parameter parameter = parameters[i];
    String parameterName = parameter.getName();
    if (parameter.getType() == int.class) {
        parameterName = "intValue";
    } else if (parameter.getType() == String.class) {
        parameterName = "stringValue";
    }
    System.out.println("Parameter " + i + " name: " + parameterName);
}

在这个例子中,我们通过判断参数类型来确定参数名。当然,你也可以使用其他规则来确定参数名。

在使用getParameter方法获取参数名时,若参数名未指定,则会默认赋值为arg0arg1arg2...等,可以通过以下两种方式解决:

  1. 指定参数名

在接口定义时,需要指定每个参数的名称,例如:

public interface UserService {
    void addUser(@RequestParam("name") String name, @RequestParam("age") int age);
}

这样,在调用getParameter方法时,就可以得到具体的参数名。

  1. 使用Spring AOP

使用Spring AOP可以实现方法级别的拦截,可以在方法调用前获取方法参数,并通过ParameterNameDiscoverer获取参数名,例如:

@Component
@Aspect
public class LogAspect {
    @Autowired
    private ParameterNameDiscoverer parameterNameDiscoverer;

    @Before("execution(* com.example.UserService.addUser(..))")
    public void beforeAddUser(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        Object[] args = joinPoint.getArgs();

        for (int i = 0; i < args.length; i++) {
            System.out.println(parameterNames[i] + " = " + args[i]);
        }
    }
}

这样,在调用addUser方法时,就可以通过AOP拦截,在方法调用前获取参数名。

参数名称为arg0、arg1等是因为Java默认使用参数名称来引用参数。如果没有在编译时使用特定的标志,则编译器会将参数名称设置为arg0,arg1等。解决此问题的方法之一是在编译时使用 -parameters 标志。这将告诉编译器将参数名称编译到字节码中。例如,在使用Maven构建项目时,可以在pom.xml文件中添加以下插件配置:


    
        
            org.apache.maven.plugins
            maven-compiler-plugin
            
                1.8
                1.8
                
                    -parameters
                
            
        
    

这将强制编译器将参数名称编译到字节码中,从而可以在运行时访问它们。

如果您使用的是JAX-WS或JAX-RPC等旧的Web服务框架,则可能会遇到此问题。这是由于这些框架使用参数的位置而不是参数的名称来识别参数。

要解决此问题,您可以使用更现代的Web服务框架,例如JAX-RS或Spring Web Services,它们支持使用参数名称而不是位置来识别参数。您还可以尝试使用一些库(例如Apache Axis)来启用参数名称支持。

如果您无法更改Web服务框架或使用库,则可以通过在Web服务方法上添加注释来手动指定参数名称。例如,在JAX-WS中,您可以使用@WebParam注释来指定参数名称,如下所示:

public String myWebServiceMethod(@WebParam(name = "myParameter") String myParameter) {
    // ...
}

这将使参数名称为“myParameter”,而不是默认名称“arg0”。

你可能感兴趣的:(#,IOC_MVC,前端,-parameters,compilerArgs,token,登录已过期,token已过期,java)