TS 71 StrutsSupport

Struts Support Test Specification

Author: Karel Zikmund, Jiri Skrivanek
Version: NetBeans 7.1
Default IZ component(s): javaee/struts
Last update: 5-th October 2011
Introduction: This test specification is focused on testing NetBeans support for Struts application framework.

Contents


Test suite: Create Struts Application

  • Setup Struts Project
    • You can either
      • create new Web project and setup Struts support on 3rd page 'Frameworks', or
      • have an existing Web Application and add Struts support in project's Properties > Frameworks.
    • In both cases these things should be satisfied in project to contain Struts support:
      • Struts JAR files are on classpath
      • Struts TLDs are copied into WEB-INF directory (if checked in Struts support)
        Note: TLDs are also packaged in JAR files, I don't know why it is necesary to copy them in advance (maybe because JAR files can be copied into J2EE application library directory and Web container is not aware about containing TLDs?).
      • Struts action servlet is created in WEB-INF/web.xml (Note: Typical URL patterns are *.do and /do/*):
<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-name>/WEB-INF/struts-config.xml</param-name>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
      • Created Struts configuration file WEB-INF/struts-config.xml (created configuration file contains definition of example Struts Action and property file. We will create them in next steps):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
</struts-config>
  • Create login page
    • Now we create login JSP with a form. Handling of the form will be part of next steps.
    • Create login JSP login.jsp:
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:html>
<head>
    <html:base/>
    <title>Login page</title>
</head>
<body>

<h3>Login</h3>

<html:form action="Login/Verify" focus="loginName">
    <table border="1">
        <tbody>
            <tr>
                <td>Name:</td>
                <td><html:text property="loginName" size="12" maxlength="20"/></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><html:password property="loginPassword" size="8" maxlength="10"/></td>
            </tr>
            <tr>
                <td colspan="2" valign="center"><html:submit value="Login"/></td>
            </tr>
        </tbody>
    </table>
</html:form>

</body>
</html:html>
    • Use code completion for Struts tags and their attributes.
    • Open WEB-INF/web.xml file and in Pages view type login.jsp into Welcome Files > Welcome Files edit box.
    • If you run project (F6) to see the form in browser, you get an error "javax.servlet.ServletException: Cannot retrieve mapping for action /Login/Verify". Let's define /Login/Verify action in next step.
  • Create Form Bean
    • Now we process login in Struts framework. First we have to create a bean (LoginFormBean) which represents data from JSP form.
    • Create Struts form bean LoginFormBean (File > New File > category Struts, file type Struts ActionForm Bean)
      Class Name: LoginForm
      Package: com.mycompany.eshop.struts.forms
    • Check created Struts configuration file WEB-INF/struts-config.xml entry:
<form-beans>
    <form-bean name="LoginForm" type="com.mycompany.eshop.struts.forms.LoginForm"/>
</form-beans>
    • Check hyperlinking on class name. You can use code completion for tags and attributes.
    • Edit LoginFormBean class to:
package com.mycompany.eshop.struts.forms;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMapping;

public class LoginForm extends org.apache.struts.action.ActionForm {

    private String loginName = null;
    private String loginPassword = null;

    public LoginForm() {
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getLoginPassword() {
        return loginPassword;
    }

    public void setLoginPassword(String loginPassword) {
        this.loginPassword = loginPassword;
    }

    @Override
    public void reset(ActionMapping mapping, HttpServletRequest request) {
        loginName = null;
        loginPassword = null;
    }
}
  • Create Action
    • Now we have to create an action which will process form data in LoginFormBean and will verify login information.
    • Create Struts action LoginVerifyAction (File > New File > category Struts, file type Struts Action):
      • 2nd wizard page "Name and Location"
        • Class Name: LoginVerifyAction
        • Package: com.mycompany.eshop.struts.actions
        • Action Path: /Login/Verify
      • 3rd wizard page "Form Bean, Parameter"
        • Form Name: choose LoginForm
        • Scope: request
        • Input Resource: /login.jsp
    • Check Struts configuration file WEB-INF/struts-config.xml entry:
<action-mappings>
    <action input="/login.jsp" name="LoginForm" path="/Login/Verify" scope="request" type="com.mycompany.eshop.struts.actions.LoginVerifyAction"/>
</action-mappings>
    • Check hyperlinking on JSP (index.jsp), form name (LoginForm) and class name.
    • Edit LoginVerifyAction class to:
package com.mycompany.eshop.struts.actions;

import com.mycompany.eshop.struts.forms.LoginForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class LoginVerifyAction extends org.apache.struts.action.Action {

    private final static String SUCCESS = "success";

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        LoginForm loginForm = (LoginForm) form;

        if (com.mycompany.eshop.security.SecurityManager.AuthenticateUser(loginForm.getLoginName(), loginForm.getLoginPassword())) {
            return mapping.findForward(SUCCESS);
        } else {
            return mapping.getInputForward();
        }
    }
}
    • login verification action uses business class com.mycompany.eshop.security.SecurityManager for authentication.
    • Create business class com.mycompany.eshop.security.SecurityManager (File > New File > category Java Classes, file type Java Class):
package com.mycompany.eshop.security;

public class SecurityManager {

    /**
     * Authenticates user. Returns true if user's name/password is OK.
     */
    public static boolean AuthenticateUser(String name, String password) {
        // Business level authentication - simple check of user name/password = admin/admin
        // TODO: Implement authentication (e.g. use database, etc.)
        return (name != null) && name.equals("admin") && (password != null) && password.equals("admin");
    }
}
    • Run project (F6) to see the form in browser. Although any login atempt will lead into empty page because action navigation is not defined. Let's define it in next step.
  • Handle verification result
    • Now we have to define what will happen if 'success' is returned from LoginVerifyAction.
    • Open Struts configuration file WEB-INF/struts-config.xml and add Forward (editor context menu > Struts > Add Forward) - define navigation on 'success' to shop.jsp:
      • Forward Name: success
      • Resource File: /shop.jsp
      • Redirect: checked
      • Location - Action: /Login/Verify
    • Prefilled value of Location - Action in Add Forward dialog is context sensitive - invoke context menu on /Login/Verify action tag in configuration file.
    • Check added Struts configuration file WEB-INF/struts-config.xml entries:
<action input="/login.jsp" name="LoginForm" path="/Login/Verify" scope="request" type="com.mycompany.eshop.struts.actions.LoginVerifyAction">
    <forward name="success" path="/shop.jsp" redirect="true"/>
</action>
    • Create shop.jsp file:
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:html>
<head>
    <html:base/>
    <title>Shop page</title>
</head>
<body>
    <h3>Shop</h3>
    You are logged into e-shop.
</body>
</html:html>
    • Run project (F6) to see the form in browser. Type valid login/password (admin/admin) to go to e-shop main page shop.jsp. Alternatively type invalid name/password to go back to login.jsp although without explanation which will be added later.
    • Tip: change form's scope type in /Login/Verify request (edit Struts configuration fileWEB-INF/struts-config.xml):
<action input="/login.jsp" name="LoginForm" path="/Login/Verify" scope="session" type="com.mycompany.eshop.struts.actions.LoginVerifyAction">
    • Run application and type invalid name/password - form values are remembered. OTOH you are now responsible for resetting form values (e.g. after successful login - depends on your needs).
  • Add logout capability
    • Now we add Logout action to the application.
    • Create logout JSP logout.jsp:
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:html>
<head>
    <html:base/>
    <title>Logout page</title>
</head>
<body>
<h3>Logout</h3>
You are logged out.
</body>
</html:html>
    • Create logout Forward Action - open Struts configuration file WEB-INF/struts-config.xml and add Forward/Include Action (editor context menu > Struts > Add Forward/Include Action):
      • Action Path: /Logout
      • Resource File: /logout.jsp
    • Check added Struts configuration file WEB-INF/struts-config.xml entry:
<action forward="/logout.jsp" path="/Logout"/>
    • Add link to logout into shop.jsp - add 2 lines at end of the file:
    <h3>Shop</h3>
    You are logged into e-shop.
    <br/>
    <html:link action="/Logout" linkName="Log me out" >Logout</html:link>
    </body>
    </html:html>
    • Run project (F6) to see logout link in shop.jsp in browser.
  • Form validation - syntax level
    • Now we add syntax validation of submitted form without using business validation. We also show how to present errors in forms to user.
    • Edit LoginForm class (com.mycompany.eshop.struts.forms.LoginForm):
      • Add validate method:
@Override
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    ActionErrors errors = new ActionErrors();

    if ((getLoginName() == null) || (getLoginName().length() == 0)) {
        ActionMessage newError = new ActionMessage("errors.required", "Login Name");
        errors.add("loginName", newError);
    }
    if ((getLoginPassword() == null) || (getLoginPassword().length() == 0)) {
        ActionMessage newError = new ActionMessage("errors.required", "Login Password");
        errors.add("loginPassword", newError);
    }

    return errors;
}
    • errors.required is ID from resource bundle which will be defined later.
      • Add imports:
 import org.apache.struts.action.ActionErrors;
 import org.apache.struts.action.ActionMessage;
    • Create application resource properties file (File > New File > Other > Properties File)
      Note: This file is created automatically when you add Struts support into WebApplication using New Project wizard or Project's Properties > Frameworks > Add.
      • File Name: ApplicationResource
      • Folder: src\java\com\mycompany\eshop\struts
# Standard Struts framework properties for error formatting (headers, prefixes, etc.)
errors.header=
errors.prefix=<span style="color: red">
errors.suffix=</span>
errors.footer=
# Application specific error messages
errors.required={0} is required.
    • errors.prefix and errors.suffix properties are standard Struts framework error formatting properties. They force errors to be red in the page.
    • Add entry into Struts configuration file WEB-INF/struts-config.xml:
<message-resources parameter="com/mycompany/eshop/struts/ApplicationResource"/>
    • This entry is added automatically when you add Struts support into WebApplication using New Project wizard or Project's Properties > Frameworks > Add.
    • Add presentation on validation results to user - edit login.jsp and add 2 lines:
    <tr>
        <td>Name:</td>
        <td><html:text property="loginName" size="12" maxlength="20"/></td>
        <td><html:errors property="loginName"/></td>
    </tr>
    <tr>
        <td>Password:</td>
        <td><html:password property="loginPassword" size="8" maxlength="10"/></td>
        <td><html:errors property="loginPassword"/></td>
    </tr>
    • Run project (F6) and enter empty password or login name (or both) to see errors in login page. Validate method is called on form class (com.mycompany.eshop.struts.forms.LoginForm) as part of Action processing (class com.mycompany.eshop.struts.actions.LoginVerifyAction).
  • Form validation - business level

You probably noticed that wrong login (which doesn't match admin/admin) is simply returned back to login page without any explanation. We will now visualize error message on login page if login is not authenticated.

    • Edit login.jsp - add error visualization:
<h3>Login</h3>

    <html:errors property="loginInvalid"/>
  
    <html:form action="Login/Verify" focus="loginName">
        <table border="1">
    • Edit LoginVerifyAction class (com.mycompany.eshop.struts.actions.LoginVerifyAction) to add error message to the page:
      • Edit execute method:
if (com.mycompany.eshop.security.SecurityManager.AuthenticateUser(loginForm.getLoginName(), loginForm.getLoginPassword())) {
        return mapping.findForward(SUCCESS);
    } else {
        ActionMessages errors = new ActionMessages();
        ActionMessage error = new ActionMessage("errors.login.invalid");
        errors.add("loginInvalid", error);
        saveErrors(request.getSession(), errors);
  
        return mapping.getInputForward();
    }
      • Add imports:
    import org.apache.struts.action.ActionMessages;
    import org.apache.struts.action.ActionMessage;
    • Edit application resources (ApplicationResource.properties in package com.mycompany.eshop.struts) to add error message text:
# Application specific error messages
errors.required={0} is required.
errors.login.invalid=Invalid login name or password. Try it again.
    • Run project (F6) and enter non-empty password and login name which are invalid (i.e. not admin/admin) to see error in login page.
Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo