Skip to main content.

JSP Controls Tag Library

Navigation: JSP Controls | About

Overview

It is possible to integrate an action framework like Struts with JSP Controls, offloading the tasks of processing input, validating it, and converting strings to specific datatypes onto a framework. Calling a Struts action is as simple as one <jsp:include> action:

<jc:handler>
  <jsp:include page="LoginComponent.do"/>
</jc:handler>

Because Struts handles only accept phase of request/response cycle, the definition of LoginComponent in the struts-config.xml file is very simple:

<form-beans>

  <form-bean name = "loginform" 
             type="net.jspcontrols.samples.component.LoginForm"/>
</form-beans>
<action-mappings>
  <!-- Login component -->
  <action path = "/logincomponent"
          type = "net.jspcontrols.samples.component.LoginComponent"
          name = "loginform" scope = "session" validate  = "false"/>
</action-mappings>

Instead of returning an ActionForward object, Struts action must return null; the view will be selected and rendered by JSP component. It is possible either to call a separate action mapping from respective Handler tag, or use one dispatch-type action class to process all events:

public class LoginComponent extends Action {

    /**
     * Instantiate event dispatcher
     */
    protected ActionDispatcher dispatcher = new EventActionDispatcher (this);

    /**
     * Use event dispatcher to call an appropriate event handler.
     * By using a dispatcher an action class does not need
     * to extend DispatchAction.
     */
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws Exception {
        return dispatcher.execute(mapping, form, request, response);
    }

    /**
     * Tries to log user in. If account not found, generates error message.
     */
    public ActionForward login (ActionMapping mapping,
                                ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response) throws Exception {

        HttpSession session = request.getSession();
        LoginForm inputForm = (LoginForm) form;

        // Log out user first
        request.getSession().removeAttribute("USER");

        // Explicitly validate input;
        // make sure that validation is turned off in struts-config.xml
        ActionMessages errors = inputForm.validate(mapping, request);

        if (errors != null) {
            // Save errors in session; removed them later after they shown
            // Struts 1.2.6+ removes errors and messages automatically
            session.setAttribute(Globals.ERROR_KEY, errors);
        } else {
            // Use this session attribute to hold user's name
            session.setAttribute("USER", inputForm.getUsername());
        }

        // Always do both of the following:
        // - set name of processed event in the request to notify JSP Controls
        //   that this is input phase and event was processed.
        // - return null,  tag will reload the component if needed
        request.setAttribute(Constants.JSPC_EVENT, "loginEvent");
        return null;
    }

    /**
     * Logs user out
     */
    public ActionForward logout (ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {

        LoginForm inputForm = (LoginForm) form;

        // Clean name and password in the input/output form bean
        inputForm.setUsername(null);
        inputForm.setPassword(null);

        // Remove dialog name from session, effectively logging out
        request.getSession().removeAttribute("USER");

        // Always do both of the following:
        // - set name of processed event in the request to notify JSP Controls
        //   that this is input phase and event was processed.
        // - return null,  tag will reload the component if needed
        request.setAttribute(Constants.JSPC_EVENT, "logoutEvent");
        return null;
    }
}

You need to set form scope to "session" to preserve form data between requests. You need to set "validate" to "false" to ensure that your handler methods are always called. Then you can validate input data from the handler method explicitly.

Here is the simple LoginForm that is used by LoginComponent:

public class LoginForm extends ActionForm {

    private String name;
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}

    private String password;
    public String getPassword() {return password;}
    public void setPassword(String password) {this.password = password;}

    // Do not forget to turn "validate" property of the action mapping off.
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        if (!"user".equalsIgnoreCase(name) ||
            !"pass".equalsIgnoreCase(password)) {
            ActionErrors errors = new ActionErrors();
            errors.add("ERROR", new ActionMessage("dialog.badpassword"));
            return errors;
        } else {
            return null;
        }
    }
}

So now you have it, a JSP/Struts component with Ajax support.