I have an action class that implements ModelDriven interface. This ModelDriven is a regular POJO, the problem is that one of its properties is another object.
Imagine that my ModelDriven is a object called Person and my person has an attribute called Address that is another object. Address has regular properties such as String, Long and etc.
In the JSP when I submit the form, all the regular properties used such as String, int, long in Person are mapped correctly, but all the data that should be mapped to address are not.
<s:textfield name="name" id="name" size="25" maxlength="15" />
<s:textfield name="address.zipcode" id="zipcode" size="25" maxlength="15" />
That's how I try mapping the properties. The name property I can get it right, but when it comes to map the properties in the person's address this approach does not work.
What am I doing wrong?
In time, my Address property is declared in Person instantiating the object, so it's never null.
EDIT: As requested, here the action source and the DTOs:
The Action:
@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;
}
}
The main 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;
}
}
The 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;
}
}
The 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>
The project-default is placed in the include struts-config.xml and extends struts-default package that contains the ModelDrivenInterceptor. I can assure that because I placed a break point in this interceptor and its passing through there.
The JSP that I used as an example before would become as follows:
<s:textfield name="name" id="name" size="25" maxlength="15" />
<s:textfield name="filter.aString" id="zipcode" size="25" maxlength="15" />
For company policies I'm not allowed to copy/paste the actual Objects and its names. But that's the idea.