看了之前 jfinal 实现添加@JsonBody自动注入json数据 的分享,想在这里提个小建议:
现有的实现里面,对于Action的参数的注入,如果内容不是form-urlencoded的兼容的,比如application/json,application/xml,甚至是Protobuf/Hessian/私有协议等,如果没有泛型,那么通过覆盖controller的getBean/getModel方法可以完美实现,但如果入参有泛型信息,就不好处理了,如果作为移动/IOT应用的后端,使用json/Protobuf等协议,并且带如下泛型信息的入参类型是非常常见的:
public class Req<T> {
// 公共入参
private String sig;
private String token;
private T payload;
// ....
}
Controller里action的入参:
public class HelloController extends MyBaseController {
public void hello(Req<Hello> req) {
// ...
}
}
由于现有的(jfinal 4.8版本或更早)实现里,getBean/getModel的入参Class<T>实际上是没有带上运行时泛型信息的,如果在MyBaseController里覆盖getBean/getModel方法,那么Hello这个泛型信息就拿不到了,没法通用的创建Req<Hello>的实例了,只能创建Req<Object>,所以处理起来就没那么方便了,如果放弃覆盖getBean/getModel,通过Interceptor也可以实现功能,但浪费了Bean/ModelGetter创建的实例.
所以如果可能,是不是可以作以下修改呢?
BeanGetter/ModelGetter这两个类,modelClass的类型声明为Type,controller的getBean/getModel的入参Class<T>也修改为Type,ParaProcessorBuilder类的101行
Class<?> typeClass = p.getType();
修改为
Type typeClass = p.getParameterizedType();
由于Class实现了Type接口,所以这个改动影响非常少(现有的其他代码不需要任何修改),并且,如果没有泛型信息时,p.getParameterizedType的返回跟getType返回是一样的(参考java.lang.reflect.Executable源码),实际使用modelClass的时候也可以通过转型得到原有的Class<T>.
这样就更通用,使用JFinal时代码也列简洁了.
最重要的是不能对现有代码有影响,由于 jfinal 已迭代发展八年多,有大量的用户,大量的项目需要照顾到升级、兼容
谢谢反馈