Creating Custom (Own) Request Processor in Struts 1.x

Struts 1.x framework can be extended in many  ways. One of the way is creating custom (own) request processor. Why we need to create custom request processor?. There may common tasks to be done on every request. For example 1) to check an user is logged in by checking the userName attribute in the session  before executing every request (i.e Validating user Session) 2) Checking roles of a user whether the particular user has rights to access the particular action method 3) capturing user activities in log table, etc..

Processing of a Request:

ActionServlet is the only servlet in Struts framework which is responsible for handling all of the requests. Whenever it receives a request, it creates a object of the RequestProcessor class ( i.e before redirecting to the programmer’s action, ActionServlet creates an object of RequestProcessor) and calls its process() method by passing HttpServletRequest and HttpServletResponse objects. The RequestProcessor class in the Struts has many methods like process(),processPreprocess(),processContent(). You can override any of the methods to do any common activities for each request.

For example, default implementation of process() method is as follows.

 public void process(HttpServletRequest request,
                        HttpServletResponse response)
    throws IOException, ServletException {
        // Wrap multipart requests with a special wrapper
        request = processMultipart(request);
        // Identify the path component we will
        // use to select a mapping
        String path = processPath(request, response);
        if (path == null) {
            return;
        }
        if (log.isDebugEnabled()) {
            log.debug("Processing a '" + request.getMethod() +
                      "' for path '" + path + "'");
        }
        // Select a Locale for the current user if requested
        processLocale(request, response);
        // Set the content type and no-caching headers
        // if requested
        processContent(request, response);
        processNoCache(request, response);
        // General purpose preprocessing hook
        if (!processPreprocess(request, response)) {
            return;
       }
        // Identify the mapping for this request
        ActionMapping mapping =
            processMapping(request, response, path);
        if (mapping == null) {
            return;
        }
        // Check for any role required to perform this action
        if (!processRoles(request, response, mapping)) {
            return;
        }
        // Process any ActionForm bean related to this request
        ActionForm form =
            processActionForm(request, response, mapping);
        processPopulate(request, response, form, mapping);
        if (!processValidate(request, response, form, mapping)) {
            return;
        }
        // Process a forward or include specified by this mapping
        if (!processForward(request, response, mapping)) {
            return;
        }
        if (!processInclude(request, response, mapping)) {
            return;
        }
        // Create or acquire the Action instance to
        // process this request
        Action action =
            processActionCreate(request, response, mapping);
        if (action == null) {
            return;
        }
        // Call the Action instance itself
        ActionForward forward =
            processActionPerform(request, response,
                                action, form, mapping);
        // Process the returned ActionForward instance
        processForwardConfig(request, response, forward);
    }

You have to do two things to implement custom request processor in struts.

1. Add the following lines to your struts-config.xml file after the element <action-mappings>   …. </action-mappings> to inform Struts that OwnRequestProcessor should be used as the RequestProcessor class.

<controller>
         <set-property property="processorClass" value="util.OwnRequestProcessor " />
</controller>

2. Create a class for example OwnRequestProcessor extending class RequestProcessor and override the method processPreprocess for example. The processPreprocess always return true. Returning false from this method will abort request processing. For example if user is not valid for the requested action then you may return false.

Before going to the implementation, let us see the sequence of processing a request in struts. Suppose user is requesting the action UserAction.

user request -> ActionServlet -> RequestProcessor -> if processPreprocess return true -> UserAction

Now let us  override processPreprocess method of RequestProcessor in OwnRequestProcessor for controlling  user access. Create your own OwnCustomRequestProcessor class under util package, which will extend the RequestProcessor class as given below.

 

 public class OwnRequestProcessor extends RequestProcessor {
        protected boolean processPreprocess (
           HttpServletRequest request,
             HttpServletResponse response) {

         HttpSession session = request.getSession(false);
        
/*If user is trying to access login page, then no need to check the session attribute. Otherwise check the Username attribute is there in the session. If username attribute is there means return true. Otherwise redirect to login page. */

   if( request.getServletPath().equals("/loginInput.do")
            || request.getServletPath().equals("/login.do") )
            return true;
        if( session != null &&
        session.getAttribute("userName") != null)
            return true;
        else{
            try{
                request.getRequestDispatcher 
                    ("/Login.jsp").forward(request,response);
            }catch(Exception ex){
            }
        }
        return false;
    }