1

I wrote a web application where there are login.jsp, loginAction and login Beans. When I fill the form in th jsp beans in the loginbeans are being filled through loginAction. When I replicate the logic from these pages to registering an user, beans are not being filled. Here is my code..

<s:form action="login" method="post">
   <p>      <s:textfield    key="username" label="Username" required="true" /><br> 
   <p>  <s:password     key="password" label="Password" required="true" /><br> 
   <p>    <s:submit         value="SignIn"/> <br>            
</s:form>

relative code in struts.xml

<action name="login" class="com.ActionClasses.LoginAction">
   <result name="success"   type="tiles">welcome    </result>
   <result name="login" type="tiles">login      </result>
   <result name="input" type="tiles">login      </result>
</action>

LoginAction.java

public class LoginAction  extends ActionSupport implements Action, ModelDriven<LoginBeans>{

LoginBeans loginBeans = new LoginBeans();
.
.
.
    @Override
public LoginBeans getModel() {      
    return loginBeans;
}

LoginBeans.java

public class LoginBeans {
private String username;
private String password;
//getters and setters
}

This is all working fine and beans are being filled. Now take a look at registering a user.

registerOphthalmologist.jsp

<s:form action="registerOphthalmologist" method="post">     
    <s:hidden       key="role"          label="role"    value="O"       />
    <s:textfield    key="username"      label="Choose UserName" required="true"/>
    <s:password     key="password"      label="Choose Password" required="true"/>

    <s:textfield    key="givenName"     label="Name"    required="true"/>
    <s:textfield    key="surname"       label="Surname" required="true"/>
    <s:textfield    key="age"           label="Age"     required="true"     value=""/>
    <s:select       key="gender"        label="Gender"  
                        list="#{'M':'Male','F':'Female'}" 
                        required="true"/>

    <s:textfield    key="contactNumber"     name="contactNumber"    label="Contact Number"  required="true"/>
    <s:textfield    key="email"             name="email"            label="email"           required="true"/>
    <s:textfield    key="city"              name="city"             label="City"            required="true"/>
    <s:textfield    key="district"          name="district"         label="District"        required="true"/>
    <s:textfield    key="state"             name="state"            label="State"           required="true"/>
    <s:textfield    key="country"           name="country"          label="country"         required="true"/>
    <s:textfield    key="postalCode"        name="postalCode"       label="Postal Code"     required="true"/>

    <s:textfield    key="degree"            label="Qualification"           required="true"/>
    <s:textfield    key="university"        label="University"              required="true"     value=""/>
    <s:textfield    key="hospitalName"      label="Hospital Name"           required="true"/>
    <s:textfield    key="experience"        label="Years of Experience"     required="true"     value=""/>

    <s:checkbox     key="checkMe"       label="Agree to terms & Conditions"/>
        <s:submit       value="Register"    align="center"/>

</s:form>

relative code in struts.xml

<action name="register*" class="com.ActionClasses.RegisterAction">
   <result name="success"   type="tiles">   home        </result>
   <result name="input" type="tiles">   register{1} </result>
   <result name="error" type="tiles">   register{1} </result>
</action>

RegisterAction.java

public class RegisterAction extends ActionSupport implements Action,ModelDriven<RegisterBeans>
{
RegisterBeans registerBeans = new RegisterBeans();  
.
.
.
    @Override
public RegisterBeans getModel() {
    // TODO Auto-generated method stub
    return registerBeans;
}

RegisterBeans.java

public class RegisterBeans extends ActionSupport{

private String username;
private String password;
private char role;
private boolean checkMe;

private String givenName;
private String surname;
private int age;
private char gender;

private String hospitalName;
private String institute;
private String university;
private String degree;
private int experience;
private int research;
private int ophthalmologists;

private String contactNumber;
private String email;
private String city;
private String district;
private String state;
private String country;
private String postalCode;
//getters and setters
}

These beans are not being filled. What is the mistake I am doing here? My complete struts.xml file is

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<package name="default" extends="struts-default">

    <result-types>
        <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
    </result-types>

    <action name="*Link" method="{1}" class="classes.HomeLinks">
        <result name="home"     type="tiles">home   </result>
        <result name="upload"   type="tiles">upload     </result>
        <result name="register" type="tiles">register   </result>
        <result name="login"    type="tiles">login      </result>
    </action>

    <action name="login" class="com.ActionClasses.LoginAction">
        <result name="success"  type="tiles">welcome    </result>
        <result name="login"    type="tiles">login      </result>
        <result name="input"    type="tiles">login      </result>
    </action>

    <action name="logout" class="com.ActionClasses.LogoutAction">
        <result name="success"  type="tiles">home</result>
    </action>

    <action name="register" class="classes.SpecificRegistrations">
        <result name="Ophthalmologist"  type="tiles">   registerOphthalmologist </result>
        <result name="practitioner"     type="tiles">   registerPractitioner    </result>
        <result name="Researcher"       type="tiles">   registerResearcher      </result>
        <result name="Hospital"         type="tiles">   registerHospital        </result>
        <result name="input"            type="tiles">   register                </result>
    </action>

    <action name="register*" class="com.ActionClasses.RegisterAction">
        <result name="success"  type="tiles">   home        </result>
        <result name="input"    type="tiles">   register{1} </result>
        <result name="error"    type="tiles">   register{1} </result>
    </action>

    <action name="upload" class="com.ActionClasses.UploadAction">
        <interceptor-ref name="fileUpload">
            <param name="maximumSize">3145728</param>
            <param name="allowedTypes">image/png,image/gif,image/jpeg,image/pjpeg, image/jpg</param>
        </interceptor-ref>
        <interceptor-ref name="defaultStack"></interceptor-ref>
        <result name="success"  type="tiles">   uploaded    </result>
        <result name="error"    type="tiles">   upload      </result>
    </action>
</package>
</struts>
Pawan
  • 423
  • 6
  • 28

1 Answers1

1

Potential error:

remove extends ActionSupport from your

public class RegisterBeans extends ActionSupport{

declaration. It will be treated like an Action in some circumstances and that is not what you want.

Warnings:

  1. Avoid using key attribute if you are specifying label and value too, use name instead. According to the docs, it

    Set the key (name, value, label) for this particular component

  2. Always specify a namespace both in struts configuration and <s:form> attribute, it is not good to work on the default namespace only.

  3. Be careful with the required="true" attribute; it works in old Struts versions, but after migrating to a newer release, it has been changed to requiredLabel, and since <s:textfield /> supports Dynamic Attributes, it will be reported on the page exactly like it is (required="true"), and then interpreted by browsers like the HTML5 required="required" attribute, making all your fields mandatory and without the * symbol ahead. I've met that yesterday while migrating an old project, it's really annoying.

  4. For the sake of the consistency, an entity representing a single bean should be called LoginBean or RegisterBean instead of the plural form LoginBeans or RegisterBeans. Same for instance variables, you should use the plural form only when it is an Array, a Collection, etc...

  5. ActionSupport is defined as

    public class ActionSupport implements Action, Validateable, ValidationAware, 
                                      TextProvider, LocaleProvider, Serializable {
    

    so extending it and implementing Action interface is redundant.

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Even after removing model driven, beans are not being filled. As the loginBean is being filled I again used ModelDriven in registerBean. Can you tell me problem with ModelDriven? – Pawan Sep 03 '14 at 09:22
  • Also make your beans `private` and check your interceptor stacks – Andrea Ligios Sep 03 '14 at 09:24
  • @Andrea Ligios. Your suggestions helped me a lot and I have followed all of it. But still beans are not being filled. – Pawan Sep 03 '14 at 09:24
  • All my beans are private only @Andrea Ligios – Pawan Sep 03 '14 at 09:26
  • Please post the interceptor stack(s) configured for both actions – Andrea Ligios Sep 03 '14 at 09:35
  • @AleksandrM Why *stop using modeldriven*? Is it deprecated? – Roman C Sep 03 '14 at 10:37
  • @user130004 : the `register` Action just before the `register*` one doesn't sound like a good idea. Try changing its name to test if this is causing conflicts. Also remember to add `private` in front of your beans declaration – Andrea Ligios Sep 03 '14 at 12:10
  • @RomanC: Nope. Not deprecated, but if someone wants to use it he/she must understand what he/she is doing. Most probably it is better off without it. – Aleksandr M Sep 03 '14 at 12:18
  • @AndreaLigios I have some other actions like registerResearchcer, registerPractitiner and so on.... – Pawan Sep 04 '14 at 02:56
  • @user130004 I know, I'm just arguing that it may be cause of conflicts to use both `register` and `register*`... you should try to change the name of one of them, as a test. Also consider upvoting (not accepting) the answer if `Your suggestions helped me a lot`, to compensate haters downvoting for no reasons :/ – Andrea Ligios Sep 04 '14 at 09:05
  • @AndreaLigios My main problem solved only after stopping the use of _ModelDriven_ – Pawan Sep 04 '14 at 09:19
  • @user130004 Of course, ModelDriven is not a bad practice on its own, but you need to know *exactly* what you are doing when messing with it; that's why me and AleksandrM told you to avoid using it [many times](http://stackoverflow.com/q/25544026/1654265). I've just realized that I've answered 4 of your questions and you've never upvoted any of them, not even the one accepted... is there any reason preventing you to upvote (useful) answers ? It doesn't cost money, it is the free way StackOverflow provides you to reward people speding time to answer your questions... – Andrea Ligios Sep 04 '14 at 09:30
  • @AndreaLigios Initially I don't enough reputation and that is the only reason to not up-voting. Nothing else prevented me. Now I will go back and up-vote your answers for my previous questions. – Pawan Sep 04 '14 at 09:35
  • @user130004 Thank you, that's gratifying ;) – Andrea Ligios Sep 04 '14 at 09:36
  • I have up-voted 2 of your answers that helped me. Thank you for helping me. I wish I will have your support for my further questions too. – Pawan Sep 04 '14 at 09:50
  • @user130004 Sure, we're here to help ;) – Andrea Ligios Sep 04 '14 at 10:01