JSP Controls Tag Library
 

JSP Controls Tag Library: Login Component Full Source Code

Overview

This page contains full source code of Login Component that you can try out live.

Login Component

Composite Page, index.jsp

First goes the composite page, index.jsp, that aggregates the Login Component:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
  <body>
    <style type='text/css'>
      .dottedframe {border: 2px dotted #fa9010; min-width: 30em; padding: 5px;}
    </style>

    <p class="dottedframe">This paragraph is defined directly in the parent page
    and should <strong>precede</strong> the content of login control.</p>

    <div class="dottedframe" id="LoginComponent">
      <jsp:include page="loginComponent.jsp"/>
    </div>

    <p class="dottedframe">This paragraph is defined directly in the parent page
    and should <strong>follow</strong> the content of login control.</p>
  </body>
</html>

The component is inserted into a composite page dynamically using <jsp:include> action. This means, that servlet/JSP container inserts the actual HTML response generated by the component, not JSP code. Two plain text paragraphs are defined in the page to make sure that content from the main page, surrounding the component, is not lost after <jsp:include> action returns.

Login Component, loginComponent.jsp

The Login Component is defined in loginComponent.jsp file:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.ArrayList,
                 net.jspcontrols.util.Constants"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://jspcontrols.net/tags-core" prefix="jc" %>
<span id="LoginComponent_def">

<%-- **********************************************************************
     The stub for authentication service; allows only "user"/"pass" account
     ********************************************************************** --%>

<%!
    public boolean authenticate(String username, String password){
        return "user".equals(username) && "pass".equals(password);
    }
%>

<%-- **********************************************************************
     Input phase, either postback or regular link containing an event
     ********************************************************************** --%>


<%-- Processing login --%>
<jc:handler event="login">
  <%
      // Log out current user first
      session.removeAttribute("USER");

      // Read username and password submitted from dialog form
      String username = request.getParameter("username");
      String password = request.getParameter("password");

      // Store user name in session if needed to redisplay.
      // No need to redisplay password, so it is not stored.
      session.setAttribute("username", username);

      // Log the user in
      if (authenticate(username, password)) {
          session.removeAttribute("username");
          session.setAttribute("USER", username);

      // User accout is not found, generate error messages
      } else {
          ArrayList messages = new ArrayList();
          String message = "Account not found.";
          messages.add(message);
          session.setAttribute("MESSAGES", messages);
      }
  %>
</jc:handler>

<%-- Processing logout --%>
<jc:handler event="logout">
  <%
      // Log out current user first
      session.removeAttribute("USER");
  %>
</jc:handler>

<%-- Accept phase has finished. Reload the composite page to render a view --%>
<jc:reload/>


<%-- **********************************************************************
     Prerender Phase: URL housekeeping; You can choose a proper view 
     ********************************************************************** --%>

<jc:prerender>
  <%
      pageContext.setAttribute(Constants.SELECTED_VIEW_NAME,
          session.getAttribute("USER") != null ? "loggedin" : "notloggedin"
      );
  %>
</jc:prerender>

<%-- **********************************************************************
     Common Render Phase: write out error messages and remove them from session
     ********************************************************************** --%>

<jc:render>
  <c:if test='${not empty sessionScope.MESSAGES}'>
    <c:forEach var='message' items='${sessionScope.MESSAGES}'>
      <ul>
        <li><b><c:out value='${message}'/></b></li>
      </ul>
    </c:forEach>
    <% session.removeAttribute("MESSAGES"); %>
  </c:if>
</jc:render>

<%-- **********************************************************************
     Render Phase: User is not logged in. Display login form.
     ********************************************************************** --%>

<jc:render view="notloggedin">
  <jsp:include page="loginComponent-viewLogin.jsp" />
</jc:render>

<%-- **********************************************************************
     Render Phase: User is logged in. Display user info and logout form.
     ********************************************************************** --%>

<jc:render view="loggedin">
  <jsp:include page="loginComponent-viewLogout.jsp" />
</jc:render>

<%-- **********************************************************************
     Render Phase: Clean messages so they won't display on refresh.
     ********************************************************************** --%>

<jc:render>
  <% session.removeAttribute("MESSAGES"); %>
</jc:render>
</span>

This does not differ much from the sample code used in the "Component lifecycle" section. The major change is that the views are factored out to separate JSP files. The same can be done for any component. Including one file from another is OK, but do not try to forward from included file, this will not work in most servlet containers (forwarding from included JSP fragment works on Resin though).

Login Panel, loginComponent-viewLogin.jsp

The login panel is defined in loginComponent-viewLogin.jsp file:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

  <h3>Log In</h3>

  <form action="loginComponent.jsp" focus="username">
    <table>

      <!-- username and password -->
      <tr>
        <td align="left">Username:</td>
        <td><input type="text"
                   name="username" maxlength="20" size="20"
                   value="<c:out value='${username}'/>" /></td>
      </tr>

      <tr>
        <td align="left">Password:</td>
        <td><input type="password"
                   name="password" maxlength="20" size="20"
                   value="" /></td>
      </tr>

      <!-- Login button-->
      <tr>
        <td></td>
        <td align="left">
          <input type="submit"
                 name="login"
                 value="Log In" />
        </td>
      </tr>
    </table>
  </form>
  <p><em>Username is "user", password is "pass".</em></p>

Logout Panel, lloginComponent-viewLogout.jsp

The logout panel is defined in loginComponent-viewLogout.jsp file and looks similar:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

  <h3>Log Out</h3>

  <form action="loginComponent.jsp">
    <table>

      <!-- User information -->
      <tr>
        <td align="left">Username:</td>
        <td><c:out value="${sessionScope.USER}"/></td>
      </tr>

      <!-- Logout button-->
      <tr>
        <td></td>
        <td align="left">
          <input type="submit"
                 name="logout"
                 value="Log Out" />
        </td>
      </tr>
    </table>
  </form>

When the browser navigates to index.jsp page, the server evaluates the included component, and renders its view as an included fragment. If the user has not logged in yet, the resulting HTML looks like this:

<html>
  <body>
    <style type='text/css'>
      .dottedframe {border: 2px dotted #fa9010; min-width: 30em; padding: 5px;}
    </style>

    <p class="dottedframe">This paragraph is defined directly in the parent page
    and should <strong>precede</strong> the content of login control.</p>

    <div class="dottedframe" id="LoginComponent">

  <h3>Log In</h3>

  <form action="loginComponent.jsp" focus="username">
    <table>

      <!-- username and password -->
      <tr>
        <td align="left">Username:</td>

        <td><input type="text"
                   name="username" maxlength="20" size="20"
                   value="" /></td>
      </tr>

      <tr>
        <td align="left">Password:</td>
        <td><input type="password"
                   name="password" maxlength="20" size="20"
                   value="" /></td>
      </tr>

      <!-- Logoff and cancel buttons-->

      <tr>
        <td></td>
        <td align="left">
          <input type="submit"
                 name="login"
                 value="Log In" />
        </td>
      </tr>
    </table>
  </form>
  <p><em>Username is "user", password is "pass".</em></p>

    </div>

    <p class="dottedframe">This paragraph is defined directly in the parent page
    and should <strong>follow</strong> the content of login control.</p>
  </body>
</html>

See detailed explanation of how this code works in the "Component lifecycle" section.