How to control XML Serialization behavior on xsi:nill= - xml-serialization

I'm working on a Webservice to share data between 2 ERP-systems. First ERP calls the webservice, which serializes the data-object and sends it to the second ERP.
A data object looks like this:
<xs:complexType name="Parent">
<xs:sequence>
<xs:element ref="ta:ReceiptLine" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Child">
<xs:sequence>
...
<xs:element name="SerialNo" type="xs:string" nillable="true" minOccurs="0"/>
<xs:element name="Quantity" type="xs:int" nillable="false"/>
...
</xs:sequence>
</xs:complexType>
...
<xs:element name="Child" type="ta:Child" nillable="true"/>
The classes generated by XSD:
[System.Serializable]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://FSM4TA/DataObjects/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://FSM4TA/DataObjects/", IsNullable=false)]
public partial class Parent {
private Child[] child;
[System.Xml.Serialization.XmlElementAttribute("Child", IsNullable=true)]
public Child[] Child {
get {return this.child;}
set {this.child = value;}
}
[System.Serializable]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://FSM4TA/DataObjects/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://FSM4TA/DataObjects/", IsNullable=true)]
public partial class Child{
private string serialNo;
private int quantity;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string SerialNo {
get {return this.serialNo;}
set {this.serialNo = value;}
}
public int Quantity {
get { return this.quantity;}
set {this.quantity = value;}
}
}
I'm serializing my data objects with XmlSerializer
The Problem Is: (On serialization) Every time in case of the Child object is empty (xsi:nil="true") XSD generates the whole Child structure anyway. And because Quantity is not nillable/nullable XSD writes 0 as value... Like this:
<Parent>
<Child xsi:nil="true">
<SerialNo xsi:nil="true" />
<Quantity>0</Quantity>
</Child>
</Parent>
I expected to get something like this:
<Parent>
</Child xsi:nil="true">
</Parent>
The Question Is: Is there a way to prevent XSD from parsing an xsi:nil="true"-Object ??
Any suggestions?
TIA

ok,
I got it now!
You have to mark the Quantity property with the XmlElementAttribute explicitly!
[XmlElement(IsNullable=false)]
public int Quantity {
get { return this.quantity;}
set {this.quantity = value;}
}
No idea why this hasn't been generated automatically...

Related

Is it possible to extract the original message body string (i.e., XML string or JSON string) within the "post()" method of a REST service?

QUESTION:
Is it possible to extract the original message body string (i.e., XML string or JSON string) - within the "post()" method - of a REST service?
Environment
Java 8
WebLogic 12.1.3 (w/ jax-rs(2.0,2.5.1) deployable library)
(The "request.getInputStream()" yields nothing... Seems that "read()" has already been applied "internally". Also, "mark()" or "reset()" is not supported)
"post()" method...
package aaa.bbb.ccc;
import javax.ejb.Stateless;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import aaa.bbb.ccc.fieldslist.FieldsList;
import java.io.*;
import java.net.URI;
import javax.ws.rs.core.*;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
#Stateless
#Path("/fieldsList")
public class Testws {
private static final Logger LOG = LogManager.getLogger(Testws.class);
public Testws() {
}
#POST
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response post(#Context UriInfo uriInfo, #Context javax.servlet.http.HttpServletRequest request, FieldsList fieldsList) throws IOException, JAXBException, Exception {
try {
//...returns empty string...
String s = IOUtils.toString(request.getInputStream(), "UTF-8");
LOG.info("message string from request.getInputStream()=" + s); <== empty string...
} catch (Exception e) {
e.printStackTrace();
}
URI uri = UriBuilder.fromUri(uriInfo.getRequestUri()).build();
Response response = Response.created(uri).build();
return response;
}
}
I've tried using an interceptor (see "aroundReadFrom()" method) to manipulate the InputStream before it is used by the post() method, but, to no effect...
-That is, in the REST service's post() method, the request.getInputStream() continues to yield nothing...
"aroundReadFrom()" method...
package aaa.bbb.ccc;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
#Provider
public class MyReaderInterceptor implements ReaderInterceptor {
static final Logger LOG = LogManager.getLogger(MyReaderInterceptor.class);
#Override
public Object aroundReadFrom(ReaderInterceptorContext ctx) throws IOException {
try {
InputStream is = ctx.getInputStream();
byte[] content = IOUtils.toByteArray(is);
is.close();
ctx.setInputStream(new ByteArrayInputStream(content));
return ctx.proceed();
} catch (IOException | WebApplicationException e) {
e.printStackTrace();
}
return null;
}
}
Here is the test xml message...:
<?xml version="1.0" encoding="UTF-8"?>
<FieldsList xmlns="http://aaa.bbb.ccc.ws/testws">
<Fields>
<FieldA>fieldA_value</FieldA>
<FieldB>fieldB_value</FieldB>
<FieldC>fieldC_value</FieldC>
</Fields>
</FieldsList>
Here is the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
targetNamespace="http://aaa.bbb.ccc.ws/testws"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:tw="http://aaa.bbb.ccc.ws/testws"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="FieldsType">
<xs:all>
<xs:element name="FieldA" type="xs:string" minOccurs="0" />
<xs:element name="FieldB" type="xs:string" minOccurs="0" />
<xs:element name="FieldC" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
<xs:element name="FieldsList">
<xs:complexType>
<xs:sequence>
<xs:element name="Fields" type="tw:FieldsType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
UPDATE:
Within the post() method I've only been able to reconstruct message string using this technique...
StringWriter sw = new StringWriter();
JAXBContext.newInstance(FieldsList.class).createMarshaller().marshal(fieldsList, sw);
System.out.println("posted xml string=" + sw.toString());
...However, this would not help if the same data is posted in JSON format. To clarify, it will reconstruct the JSON post message as an XML string rather than the original JSON string
Again, I what I'm trying to do is access the original posted XML/JSON message string within the post() method
Solution using Request Attribute - Tested work 100%
#Provider
public class ContainerRequestFilterImpl implements ContainerRequestFilter {
#Context
private HttpServletRequest request;
#Override
public void filter(ContainerRequestContext ctx) throws IOException {
InputStream is = ctx.getEntityStream();
byte[] content = IOUtils.toByteArray(is);
// Store content as Request Attribute
request.setAttribute("content", new String(content, "UTF-8"));
ctx.setEntityStream(new ByteArrayInputStream(content));
}
}
AND
#POST
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response post(#Context UriInfo uriInfo, #Context HttpServletRequest request, FieldsList fieldsList) throws IOException, JAXBException, Exception {
try {
String s = request.getAttribute("postContent");
LOG.info("Post content: " + s);
} catch (Exception e) {
e.printStackTrace();
}
}
I think you can use ReaderInterceptor instead of ContainerRequestFilter. It should work too.
You can just use a ReaderInterceptor. This is where you can get the raw data. You basically need to get the InputStream from the ReaderInterceptorContext, read it, then you need to set the new InputStream, since the original InputStream can only be read once. So you need to use some buffering strategy when reading the original stream
#Override
public Object aroundReadFrom(ReaderInterceptorContext context) {
InputStream ogStream = context.getInputStream();
// readStream with some buffer
// set new stream
context.setInputStream(bufferedStream);
return context.proceed();
}
See Also:
Filters and Interceptors
JAX-RS 2 print JSON request. This example is used for client side, but it can easily be refactored to use the server side filters (i.e. Container(Request|Response)Filter.

Error in XML Schema Validation

I have a particular Java class like
public class JavaClass implements Serializable{
private static final long serialVersionUID = 1L;
private ElementC ElementC = null;
private ArrayList<ElementA> elementA = new ArrayList<ElementA>();
private ArrayList<ElementB> elementB = new ArrayList<ElementB>();
and an XSD generated along with WSDL for the particular class, something like below.
(XSD File)
<xs:complexType name="JavaClass">
<xs:sequence>
<xs:element name="ElementA" type="tns:elementA" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="ElementB" type="tns:elementB" nillable="true" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="ElementC" type="xs:string" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
Below is the chunk of Java code am using for schema validation.
When I debug to peek in the parse exception thrown, The message says
One of '{elementA, elementB}' is expected. (I suppose the problem is in SAXParseException.)
public void warning(SAXParseException e) throws SAXException {
//System.out.println("In Warning() of SchemaErrorHandler");
// Store warnings in the packet so that they can be retrieved from the endpoint
packet.invocationProperties.put("WARNING", e);
}
public void error(SAXParseException e) throws SAXException
{
count++;
String error = e.getMessage();
if(error.contains("cvc-enumeration-valid")){
StringTokenizer st = new StringTokenizer(error,"[");
st.nextElement();
StringTokenizer st2 = new StringTokenizer(st.nextElement().toString(),"]");
exceptionTypeDetails = (String) st2.nextElement();
Now when I trigger a SOAP request without ElementB(Mandatory) the SOAP throws an error saying "ElementA was not found, Excepted ElementA"(Even though ElementA is non Mandatory).
Please halp how can I debug the issue. Let me know incase of futher clarrifications needed on this question.

CXF client don't work with ArrayOfType Axis service

I have this bean:
public class ListFrameTO implements Serializable
{
private FrameTO[] frameTOs=null;
public ListFrameTO() {
}
public FrameTO[] getFrameTOs() {
return frameTOs;
}
public void setFrameTOs(FrameTO[] frameTOs) {
this.frameTOs = frameTOs;
}
}
axis converts it in:
<complexType name="ListFrameTO">
<complexContent>
<extension base="tns2:TransferObject">
<sequence>
<element name="frameTOs" nillable="true" type="impl:ArrayOf_tns2_FrameTO"/>
</sequence>
</extension>
</complexContent>
and
<complexType name="ArrayOf_tns2_FrameTO">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="tns2:FrameTO"/>
</sequence>
</complexType>
CXF client caused:
javax.xml.bind.UnmarshalException: unexpected element (uri:"xxx", local:"frameTOs"). Expected elements are <{xxx}item>
I need to convert ArrayOf_tns2_FrameTO in FrameTO[] in cfx client bean.
I don't use any custom binding file.

Large MIME attachment & SOAP

I have simple web service server which receive SOAP with MIME attachment, store it to the HashMap and send back message with this mime attachment:
Java 1.7.0_13-b20
Spring WS 2.1.3
MOXy implementation of JAXB (EclipseLink 2.4.1)
Glassfish 3.1.1
MIME attachment & SOAP
enabled SAAJ MimePull to save to the hard drive
based on Enabling large file transfers through SOAP with Spring WS, MTOM/XOP and JAXB2 and Spring WS "mtom" sample
tested by SoapUI
If I send Request with small attachment (<80MB) everything is OK but when I send Request with >80 MB attachment the DataHandler object is null. So it is not parsed from Request and not stored to the HashMap. Does not matter if I have enabled mimepull, if yes the large attachment is stored to the temporary folder on hard drive.
Enabled MimePull:
-Dsaaj.use.mimepull=true
-Djava.io.tmpdir=/path/to/tmpdir
Enlarged GlassFish Thread Pools:
"Max Thread Pool Size" from 5 to 32
"Min Thread Pool Size" from 2 to 16
ImageRequest.java
package sample.mtom.schema;
#XmlRootElement
#XmlType(propOrder = {"fileName", "data"})
public class ImageRequest {
protected String fileName;
protected DataHandler data;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
#XmlMimeType("*/*")
public DataHandler getData() {
return data;
}
public void setData(DataHandler data) {
this.data = data;
}
}
ImageResponse.java
package sample.mtom.schema;
#XmlRootElement
#XmlType(propOrder = {"fileName", "data"})
public class ImageResponse {
// the same as ImageRequest
}
package-info.java
#XmlSchema(namespace = "http://www.example.org/Image",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package sample.mtom.schema;
import javax.xml.bind.annotation.XmlSchema;
StubRepository.java
package sample.mtom.service;
public class StubRepository implements Repository {
private Map<String, DataHandler> files = new HashMap();
public DataHandler readFile(String name) throws IOException {
return files.get(name);
}
public void storeFile(String name, DataHandler file) throws IOException {
files.put(name, file);
}
}
ImageRepositoryEndpoint.java
package sample.mtom.ws;
#Endpoint
public class ImageRepositoryEndpoint {
private static Repository repository;
static {
repository = new StubRepository();
}
#PayloadRoot(localPart = "imageRequest", namespace = "http://www.example.org/Image")
#ResponsePayload
public ImageResponse handleRequest(#RequestPayload ImageRequest request) throws IOException {
repository.storeFile(request.getFileName(), request.getData());
ImageResponse response = new ImageResponse();
response.setFileName(request.getFileName());
response.setData(repository.readFile(request.getFileName()));
return response;
}
}
schema.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
targetNamespace="http://www.example.org/Image"
elementFormDefault="qualified">
<xsd:element name="imageRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="fileName" type="xsd:string"/>
<xsd:element name="data" type="xsd:base64Binary" xmime:expectedContentTypes="*/*"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="imageResponse">
<!-- the same as imageRequest -->
</xsd:element>
</xsd:schema>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>MyCompany HR Holiday Service</display-name>
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
spring-ws-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="sample.mtom.ws"/>
<bean id="defaultMethodEndpointAdapter"
class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
<property name="methodArgumentResolvers" ref="marshallingPayloadMethodProcessor"/>
<property name="methodReturnValueHandlers" ref="marshallingPayloadMethodProcessor"/>
</bean>
<bean id="marshallingPayloadMethodProcessor"
class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
<constructor-arg ref="jaxb2Marshaller"/>
</bean>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan" value="sample.mtom.schema"/>
<property name="mtomEnabled" value="true"/>
</bean>
<sws:dynamic-wsdl id="image"
portTypeName="ImageResource"
locationUri="/">
<sws:xsd location="/WEB-INF/schema.xsd"/>
</sws:dynamic-wsdl>
</beans>

Unable to instantiate Action, signupFormAction, defined for 'signupForm' in namespace '/'signupFormAction. ClassNotFoundException: signupFormAction

Been trying to setup a Struts2 + Sprint + Hibernate basic framework and was working on creating a sample application. Everything configured and the stack doesnt through any error/exception while starting tomcat. Even when I run the action it doesnt throw any Exception, but on the browser it throws the following stack
Unable to instantiate Action, signupFormAction, defined for 'signupForm' in namespace '/'signupFormAction
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:318)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:399)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:198)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:475)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
root cause
java.lang.ClassNotFoundException: signupFormAction
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
com.opensymphony.xwork2.util.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:157)
com.opensymphony.xwork2.ObjectFactory.getClassInstance(ObjectFactory.java:107)
com.opensymphony.xwork2.spring.SpringObjectFactory.getClassInstance(SpringObjectFactory.java:223)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:143)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:150)
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:120)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:299)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:399)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:198)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:475)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
My struts.xml
<struts>
<!-- <constant name="struts.enable.DynamicMethodInvocation" value="false" />-->
<constant name="struts.devMode" value="false" />
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<package name="default" extends="struts-default" namespace="/">
<action name="login" class="loginAction">
<result name="success">welcome.jsp</result>
<result name="error">login.jsp</result>
</action>
<action name="signup" class="registerAction" method="add">
<result name="success">welcome.jsp</result>
<result name="error">login.jsp</result>
</action>
<action name="signupForm" class="signupFormAction">
<result name="input">registerForm.jsp</result>
<result name="error">login.jsp</result>
</action>
</package>
</struts>
My SpringBeans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- Database Configuration -->
<import resource="config/spring/DataSource.xml" />
<import resource="config/spring/HibernateSessionFactory.xml" />
<!-- Beans Declaration -->
<import resource="com/srisris/khiraya/spring/register.xml" />
<import resource="com/srisris/khiraya/spring/login.xml" />
</beans>
My register.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- <bean id="ownerService" class="com.srisris.khiraya.service.OwnerServiceImpl">-->
<!-- <property name="ownerDAO" ref="ownerDAO" />-->
<!-- </bean>-->
<bean id="signupForm" class="com.srisris.khiraya.action.RegisterAction"/>
<!-- <bean id="registerAction" class="com.srisris.khiraya.action.RegisterAction">-->
<!-- <property name="ownerService" ref="ownerService" /> -->
<!-- </bean>-->
<!-- <bean id="ownerDAO" class="com.srisris.khiraya.dao.OwnerDAOImpl" >-->
<!-- <property name="sessionFactory" ref="sessionFactory" />-->
<!-- </bean>-->
</beans>
My Action Class
package com.srisris.khiraya.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.srisris.khiraya.dao.hibernate.Owner;
import com.srisris.khiraya.service.OwnerService;
#SuppressWarnings("rawtypes")
public class RegisterAction extends ActionSupport implements ModelDriven{
private static final long serialVersionUID = 6521996078347478542L;
private String ownerFirstName;
private String ownerLastName;
private String username;
private String password;
private String ownerPhone;
private String ownerEmail;
private OwnerService ownerService;
Owner owner = new Owner();
public void setOwnerService(OwnerService ownerService) {
this.ownerService = ownerService;
}
public String add() {
owner.setOwnerFirstName(ownerFirstName);
owner.setOwnerLastName(ownerLastName);
owner.setOwnerPassword(password);
owner.setOwnerPhone(ownerPhone);
owner.setOwnerEmail(ownerEmail);
ownerService.save(owner);
return SUCCESS;
}
public String execute() {
return INPUT;
}
public String getOwnerFirstName() {
return ownerFirstName;
}
public void setOwnerFirstName(String ownerFirstName) {
this.ownerFirstName = ownerFirstName;
}
public String getOwnerLastName() {
return ownerLastName;
}
public void setOwnerLastName(String ownerLastName) {
this.ownerLastName = ownerLastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getOwnerPhone() {
return ownerPhone;
}
public void setOwnerPhone(String ownerPhone) {
this.ownerPhone = ownerPhone;
}
public String getOwnerEmail() {
return ownerEmail;
}
public void setOwnerEmail(String ownerEmail) {
this.ownerEmail = ownerEmail;
}
public Object getModel() {
return owner;
}
}
I made a trivial mistake which costed me hours of pain. Silly me the problem was that my class name in struts.xml and id in register.xml were not matching and hence the issue.