【发布时间】:2015-06-25 08:14:49
【问题描述】:
我有一个 struts 2 动作类:
public class MyAction{
private ArrayList<User> users;
public void setUsers(ArrayList<User> users){
this.users = users;
}
public String doMyAction(){
//...
}
}
doMyAction方法有一个AOP切入点,所以MyAction在运行时实际上是一个cglib代理类,当启用aop时,users字段将由客户端的json数据填充, struts JSONInterceptor 将无法将 json 数据填充到 users 字段中。我用struts json插件的源代码调试,在org.apache.struts2.json.JSONPopulator中找到了这个:
public void populateObject(Object object, final Map elements)
throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException, IntrospectionException,
IllegalArgumentException, JSONException, InstantiationException {
Class clazz = object.getClass();
BeanInfo info = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] props = info.getPropertyDescriptors();
// iterate over class fields
for (int i = 0; i < props.length; ++i) {
PropertyDescriptor prop = props[i];
String name = prop.getName();
if (elements.containsKey(name)) {
Object value = elements.get(name);
Method method = prop.getWriteMethod();
if (method != null) {
JSON json = method.getAnnotation(JSON.class);
if ((json != null) && !json.deserialize()) {
continue;
}
// use only public setters
if (Modifier.isPublic(method.getModifiers())) {
Class[] paramTypes = method.getParameterTypes();
Type[] genericTypes = method.getGenericParameterTypes();
if (paramTypes.length == 1) {
Object convertedValue = this.convert(paramTypes[0],
genericTypes[0], value, method);
method.invoke(object, new Object[] { convertedValue });
}
}
}
}
}
}
在这一行:
Type[] genericTypes = method.getGenericParameterTypes();
当启用 AOP 时,它会针对 users 字段的 setter 方法返回 java.util.ArrayList。但应该是java.util.ArrayList<User>。
似乎我的动作类在被 cglib 代理时丢失了它的通用信息。我还找到了a old bug 关于这个。
我可以从 aop 配置中排除我的方法来解决这个问题。但我还是想知道有没有更好的解决方案?
【问题讨论】:
标签: java json spring struts2 cglib