1

I was recently working with a login page with Struts2 framework and for validating the fields i used XML Validation feature provided by Struts2. And the fields are validated but the problem is that, if any of the field is not empty after validation the those field values are not repopulated in the corresponding field.The Example code is given.The version of the framework is 2.5.x.

Login.jsp

<s:form method="post" action="authenticate">
    <div class="form-group">
        <span class="input-icon"> 
                <s:textfield name="strUserName" id="strUserName" cssClass="form-control" placeholder="Username or Email"></s:textfield> 
                <i class="fa fa-user"></i>
                </span> 
                <span>
                    <s:fielderror fieldName="strUserName"/>
                </span>
                </div>
        <div class="form-group">
           <span class="input-icon"> 
                <s:password name="strPassword" id="strPassword" cssClass="form-control" placeholder="Password"></s:password> <i class="fa fa-lock"></i>
           </span> 
            <span>
                <s:fielderror fieldName="strPassword"/>
            </span>
        </div>
</s:form>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />   
    <constant name="struts.action.extension" value=",json"/>

    <!--    Set to false before deploying the application -->
    <constant name="struts.devMode" value="true" /> 
    <constant name="struts.enable.SlashesInActionNames" value="true"/>
    <constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>

    <constant name="struts.configuration.xml.reload" value="false" />
    <!-- constant to define global resource bundle -->
    <constant name="struts.custom.i18n.resources" value="globalMessages" />
    <constant name="struts.ui.theme" value="simple" />

<package name="<package_name>" namespace="/" extends="struts-default">
<action name="authenticate" class="<Action_class_name>" method="<method_name>">
            <interceptor-ref name="store">
                <param name="operationMode">STORE</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack" />
            <result type="redirectAction">Successpage</result>
            <result name="input" type="redirectAction">login</result>
</action>   
<action name="login">
            <interceptor-ref name="store">
                <param name="operationMode">RETRIEVE</param>
            </interceptor-ref>
            <result>login.jsp</result>
</action>
</package>
</struts>

Action_name-validation.xml

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
 <validator type="requiredstring">
    <param name="fieldname">strUserName</param>
    <param name="trim">true</param>
    <message key="errors.required"></message>
 </validator>
  <validator type="requiredstring">
    <param name="fieldname">strPassword</param>
    <param name="trim">true</param>
    <message key="errors.required"></message>
 </validator>
</validators>

Action_name.java

public class Action_name extends ActionSupport implements ModelDriven<UserModel> {
    private UserModel user;

    public String method_name() {
     if(success){
        return SUCCESS;
     }else{
       return INPUT;
     }
    }
    @Override
    public UserModel getModel() {
        user = new UserModel();
        return user;
    }
}

Applicatin - intial run

enter image description here

Application - After Validation

enter image description here

value "xyz" is not repopulated after the validation.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Sebin Thomas
  • 279
  • 8
  • 21
  • For security reasons you shouldn't repopulate that fields. – Roman C Sep 02 '16 at 10:41
  • @RomanC its not working in not only in login form but other forms with same config. – Sebin Thomas Sep 02 '16 at 10:52
  • That is why is not working but other forms are not related though. – Roman C Sep 02 '16 at 12:43
  • I don't know why it is marked Duplicate.it does have a similarity but that's not what i have asked here.There is a type redirectAction is given in my code which is why the fields are not populated, which you wont find in the other question.So please read the question before you mark it duplicate. – Sebin Thomas Sep 03 '16 at 05:17
  • Duplicate question is the one that is already asked before. You have asked the same question that was answered several years before, and your question can't be useful to the community. You should know that SO is *not* Help and Support* site but Q&A. You should know [how to ask](http://stackoverflow.com/help/how-to-ask) the question before posting your problems here. Again, your problems already have been solved. – Roman C Sep 03 '16 at 12:37

1 Answers1

1

There are two problems:

  1. your login action

    <action name="login">
        <interceptor-ref name="store">
            <param name="operationMode">RETRIEVE</param>
        </interceptor-ref>
        <result>login.jsp</result>
    </action>
    

    has only a single interceptor, the MessageStore one.

    It should have instead at least the ModelDriven and the Parameters Interceptors to work correctly. For example

    <action name="login">
        <interceptor-ref name="store">
            <param name="operationMode">RETRIEVE</param>
        </interceptor-ref>
        <interceptor-ref name="defaultStack" />
        <result>login.jsp</result>
    </action>
    

    But note that this would lead to infinite recursion due to the MessageStore Interceptor always adding errors and the Workflow Interceptor always returning "input"; to avoid it you should define a secondary defaultStack in your struts.xml with all the intercpetors except the Workflow one, otherwise the MessageStore with RETRIEVE will make it loop or, if you haven't defined an input result for your login action, complaining about a missing input result.

  2. The second error is that you are redirecting, and hence losing the parameters. You're using the MessageStore Interceptor to preserve Action Messages, Action Errors and Field Errors across the redirection, but every other parameter is lost. If you want to preserve a parameter across a redirectAction you must explicitly send it, or store it in session in the source action and retrieving it in the destination action. In your case, it would be better to simply return the JSP in case of input result, instead of redirecting:

    <action name="authenticate" class="<Action_class_name>" method="<method_name>">
        <interceptor-ref name="store">
            <param name="operationMode">STORE</param>
        </interceptor-ref>
        <interceptor-ref name="defaultStack" />
        <result type="redirectAction">Successpage</result>
        <result name="input" >login.jsp</result>
    </action>
    <action name="login">
        <interceptor-ref name="defaultStack" />
        <result>login.jsp</result>
    </action>
    
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Adding the `` makes no change , still not repopulating. – Sebin Thomas Sep 02 '16 at 11:04
  • The 2nd one Solved the issue, and thank you.But as you said how can i preserve the parameters across the action without removing redirectAction. – Sebin Thomas Sep 02 '16 at 15:11
  • What do you know about Scope Interceptor?? i just heard i have no idea what it is. will that help to resolve this prob?? – Sebin Thomas Sep 02 '16 at 15:24
  • Never used the scope interceptor. The best shot is to remove redirectAction, otherwise you'd need to specify the parameters one by one, or [doing black magic like I've did here](http://stackoverflow.com/a/25685548/1654265), but seriously... do not try this at home :) – Andrea Ligios Sep 02 '16 at 15:30
  • That's great. In Login form removing the redirectAction will resolve my prob. but there are other forms which have slimier issues where I must use the redirectAction as I have other processing in those action.Can you do some "Black Magic" here.:) . What do you get from this http://stackoverflow.com/questions/12773877/store-interceptor-and-loose-value-stack-when-redirection – Sebin Thomas Sep 02 '16 at 15:40
  • The point is that you should use PRG (Post Redirect Get) pattern, and performing redirect when needed. The INPUT result of an action that is asking you to logging in should be a dispatcher result of the same action, not the success result of another action.You redirect when you need to execute *another* action, for exmaple when you need to insert or update data, you execute the xxxinsert action, return redirectResult to xxxshow action, and in there you don't need to retain the previously inserted values, just to show the ones loaded from db. If in the xxxinsert action you get INPUT, you – Andrea Ligios Sep 02 '16 at 15:45
  • return the jsp, not the xxxshow action. Then if you have data that must always be loaded (for example default comboboxes loaded from database), so that when you return a jsp from every action (show, insert, ecc) you have them always available, just put the loading in the prepare() method that is always executed. It's a nonsense to preserve unknown random parameters across redirections, you probably don't need those redirections. – Andrea Ligios Sep 02 '16 at 15:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122556/discussion-between-zionz-and-andrea-ligios). – Sebin Thomas Sep 03 '16 at 05:27