把项目中的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