我有一个实现ModelDriven接口的动作类。这个ModelDriven是一个普通的POJO,问题在于它的属性之一是另一个对象。
想象一下,我的ModelDriven是一个名为Person的对象,而我的个人有一个名为Address的属性,它是另一个对象。地址具有常规属性,例如字符串,长整数等。
在JSP提交表单时,在所有使用的常规属性(例如String,int,long in Person)中均已正确映射,但所有应映射到address的数据均未正确映射。
<s:textfield name="name" id="name" size="25" maxlength="15" /> <s:textfield name="address.zipcode" id="zipcode" size="25" maxlength="15" />
这就是我尝试映射属性的方式。我可以正确使用name属性,但是在人的住所中映射属性时,这种方法不起作用。
我究竟做错了什么?
及时地,我的Address属性在实例化对象的Person中声明,因此它永远不会为null。
编辑: 根据要求,此处是操作源和DTO:
那个行动:
@Controller @Scope("request") public class AnAction extends BaseAction implements ModelDriven<FakeDTO> { private static final long serialVersionUID = 8238033889271514835L; @Autowired private FakeFacade facade; private FakeDTO fakeDTO = new FakeDTO(); public String action01() { return Action.SUCCESS; } public String action02() { this.fakeDTO.setAnswer(this.fakeFacade.fakeFacadeMethod(this.fakeDTO.getComplexObject())); return Action.SUCCESS; } @Override public FakeDTO getModel() { return this.fakeDTO; } }
主要DTO:
public class FakeDTO implements BaseDTO { private static final long serialVersionUID = -2093038083351846003L; private FakeFilterDTO filter = new FakeFilterDTO(); private String name; public FakeDTO() { super(); } @Override public FakeFilterDTO getFilter() { return this.filter; } public void setFilter(final FakeFilterDTO filterParam) { this.filter = filterParam; } public String getName() { return this.name; } public String setName(final String nameParam) { this.name = nameParam; } }
FakeFilterDTO:
public class FakeFilterDTO extends BaseFilterDTO { private static final long serialVersionUID = 4528040257605851210L; private Date aDate; private Long aLong; private Integer anInteger; private String aString; public Date getADate() { return this.aDate; } public void setDataInicial(final Date aDateParam) { this.aDate = aDateParam; } public Long getALong() { return this.aLong; } public void setALong(final Long aLongParam) { this.aLong = aLongParam; } public Integer getAnInteger() { return this.anInteger; } public void setAnInteger(final Integer anIntegerParam) { this.anInteger = anIntegerParam; } public String getAString() { return this.aString; } public void setAString(final String aStringParam) { this.aString = aStringParam; } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <include file="META-INF/bsad/struts2/struts-config.xml" /> <package name="reports" namespace="/reports" extends="project-default"> <action name="anAction" class="anAction" method="action01"> <result>/WEB-INF/pages/success.jsp</result> <result name="input">/WEB-INF/pages/input.jsp</result> </action> <action name="generateReport" class="anAction" method="action02"> <result>/WEB-INF/pages/reportGenerated.jsp</result> </action> </package> </struts>
项目默认值放置在include struts-config.xml中,并扩展了包含ModelDrivenInterceptor的struts- default包。我可以保证,因为我在该拦截器中放置了一个断点,并且该截断点通过了它。
我之前用作示例的JSP如下所示:
<s:textfield name="name" id="name" size="25" maxlength="15" /> <s:textfield name="filter.aString" id="zipcode" size="25" maxlength="15" />
对于公司政策,我不允许复制/粘贴实际的对象及其名称。但这就是想法。
在fakeDTO那是您的模型中,您应该有一个属性address,该属性应该返回一个对象,就像AddressDTO在该对象中应该有一个属性zipcode。
fakeDTO
address
AddressDTO
zipcode
public class FakeDTO implements BaseDTO { private AddressDTO address; public AddressDTO getAddress() { return address; } public void setAddress (AddressDTO address) { this.address = address; } ... } public class AddressDTO implements BaseDTO { private String zipcode; public String getZipcode() { return zipcode; } public void setZipcode(String zipcode) { this.zipcode = zipcode; } ... }
由于您尚未发布struts.xml操作配置,因此应该包含modelDriven拦截器,defaultStack默认情况下,扩展struts- default包中将使用该拦截器。请参见模型驱动的示例。该模型推到top的valueStack被拦截,让喜欢的对象address应可如果它有一个 默认的构造函数 将被OGNL创建和zipcode设置在那里。当您在JSP中显示字段时,它将address.zipcode被评估为OGNL表达式,zipcode如果模型已初始化,则从地址bean 检索该bean和邮政编码本身。OGNL表达式中引用的所有bean应该被初始化并具有getter / setter属性。
modelDriven
defaultStack
struts- default
top
valueStack
address.zipcode