解决使用Struts2的s:textfield标签出现Unable to find setter method for attribute: style的问题

时间:2023-01-29 12:32:49

把项目中的struts2从2.3.1.2升级到2.3.20,跑起来之后出现一个这样的问题:

org.apache.jasper.JasperException: /pages/login.jsp (line: 103, column: 7) Unable to find setter method for attribute: style

错误消息很明显:没有style的setter方法,但是很诡异,jsp中哪有什么setter方法,定位到代码一看,是s:textfield中的style属性:

<s:textfield label="用户ID" name="model.userid" id="userid" required="true" class="{character:true}" style="width:220px; height:30px; margin-left:10px;" />

谷歌下,发现是Struts2 2.3.20的一个bug,org.apache.struts2.views.jsp.ui.AbstractUITagBeanInfo中没有对style属性进行解析处理:

public class AbstractUITagBeanInfo extends SimpleBeanInfo {

private static final Logger LOG = LoggerFactory.getLogger(AbstractUITagBeanInfo.class);

@Override
public PropertyDescriptor[] getPropertyDescriptors() {
try {
List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>();

// Add the tricky one first
Method setter = AbstractUITag.class.getMethod("setCssClass", String.class);
descriptors.add(new PropertyDescriptor("class", null, setter));
descriptors.add(new PropertyDescriptor("cssClass", null, setter));

for (Field field : AbstractUITag.class.getDeclaredFields()) {
String fieldName = field.getName();
if (!"dynamicAttributes".equals(fieldName)) {
String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
setter = AbstractUITag.class.getMethod(setterName, String.class);
descriptors.add(new PropertyDescriptor(fieldName, null, setter));
}
}

PropertyDescriptor[] array = new PropertyDescriptor[descriptors.size()];
return descriptors.toArray(array);
} catch (Exception e) {
// This is crazy talk, we're only doing things that should always succeed
LOG.fatal("Could not construct bean info for AbstractUITag. This is very bad.", e);
return null;
}
}

}

目前已经在2.3.21中已经修复了:

public class AbstractUITagBeanInfo extends SimpleBeanInfo {

private static final Logger LOG = LoggerFactory.getLogger(AbstractUITagBeanInfo.class);

@Override
public PropertyDescriptor[] getPropertyDescriptors() {
try {
List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>();

// Add the tricky one first
Method classSetter = AbstractUITag.class.getMethod("setCssClass", String.class);
Method styleSetter = AbstractUITag.class.getMethod("setCssStyle", String.class);

descriptors.add(new PropertyDescriptor("class", null, classSetter));
descriptors.add(new PropertyDescriptor("cssClass", null, classSetter));

descriptors.add(new PropertyDescriptor("style", null, styleSetter));
descriptors.add(new PropertyDescriptor("cssStyle", null, styleSetter));

for (Field field : AbstractUITag.class.getDeclaredFields()) {
String fieldName = field.getName();
if (!"dynamicAttributes".equals(fieldName)) {
String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Method setter = AbstractUITag.class.getMethod(setterName, String.class);
descriptors.add(new PropertyDescriptor(fieldName, null, setter));
}
}

PropertyDescriptor[] array = new PropertyDescriptor[descriptors.size()];
return descriptors.toArray(array);
} catch (Exception e) {
// This is crazy talk, we're only doing things that should always succeed
LOG.fatal("Could not construct bean info for AbstractUITag. This is very bad.", e);
return null;
}
}

}

jira:https://fisheye6.atlassian.com/browse/struts/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITagBeanInfo.java?r1=587e3a41b1d306eb246aa39d71dce469f4e50e9d&r2=4964b74797971751bedad0ba0982f53ef0934a2c