# 背景
测试那边转过来一个问题单,开发这边初步定位是 struts 框架接收集合参数只能接收到 256 个
# 定位
# google 一下
先直接 google 了一下,感觉回答有点偏,说是 struts2.5.15 升级到 2.5.30 就会有这个问题,是 struts 改用 ArrayList 的 TypeConverter, 我自己去代码里面看根本咩有限制
public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) {
Collection result;
Class memberType = String.class;
if (target != null) {
memberType = objectTypeDeterminer.getElementClass(target.getClass(), propertyName, null);
if (memberType == null) {
memberType = String.class;
}
}
if (toType.isAssignableFrom(value.getClass())) {
// no need to do anything
result = (Collection) value;
} else if (value.getClass().isArray()) {
Object[] objArray = (Object[]) value;
TypeConverter converter = getTypeConverter(context);
result = createCollection(toType, memberType, objArray.length);
for (Object anObjArray : objArray) {
Object convertedValue = converter.convertValue(context, target, member, propertyName, anObjArray, memberType);
if (!TypeConverter.NO_CONVERSION_POSSIBLE.equals(convertedValue)) {
result.add(convertedValue);
}
}
} else if (Collection.class.isAssignableFrom(value.getClass())) {
Collection col = (Collection) value;
TypeConverter converter = getTypeConverter(context);
result = createCollection(toType, memberType, col.size());
for (Object aCol : col) {
Object convertedValue = converter.convertValue(context, target, member, propertyName, aCol, memberType);
if (!TypeConverter.NO_CONVERSION_POSSIBLE.equals(convertedValue)) {
result.add(convertedValue);
}
}
} else {
result = createCollection(toType, memberType, -1);
TypeConverter converter = getTypeConverter(context);
Object convertedValue = converter.convertValue(context, target, member, propertyName, value, memberType);
if (!TypeConverter.NO_CONVERSION_POSSIBLE.equals(convertedValue)) {
result.add(convertedValue);
}
}
return result;
}
# struts.ognl.expressionMaxLength
这时候就这专门去 clone 了一下 struts 的仓库
先切换到 2.5.33 版本,然后曲剧检索了一下 256, 还真让找到了一处配置
但是被注释掉了,翻译过来,不配置的话,就不会被限制,实际情况,本来就没有设置这个参数,应该和在这个配置没有关系,而且实际给的参数列表超过了 256, 这个参数是接收 OGNL 的个数,我们出现的问题是 OGNL 集合参数被限制在 256 以内,
# struts.ognl.autoGrowthCollectionLimit
无奈,只得继续看提交记录,好在提交记录 并不是很多,看着看着,又发现了一处
public Object getProperty(Map context, Object target, Object name) throws OgnlException {
if (ReflectionContextState.isGettingByKeyProperty(context)
|| name.equals(XWorkCollectionPropertyAccessor.KEY_PROPERTY_FOR_CREATION)) {
return _sAcc.getProperty(context, target, name);
} else if (name instanceof String) {
return super.getProperty(context, target, name);
}
ReflectionContextState.updateCurrentPropertyPath(context, name);
Class lastClass = (Class) context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);
String lastProperty = (String) context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
if (name instanceof Number
&& ReflectionContextState.isCreatingNullObjects(context)
&& objectTypeDeterminer.shouldCreateIfNew(lastClass,lastProperty,target,null,true)) {
List list = (List) target;
int index = ((Number) name).intValue();
int listSize = list.size();
if (lastClass == null || lastProperty == null) {
return super.getProperty(context, target, name);
}
Class beanClass = objectTypeDeterminer.getElementClass(lastClass, lastProperty, name);
if (listSize <= index) {
Object result;
if (index > autoGrowCollectionLimit) {
throw new OgnlException("Error auto growing collection size to " + index + " which limited to "
+ autoGrowCollectionLimit);
}
for (int i = listSize; i < index; i++) {
list.add(null);
}
try {
list.add(index, result = objectFactory.buildBean(beanClass, context));
} catch (Exception exc) {
throw new XWorkException(exc);
}
return result;
} else if (list.get(index) == null) {
Object result;
try {
list.set(index, result = objectFactory.buildBean(beanClass, context));
} catch (Exception exc) {
throw new XWorkException(exc);
}
return result;
}
}
return super.getProperty(context, target, name);
}
早知道就一起检索 255 了,还看了这么多提交记录,这次直接到 struts 的配置里面加上,测试了一下,果然可以
# 吐槽
struts 真的可以,增加了 default 配置,也不写到版本更新里面去,还得自己来看源码才能知道
# 推想
struts.ognl.expressionMaxLength 这个配置,看了一下他们的 issue, 还是感觉挺好笑的,2.5.21 加上后,2.5.22 又给注释掉,实际外发的版本 2.5.21 都没了,
struts.ognl.expressionMaxLength 讨论