由于我们的api接口是通过参数名称与json对象属性名绑定的,类似这样:
image.png

调用时传递json对象:
image.png

因此参数名称很重要。

原本以为通过-parameters参数可以在编译时保留参数,但因为使用混淆工具后,参数名称变了,还是导致参数绑定失败。而且我们用的混淆工具也不支持保留参数名。

原本jdk1.8的情况下,由于Spring框架内部有兼容机制(见后述),也是可以兼容的。但升级到jdk17的Spring 6.x版本之后,这个兼容机制没有了。

这个问题困扰了很久,经过研究最终发现是用于Spring废除了一个参数名获取机制所致。

Spring5.x在普通情况下,Spring通过反射机制获取api方法的参数名称,使用的是这个类来实现:org.springframework.core.StandardReflectionParameterNameDiscoverer。
混淆之后,由于StandardReflectionParameterNameDiscoverer获取失败,会再用
org.springframework.core.LocalVariableTableParameterNameDiscoverer这个类来获取参数名。

而Spring 6.x直接废除了LocalVariableTableParameterNameDiscoverer这个类来这个类,导致无法获取参数名。
https://github.com/spring-projects/spring-framework/issues/29559

所以解决方案就是,把5.x的LocalVariableTableParameterNameDiscoverer类的代码放到项目中,然后用它来获取参数名:

    private static LocalVariableTableParameterNameDiscoverer localDiscover = new LocalVariableTableParameterNameDiscoverer();

String paramName = anno.value();
        if (StringUtils.isEmpty(paramName)) {
            String[] names = localDiscover.getParameterNames(methodParameter.getMethod());
            if (names != null) paramName = names[methodParameter.getParameterIndex()];
        }

okfine
512 声望29 粉丝

A front-end enthusiast!