使用Feign来调用get请求时,如果传参是一个类对象,框架就需要把这个类对象解析成query参数。但是直接在方法中写传参框架不会自动把类对象解析成query参数。此时就需要在类对象前加一个注解@SpringQueryMap,此注解的作用就是把pojo解析成k=v&k=v的query参数格式。
public class Teacher {
private String teacherId;
/** getter and setter **/
}
@GetMapping(value = "/feign/upload")
Result uploadVideoAuth(@SpringQueryMap Teacher techer);
运行一下,完全没问题。
但是如果Teacher继承了一个User类
public class User {
private String name;
/** getter and setter **/
}
public class Teacher extends User {
private String teacherId;
/** getter and setter **/
}
再运行一下,然后发现teacherId解析过来类,但是name没有解析过来。
很明显,父类的属性不会解析成query形式的参数,为什么不会呢?带着这个问题翻阅类解析源码的解析过程,那么我们先来简单的贴上源码。
package feign.querymap;
public class FieldQueryMapEncoder implements QueryMapEncoder {
/** 其他源码省略,直接看重要的 **/
//这个是内部类
private static class ObjectParamMetadata {
//这里的传参就是Teacher的Class类
private static ObjectParamMetadata parseObjectType(Class type) {
List fields =new ArrayList();
//这里直接获取Teacher的参数,并没有去拿父类User的参数
for (Field field : type.getDeclaredFields()) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
fields.add(field);
}
return new ObjectParamMetadata(fields);
}
}
}
package feign.querymap;
public class BeanQueryMapEncoder implements QueryMapEncoder {
/** 其他源码省略,直接看重要的 **/
//这个是内部类
private static class ObjectParamMetadata {
//这里的传参就是Teacher的Class类
private static ObjectParamMetadata parseObjectType(Class type) {
List properties =new ArrayList();
//这里调用java.bean中的userInfo去获取到PropertyDescriptors,再通过PropertyDescriptors获取属性的值
for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
boolean isGetterMethod = pd.getReadMethod() !=null && !"class".equals(pd.getName());
if (isGetterMethod) {
properties.add(pd);
}
}
return new ObjectParamMetadata(properties);
}
}
}
框架默认FieldQueryMapEncoder类去解析而不是BeanQueryMapEncoder去解析,所以Teacher类的父类User是解析不到,而BeanQueryMapEncoder是通过java.bean的获取类信息和字段信息去解析的,其实PropertyDescriptors在很多框架中会用到,比如JdbcTemplate中的pojo和数据库的字段映射。
解决方案就是
https://blog.csdn.net/li295214001/article/details/90410945
懒得再写了,就直接拿过来了。