由于我们的api接口是通过参数名称与json对象属性名绑定的,类似这样:
调用时传递json对象:
因此参数名称很重要。
原本以为通过-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()];
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。