JSP (and Servlets) Random Notes

Until I find time to get more organized, which will probably never happen given how old and decreasingly necessary this technology is, here are a number of miscellaneous notes assembled when I find answers to JSP questions and don't want to have to go looking for them again.


POST oder GET : es ist die Frage

The advantage of using GET is a clear command line.

The advantages of using POST are:


Default POST action

When a JSP is posted without an explicit action, the behavior is to re-enter that JSP. Here, imagine one.jsp

	<%
	  /* farkle, starting out empty, will be filled in by the user, then
	   * transmitted to another.jsp when the Go button is clicked.
	   *
	   * (Unless passed into this JSP (one.jsp?farkle=something), farkle
	   * has no value to be got by this embedded Java code.
	   */
	  String  farkle = Parm.returnRequestMember( request, "farkle" ).trim();
	%>

	<form method="post" action="another.jsp">
	  <input type="text" name="farkle" value="<%=farkel %>" />
	  .
	  .
	  .
	  <input type="submit" value="Go" />
	</form>

When the submit button is clicked, the JSP containing the code above will launch another.jsp, while the following code will simply re-enter the current one. This is useful if you want to stay with the current one because of your UI design.

	<%
	  /* farkle, starting out empty the first time, will be filled in the
	   * next time through this JSP.
	   *
	   * (Unless passed into this JSP (one.jsp?farkle=something), farkle
	   * has no value to be got by this embedded Java code the first time around.
	   */
	  String  farkle = Parm.returnRequestMember( request, "farkle" ).trim();
	%>

	<form method="post">
	  <input type="text" name="farkle" value="<%=farkel %>" />
	  .
	  .
	  .
	  <input type="submit" value="Go" />
	</form>

Java servlet filters

Servlet filters are components that intercept and modify, for example, HTTP requests and responses from the server. For example, you might want to check the session used in a request to ensure it is current before allowing access to a page. This can be done on one or more pages as appropriate and, if not current, invoke authentication, e.g.: login.jsp so that the user can make it current.

Some cool uses of filters include:

	package com.etretatlogiciels.servlet.filter;

	import java.io.IOException;
	import java.util.Date;

	import javax.servlet.Filter;
	import javax.servlet.FilterChain;
	import javax.servlet.FilterConfig;
	import javax.servlet.ServletException;
	import javax.servlet.ServletRequest;
	import javax.servlet.ServletResponse;
	import javax.servlet.http.HttpServletRequest;

	public class LogFilter implements Filter
	{
	  /**
	   * Implement the actual filter, in this case, the information logging. Here
	   * can request, session or response information be modified, attributes added,
	   * etc.
	   */
	  public void doFilter( ServletRequest  req,
	                        ServletResponse res,
	                        FilterChain     chain)
	    throws IOException, ServletException
	  {
	    HttpServletRequest request = ( HttpServletRequest ) req;

	    // get the IP address of client machine...
	    String ipAddress = request.getRemoteAddr();

	    // log the IP address and current timestamp...
	    System.out.println( "Filter working!\nIP "
	                        + ipAddress
	                        + ", Time "
	                        + new Date().toString() );

	    chain.doFilter(req, res);
	  }

	  /**
	   * FilterConfig is passed from web.xml and contains
	   * Filter-level information and init parameters.
	   */
	  public void init( FilterConfig config ) throws ServletException
	  {
	      // get init parameter...
	      String testParam = config.getInitParameter( "test-param" );

	      // print the init parameter...
	      System.out.println( "Test Param: " + testParam );
	  }

	  /**
	   * This will be called by the container to garbage-collect if the filter hasn't
	   * been used for a while.
	   */
	  public void destroy()
	  {
	      //add code to release any resource
	  }
	}

This is combined with additions to a deployment file:

	<?xml version="1.0" encoding="UTF-8"?>
	<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	         xmlns="http://java.sun.com/xml/ns/javaee"
	         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	         id="WebApp_ID"
	         version="2.5">
	  <display-name>ServletFilterProject</display-name>
	  <welcome-file-list>
	    <welcome-file>index.html</welcome-file>
	    <welcome-file>index.htm</welcome-file>
	    <welcome-file>index.jsp</welcome-file>
	    <welcome-file>default.html</welcome-file>
	    <welcome-file>default.htm</welcome-file>
	    <welcome-file>default.jsp</welcome-file>
	  </welcome-file-list>

	  <filter>
	    <filter-name>LogFilter</filter-name>
	    <filter-class>
	      com.etretatlogiciels.servlet.filter.LogFilter
	    </filter-class>
	    <init-param>
	      <param-name>test-param</param-name>
	      <param-value>This parameter is for testing.</param-value>
	    </init-param>
	  </filter>
	  <filter-mapping>
	    <filter-name>LogFilter</filter-name>
	    <url-pattern>/*</url-pattern>
	  </filter-mapping>
	</web-app>

If we were identifying requests that needed to be authenticated, we could verify whether a session was current or not. We'd insert code similar to this:

	    .
	    .
	    .
	    HttpServletRequest  req = ( HttpServletRequest ) request;
	    HttpServletResponse res = ( HttpServletResponse ) response;

	    boolean             authorized   = false;
	    String              fileName     = "";
	    String              parentFolder = "";

	    int i = request.getRequestURI().lastIndexOf('/');

	    if( i > -1 )
	    {
	      fileName = request.getRequestURI().substring( i );

	      int j = request.getRequestURI().lastIndexOf( '/', i-1 );

	      if( j > -1 )
	        parentFolder = request.getRequestURI().substring( j );
	    }

	    request.setCharacterEncoding( "UTF-8" );
	    response.addHeader( "Expires", "-1" );

	    /* Check all pages to see if the user is properly logged in. The only ones not
	     * subject to this check are index.jsp and login.jsp (of course).
	     *
	     * If not logged in, redirect to login.jsp.
	     */
	    if (
	           !fileName.equals(" /index.jsp" )
	        && !fileName.equals(" /login.jsp" )
	       )
	    {
	      HttpSession session = request.getSession(false);

	      if( session != null )
	        authorized = isLoggedIn( session );

	      if( !authorized )
	      {
	        if( session != null )
	          session.invalidate();

	        log.debug( "Unauthorized access detected from "
	                   + request.getRemoteAddr()
	                   + "  ... redirecting to login page.");

	        RequestDispatcher r = req.getRequestDispatcher( "/login.jsp" );
	        r.forward(req, res);
	        return;
	      }
	    }
	  }

	  // pass along to next filter
	  chain.doFilter( request, response );
	}

	private boolean isLoggedIn( HttpSession session )
	{
	  Object o = session.getAttribute( "logged_in" );

	  return( o != null );
	}

Servlet parameters

Yet more servlet stuff. This is a means of communication between two applications via HTTP.

An HTTP servlet accepts the following URI consisting of

  1. protocol
  2. domain
  3. port-number
  4. path
  5. method
  6. method-name
  7. parameter
  8. value
  9. etc.

...assuming servlet.jsp is written to accept a method, name and parameters parm1 and parm2. The parameters come back by means of HttpServletRequest.getParameters( name ). The method and name pair is just another parameter and its value, and it could appear unorthogonally anywhere including the end of the URI. You have to be looking for by name to see if it's there.


	http://127.0.0.1:8080/Servlet/myservlet.jsp?method=name&parm1=value&parm2=value
	^       ^        ^    ^-------------------- ^      ^    ^     ^     ^     ^
	|       |        |    |                     |      |    |     |     |     |
	|       |        |    |                     |      |    |     |     |     value
	|       |        |    |                     |      |    |     |     parm
	|       |        |    |                     |      |    |     value
	|       |        |    |                     |      |    parm
	|       |        |    |                     |      method-name
	|       |        |    |                     method
	|       |        |    servlet-name and path
	|       |        port-number
	|       domain
	protocol

In Java, ...

	class MyServlet
	{
	  public static void processMethod1( String parm1, String parm2 )
	  {
	    // do first method processing...
	  }

	  public static void processMethod2( String parm1, int parm2 )
	  {
	    // do second method processing...
	  }
	}

...and in the JSP the processing is dispatched thus:

	<%
	String method = request.getParameter( "method" );

	if( method.equals( "method_1" ) )
	  MyServlet.processMethod1( request.getParameter( "parm1" ),
	                            request.getParameter( "parm2" ) );
	else if( method.equals( "method_2" ) )
	  MyServlet.processMethod1( request.getParameter( "parm1" ),
	                            Integer. parseInt( request.getParameter( "parm2" ) ) );
	%gt;

...etc. Obviously, different methods can have different parameters (or different types.


More servlet parameters

More ReSTful style in combination with query parameters (which aren't strictly speaking ReSTful)...


https://acme.com:8080/cloudmgr/account/address/3498FA32BD?city=Seattle&street=Posner%20Boulevard

^       ^        ^    ^        ^       ^       ^          ^    ^       ^      ^
|       |        |    |        |       |       |          |    |       |      |
|       |        |    |        |       |       |          |    |       |      value
|       |        |    |        |       |       |          |    |       query-parm
|       |        |    |        |       |       |          |    value
|       |        |    |        |       |       |          query-parm
|       |        |    |        |       |       path-parm (address id)
|       |        |    |        |       path-element
|       |        |    |        path-element
|       |        |    servlet-name
|       |        port-number
|       domain-name
protocol

Scope in JSP

A JSP object is available for use from different places in the application

Page, session and application scope example

example.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Page, Session or Application Scope Example</title>
</head>
<body>
    <c:set var="name" value="Russ" scope="page|session|application" />
    Local Variable : <c:out value="${name}" />
    <a href="test.jsp">Click this link</a>
</body>
</html>
test.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Page, Session or Application Scope Example: Page Two</title>
</head>
<body>
    <h2> Variable defined on previous page: <c:out value="${name}" /> </h2>
</body>
</html>

Only one of page, session or application may be coded in the above.

Page scope: If the link were clicked in the above example, ${name} would be printed, but no longer available for use in test.jsp where it would be undefined.

Session scope: If the link were clicked in the above example, ${name} would be printed, but also available for use in test.jsp assuming this code executed during the same session, which is likely the case since switching pages does not end the session.

Application scope: If the link were clicked in the above example, ${name} would be printed, but also available for use in test.jsp. ${name} is like a global variable in a programming language like Pascal, an extern static in C, etc.

Request scope example

example.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Request Scope Example</title>
</head>
<body>
    <c:set var="name" value="Russ" scope="request" />
    <jsp:forward page="test.jsp"></jsp:forward>
</body>
</html>
test.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Request Scope Example: Page Two</title>
</head>
<body>
    <h2> Variable defined on previous page: <c:out value="${name}" /> </h2>
</body>
</html>

On the first page of the second JSP ( test.jsp), the one that's the object of the forwarding request, ${name} is defined and will print "Russ".

Session scope example

This example is identical to the application-scope example except for scope="session". %{name} is only visible during the same session as when it was defined.