Struts2 validation and preparation method
We have an action custprofileview
that shows a JSP page with all client details and in my JSP all fields are like mine
<s:textfield name="custprofileVO.email" value="%{custprofileVO.email}" />
<s:textfield name="custprofileVO.phone" value="%{custprofileVO.phone}" />
and do that and a submit button appears which triggers the action updatecustprofile
.
In updatecustprofile
Action, instead of directly mapping properties, I have a member variable private CustprofileVO custprofileVO;
with a setter and getter.
In CustprofileVO
Class I have fields like email
, phone
and all other fields with their settings and getters methods.
Problem : in updatecustprofile
Action I am implementing the interface Prepareable
, and in the implementation of the method prepare()
I have custprofileVO.setDefaultID("Select");
and set 4 more fields, but when I run the program by clicking the submit button, I get NPE
in the very first line thatcustprofileVO.setDefaultID("Select");
It looks like the framework doesn't instantiate CustprofileVO custprofileVO
. If I manually instantiate CustprofileVO
just above the field setting (by doing custprofileVO = new CustprofileVO()
, then it works. The problem is, ideally the struts2 framework should give me an instance, which it doesn't, you want to understand the reason.
Also if I manually set CustprofileVO
in the prepare method it works, but I also applied validation using XML where my field name is custprofileVO.email
, validate it and then custprofileVO.phone
validate it.
When I try to do validation on click of the submit button validate but on screen I see messages for all fields as the data in all text boxes is dull.
Why is the data being deleted?
source to share
You shouldn't instantiate an object that comes from JSP.
To get it in a method prepare()
, run Prepare Interceptor
before Param Interceptor
, you need to use a special stack : paramsPrepareParamsStack
<!-- An example of the paramsPrepareParams trick. This stack
is exactly the same as the defaultStack, except that it
includes one extra interceptor before the prepare interceptor:
the params interceptor.
This is useful for when you wish to apply parameters directly
to an object that you wish to load externally (such as a DAO
or database or service layer), but can't load that object
until at least the ID parameter has been loaded. By loading
the parameters twice, you can retrieve the object in the
prepare() method, allowing the second params interceptor to
apply the values on the object. -->
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="params">
<param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
source to share