Question

I don't understand conception of Struts2 validation in next case :

My application consists of 2 actions:

  1. login.action
  2. drive.action

I can run drive.action from browser command line without filling user and password in login.action

How can I implement validation code which prevents the run of drive.action from command line if user hasn't successfully filled user and password in login.action?

Was it helpful?

Solution

The validation concept

Struts 2 validation is configured via XML or annotations. Manual validation in the action is also possible, and may be combined with XML and annotation-driven validation.

Validation also depends on both the validation and workflow interceptors (both are included in the default interceptor stack). The validation interceptor does the validation itself and creates a list of field-specific errors. The workflow interceptor checks for the presence of validation errors: if any are found, it returns the "input" result (by default), taking the user back to the form which contained the validation errors.

If we're using the default settings and our action doesn't have an "input" result defined and there are validation (or, incidentally, type conversion) errors, we'll get an error message back telling us there's no "input" result defined for the action.


It is simple, you map the validators to the fields via the validation configuration file, or via annotations. Then apply a validation interceptor to the action via referencing it explicitly or implicitly via the interceptor stack, custom stack or defaultStack.

When validation started it invokes the validation manager to perform actual validation and save errors to the ValidationAware action.

Your action should implement this interface, or just extend the ActionSupport where it's already implemented, to save the errors. Then workflow interceptor checks for those errors and if found any of them redirect to the INPUT result, if no errors found the action invocation is executed. You may also add a programmatic validation to the action by implementing Validateable interface, which ActionSupport is implemented by default, hence to override the validate() method(s).

As a supplement to XML based validation you could also apply annotation based configuration. This only the server-side validation, the client-side validation applied to the browser enabled javascript via Struts tags used for rendering a validation content to the page being validated.

All of this concept is not applicable to the action which requires authentication (unless the authentication interceptor is applied to the action). If you use JAAS authentication, then you should consider your action to implement PrincipalAware or use roles interceptor to restrict access to the action which checks the isUserInRole(). You may use Action.LOGIN result to return to the login page in authentication interceptor if the user is not authenticated like in Is there a way to redirect to another action class without using on struts.xml example.

OTHER TIPS

To achieve this you need to use interceptor as said by Dave Newton.
Interceptor code is :

package com.interceptor;
public class SessionInterceptor implements Interceptor,ServletRequestAware,SessionAware
{ 
   HttpServletRequest request; //request object
   public Map<String, Object> sessionMap;

@Override
public void setSession(Map<String, Object> arg0) {
    
    this.sessionMap = arg0;
}

@Override
public void setServletRequest(HttpServletRequest arg0) {
    
    this.request = arg0;
}

@Override
public void destroy() {
    
    
}

@Override
public void init() {
    
    
}

@Override
public String intercept(ActionInvocation invocation) throws Exception {
    
    sessionMap=invocation.getInvocationContext().getSession();
    ActionContext context=(ActionContext)invocation.getInvocationContext();

    String className = invocation.getAction().getClass().getName();
    String ActionName = invocation.getAction().toString();//action name which is called
           
            //below check if session map or username is null or you logic
            if(sessionMap==null || sessionMap.get("userName")==null){
            return "loginError";    //this will return without calling your drive.action if user name or session is null
        }else{
            return invocation.invoke();  //if session is available or user name then it will run the action
        }
  }//end of intercept method
}//end of class

struts.xml is :

    <package name="Pkg" extends="struts-default" namespace="/">
    
    <interceptors>
        <interceptor name="sessionCheck" class="com.interceptor.SessionInterceptor">
    </interceptor>
    <interceptor-stack name="sessionStack">
        <interceptor-ref name="sessionCheck"/>          
        <interceptor-ref name="defaultStack" />
    </interceptor-stack>
    </interceptors>
    
    <default-interceptor-ref name="sessionStack"></default-interceptor-ref>
    
    <global-results>
        <result name="loginError">login.jsp</result>
    </global-results>
           //here all the actions which you want to apply interceptor
         //rest of actions where above SessionInterceptor will be applied
        ...
        ....
        .....

Do not write you first login.action inside above package instead create new package in struts.xml like :

   <package name="Pkg2" extends="struts-default">       
    <action name="login.action" class="com.action.LogAction" method="execute">
        <result name="success" type="redirect">drive</result> <!-- here action name drive is action from above package where interceptor is applied or any which you want-->
    </action>
  </package>

I hope this is what you are looking for.
Here are few links which may help you

  1. session interceptor
  2. package configuration
  3. interceptor
  4. interceptor stack example
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top