1

I have Struts validation interceptor mentioned in struts.xml.

    <!-- Configuration for the default package. -->
    <package name="default"  extends="struts-default">
        <interceptors>
            <!-- Interceptor to handle allowing only admins to certain actions -->
            <interceptor name="adminOnly" class="adminInterceptor"/>
            <!-- Interceptor to handle accessDenied exceptions thrown from service/model layer called from within actions -->
            <interceptor name="accessDenied" class="accessDeniedInterceptor"/>
            <!-- Copied from struts-default.xml and changed validation exclude methods -->
            <interceptor-stack name="defaultStack">
                <interceptor-ref name="accessDenied"/>
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">cancel,execute,delete,edit,list</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,browse,cancel</param>
                </interceptor-ref>
            </interceptor-stack>
            <interceptor-stack name="fileUploadStack">
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
            <interceptor-stack name="adminCheck">
                <interceptor-ref name="defaultStack"/>
                <interceptor-ref name="adminOnly"/>
            </interceptor-stack>
        </interceptors>



<action name="editUser" class="userAction" method="edit">
            <interceptor-ref name="adminCheck"/>
            <result name="success">/WEB-INF/pages/userForm.jsp</result>
            <result name="input">/WEB-INF/pages/admin/userList.jsp</result>
            
        </action>
        
         <action name="cancelUser" class="userAction" method="cancel">     
         
         <result name="cancel" type="redirectAction">admin/users</result>      
         <!--    <result name="cancel">/WEB-INF/pages/admin/userList.jsp</result> -->          
         </action>

<action name="saveUser" class="userAction" method="save">
         <!--    <result name="cancel" type="redirectAction">admin/users</result>  -->
            <result name="input">/WEB-INF/pages/userForm.jsp</result>
            <result name="success" type="redirectAction">admin/users</result>
        </action>

And then I have JSP page in which I mention

<s:form name="userForm" action="saveUser" method="post" validate="true" cssClass="well" autocomplete="off">   

And form has 3 submit buttons.

<div id="actions" class="form-group">
            <s:submit type="button" cssClass="btn btn-primary" method="save" key="button.save" theme="simple">
                <i class="icon-ok icon-white"></i>
                <fmt:message key="button.save"/>
            </s:submit>
            <c:if test="${param.from == 'list' and not empty user.id}">
                <s:submit type="button" cssClass="btn btn-danger" method="delete" key="button.delete"
                          onclick="return confirmMessage(msgDelConfirm)" theme="simple">
                    <i class="icon-trash"></i>
                    <fmt:message key="button.delete"/>
                </s:submit>
            </c:if>
            <s:submit type="button" cssClass="btn btn-default" method="cancel" action="cancelUser"  key="button.cancel" theme="simple">
                <i class="icon-remove"></i>
                <fmt:message key="button.cancel"/>
            </s:submit>
        </div>
        </s:form>

And my action class has these methods :

public String execute() {
    return SUCCESS;
}


public String cancel() {
    if (!"list".equals(from)) {
        return "home";
    }
    return "cancel";
}


public String save() throws Exception {

    Integer originalVersion = user.getVersion();

    boolean isNew = ("".equals(getRequest().getParameter("user.version")));
    // only attempt to change roles if user is admin
    // for other users, prepare() method will handle populating
    if (getRequest().isUserInRole(Constants.ADMIN_ROLE)) {
        user.getRoles().clear(); // APF-788: Removing roles from user
                                    // doesn't work
        String[] userRoles = getRequest().getParameterValues("userRoles");

        for (int i = 0; userRoles != null && i < userRoles.length; i++) {
            String roleName = userRoles[i];
            try {
                user.addRole(roleManager.getRole(roleName));
            } catch (DataIntegrityViolationException e) {
                return showUserExistsException(originalVersion);
            }
        }
    

Validations are getting triggered on click of Cancel button too. Is there a way to stop validations from getting triggered on click of Cancel?

Changed code :

<!-- Configuration for the default package. -->
    <package name="default"  extends="struts-default">
        <interceptors>
            <!-- Interceptor to handle allowing only admins to certain actions -->
            <interceptor name="adminOnly" class="adminInterceptor"/>
            <!-- Interceptor to handle accessDenied exceptions thrown from service/model layer called from within actions -->
            <interceptor name="accessDenied" class="accessDeniedInterceptor"/>
            <!-- Copied from struts-default.xml and changed validation exclude methods -->
            <interceptor-stack name="myDefaultStack">
                <interceptor-ref name="accessDenied"/>
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">cancel,execute,delete,edit,list</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input, back, browse, cancel</param>
                </interceptor-ref>
            </interceptor-stack>
            <interceptor-stack name="fileUploadStack">
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="myDefaultStack"/>
            </interceptor-stack>
            
          <!--   <default-interceptor-ref name="myDefaultStack"/> -->
          
            <interceptor-stack name="adminCheck">
                <interceptor-ref name="myDefaultStack"/>
                <interceptor-ref name="adminOnly"/>
            </interceptor-stack>                      
        </interceptors>
            
            
         <default-interceptor-ref name="myDefaultStack"/>
Roman C
  • 49,761
  • 33
  • 66
  • 176
user3339592
  • 127
  • 1
  • 1
  • 13
  • It should work. Can you post your complete (relevant) struts.xml ? – Andrea Ligios Jul 23 '14 at 15:46
  • here is my interceptor definition : – user3339592 Jul 23 '14 at 16:15
  • I have Edited the code with more struts.xml and methods from my action class. Exclude method should bypass validations on Cancel but it is not. On click of cancel button user is asked to enter all the required fields. And then cancel works. Which is very odd. – user3339592 Jul 23 '14 at 16:33
  • What version of Struts are you using? – Roman C Jul 23 '14 at 19:53
  • I had done the configuration. I was asking what is wrong with it. Probably my title for question is wrong. But my intention to ask was why it is not working for me. what is wrong with my code. – user3339592 Jul 24 '14 at 13:03

1 Answers1

0

I had done the configuration. I was asking what is wrong with it. Probably my title for question is wrong. But my intention to ask was why it is not working for me. What is wrong with my code.

In your code you have used method attribute on s:submit tag. This attribute no longer works by default because DMI (Dynamic Method Invocation) is disabled. There's a setting constant in the xml configuration that you can change to enable this feature. But you might have other security problems if you don't have implied security on methods.

<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<constant name="struts.mapper.action.prefix.enabled" value="false"/>

and use

<s:submit type="button" cssClass="btn btn-default" method="cancel"
  key="button.cancel" theme="simple"> 

Another approach is to change attribute method to action and use

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.mapper.action.prefix.enabled" value="true"/>

and use

<s:submit type="button" cssClass="btn btn-default" action="cancelUser"
  key="button.cancel" theme="simple"> 

you cannot use both attributes method and action in the s:submit tag. And if both settings above are false the action bound to the s:form tag will execute. That's why validation have been occurred.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • `you cannot use both attributes method and action in the s:submit tag` > I've used them with no problems. The action was the same of the form, though, explicited for clarity, but no errors occurred. – Andrea Ligios Jul 25 '14 at 12:37
  • the only one of them can work, not both and first has a priority. – Roman C Jul 25 '14 at 12:49
  • Just checked, method was second but it worked. `` Called action foo and method bar. Maybe it was dropped because it was the same action of the form, but it works. Obviously is old code, no DMI anymore... S2.3.1.2 – Andrea Ligios Jul 25 '14 at 12:55
  • May be I was precise to what I was thought, but I posted clarification. You answer is/was actually wrong about interceptor configuration. I didn't want do discuss it because it's not concerned the question. – Roman C Jul 25 '14 at 13:13
  • Thanks for all the discussion guys. It was helpful to understand. My issue is still not resolved though. @Roman C I tried both your config. First config was existing in my app. But it did not work. I tried second config with but it did not work either. I have seen other questions stating that it works only after Struts 2.3.15.1 I am using 2.3.16 but still does not work. Not sure how to get rid of this bug in the app. – user3339592 Jul 28 '14 at 19:42
  • @user3339592 Update Struts to v. 2.3.28. – Roman C Mar 24 '16 at 15:43