My project consists of 3 jsps: DVDproduct.jsp, DVDcatalog.jsp, and DVDaddtocart.jsp......
The DVDcatalog.jsp works but DVDproduct.jsp and DVDaddtocart.jsp are both getting the same error of:
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
----
Error: 500
Location: /jsp/DVDaddtocart.jsp
Internal Servlet Error:
javax.servlet.ServletExcep
tion: A property getter for product not found in catalog
Root cause:
javax.servlet.jsp.JspExcep
tion: A property getter for product not found in catalog
at dvdshop.tags.UsePropertyTa
g.getPrope
rty(UsePro
pertyTag.j
ava:140)
at dvdshop.tags.UsePropertyTa
g.doEndTag
(UseProper
tyTag.java
:94)
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
-----
I know that the DVDCatalogBean.java (which is the file that DVDaddtocart.jsp and DVDproduct.jsp are trying to access) is fine because I ran a test on it...but I still can't
find the problem.
UsePropertyTag.java or the jsp's are the only files may be a problem but I don't see anything wrong with it.
thanks,
Warren
Below are the copies of the code:
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
DVDaddtocart.jsp:
__________________________
__________
__________
_____
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" contentType="text/html" %>
<%@ taglib uri="dvdtaglib.tld" prefix="dvd" %>
<%@ page import="java.text.*" %>
<%@ page import="dvdshop.DVDProduct
Bean" %>
<%@ page import="dvdshop.DVDCatalog
Bean" %>
<%@ page import="dvdshop.DVDCartBea
n" %>
<html>
<HEAD>
<META name="GENERATOR" content="IBM WebSphere Studio">
</HEAD>
<body>
hi
<jsp:useBean
id="catalog"
scope="application"
class="dvdshop.DVDCatalogB
ean"
/>
<jsp:useBean
id="cart"
scope="session"
class="dvdshop.DVDCartBean
"
/>
<%-- Get the DVDProductBean from the catalog and save it in the cart --%>
<dvd:useProperty id="product" name="catalog" property="product"
arg='<%= request.getParameter("id")
%>'
className="dvdshop.DVDProd
uctBean" />
<jsp:setProperty name="cart" property="product" value="<%= product %>" />
<%-- Redirect back to the catalog page --%>
<dvd:redirect page="DVDcatalog.jsp" />
</body>
</html>
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_______
DVDproduct.jsp:
__________________________
__________
__________
_______
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" contentType="text/html" %>
<%@ taglib uri="dvdtaglib.tld" prefix="dvd" %>
<%@ page import="java.text.*" %>
<%@ page import="dvdshop.DVDProduct
Bean" %>
<html>
<head>
<title>Product Description</title>
<META name="GENERATOR" content="IBM WebSphere Studio">
</head>
<body bgcolor="white">
<jsp:useBean id="catalog" scope="application" class="dvdshop.DVDCatalogB
ean" />
<%-- Get the DVDProductBean from the catalog --%>
<dvd:useProperty id="product" name="catalog" property="product"
arg="<%= request.getParameter(\"id\
") %>"
className="dvdshop.DVDProd
uctBean" />
<h1>
<jsp:getProperty name="product" property="name" />
</h1>
<jsp:getProperty name="product" property="descr" />
<p>
<a href="<dvd:encodeURL url="DVDaddtocart.jsp">
</dvd:encodeURL>">Add this book to the shopping cart</a>
</body>
</html>
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
DVDcatalog.jsp
__________________________
__________
__________
______
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" contentType="text/html" %>
<%@ taglib uri="dvdtaglib.tld" prefix="dvd" %>
<%@ page import="java.text.*" %>
<%@ page import="dvdshop.DVDProduct
Bean" %>
<%@ page import="dvdshop.DVDCatalog
Bean" %>
<%@ page import="dvdshop.DVDCartBea
n" %>
<html>
<head>
<title>Warren's DVD Store Inc</title>
<META name="GENERATOR" content="IBM WebSphere Studio">
</head>
<body bgcolor="white">
<table width="100%" height="63" border=0 cellpadding=4 cellspacing=0>
<tr bgcolor=9bbad6><td valign=top colspan=4>
<font face=arial size=20>
<b>
<font
size="+3" face="Arial, Helvetica, sans-serif">DVD Store Catalog
</font>
</b>
</tr>
</table>
<br>
Please choose a dvd from our catalog to read the description and
decide if you like to purchase a copy:
<jsp:useBean
id="catalog"
scope="application"
class="dvdshop.DVDCatalogB
ean"
/>
<%-- Generate a list of all products with links to the product page. --%>
<ul>
<dvd:loop name="catalog" property="productList" loopId="product" className="DVDProductBean"
>
<li>
<a href="
<dvd:encodeURL url="DVDproduct.jsp ">
<dvd:param name="id" value="<%= product.getId() %>"/>
</dvd:encodeURL>"><%= product.getName() %>
</a>
</dvd:loop>
</ul>
<jsp:useBean
id="cart"
scope="session"
class="dvdshop.DVDCartBean
"
/>
<%-- Show the contents of the shopping cart, if any --%>
<%
if (!cart.isEmpty()) {
NumberFormat numFormat = NumberFormat.getCurrencyIn
stance();
%>
Your shopping cart contains the following items:
<p>
<table border=0>
<dvd:loop name="cart" property="products" loopId="product" className="DVDProductBean"
>
<tr>
<td><%= product.getName() %></td>
<td><%= numFormat.format(product.g
etPrice())
%></td>
</tr>
</dvd:loop>
<tr><td colspan=2><hr></td></tr>
<tr>
<td><b>Total:</b></td>
<td><%= numFormat.format(cart.getT
otal()) %></td></tr>
</table>
<% } %>
</body>
</html>
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_________
dvdtaglib.tld
__________________________
__________
________
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "
http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibvers
ion>
<jspversion>1.1</jspversio
n>
<shortname>dvd</shortname>
<uri>/dvdtaglib</uri>
<tag>
<name>param</name>
<tagclass>dvdshop.tags.Par
amTag</tag
class>
<bodycontent>JSP</bodycont
ent>
<description>
Adds a parameter to a containing 'import' tag's URL.
</description>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>false</rtexpr
value>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>false</rtexpr
value>
</attribute>
</tag>
<tag>
<name>loop</name>
<tagclass>dvdshop.tags.Loo
pTag1</tag
class>
<teiclass>dvdshop.tags.Loo
pTag1Extra
Info</teic
lass>
<bodycontent>JSP</bodycont
ent>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
</attribute>
<attribute>
<name>loopId</name>
<required>true</required>
</attribute>
<attribute>
<name>className</name>
<required>true</required>
</attribute>
</tag>
<tag>
<name>encodeURL</name>
<tagclass>dvdshop.tags.Enc
odeURLTag<
/tagclass>
<bodycontent>JSP</bodycont
ent>
<info>
Encodes the url attribute and possible param tags in the body
</info>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprv
alue>
</attribute>
</tag>
<tag>
<name>redirect</name>
<tagclass>dvdshop.tags.Red
irectTag</
tagclass>
<bodycontent>JSP</bodycont
ent>
<info>
Encodes the url attribute and possible param tags in the body
and set redirect headers.
</info>
<attribute>
<name>page</name>
<required>true</required>
<rtexprvalue>true</rtexprv
alue>
</attribute>
</tag>
<tag>
<name>useProperty</name>
<tagclass>dvdshop.tags.Use
PropertyTa
g</tagclas
s>
<teiclass>dvdshop.tags.Use
PropertyTa
gExtraInfo
</teiclass
>
<bodycontent>JSP</bodycont
ent>
<info>
Gets a bean property using a getter with a String argument
</info>
<attribute>
<name>id</name>
<required>true</required>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>property</name>
<required>true</required>
</attribute>
<attribute>
<name>arg</name>
<required>false</required>
<rtexprvalue>true</rtexprv
alue>
</attribute>
<attribute>
<name>className</name>
<required>true</required>
</attribute>
</tag>
</taglib>
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_________
EncodeURLTag.java
__________________________
_____
package dvdshop.tags;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
/**
* This class is a custom action for encoding URLs for URL rewriting
* (session tracking) with possible parameter values URL encoded.
* @tagName encodeURL
* @displayName <{EncodeURLTag}>
* @persistent
* @WebService
*
*/
public class EncodeURLTag extends TagSupport implements ParamParent {
private String url;
private Vector params;
/**
* Sets the url attribute.
*
* @param url the page URL value
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Adds a parameter name and value. This method is called by param
* tags in the action body.
*
* @param name the parameter name
* @param value the URL encoded parameter value
*/
public void addParameter(String name, String value) {
if (params == null) {
params = new Vector();
}
Param param = new Param(name, value);
params.addElement(param);
}
/**
* Override the default implementation so that possible
* param actions in the body are processed.
*/
public int doStartTag() {
// Reset per-use state set by nested elements
params = null;
return EVAL_BODY_INCLUDE;
}
/**
* Appends possible URL encoded parameters to the main URL,
* encodes the result for URL rewriting and writes the result
* to the JspWriter.
*/
public int doEndTag() throws JspException {
StringBuffer encodedURL = new StringBuffer(url);
if (params != null && params.size() > 0) {
encodedURL.append('?');
boolean isFirst = true;
Enumeration e = params.elements();
while (e.hasMoreElements()) {
Param p = (Param) e.nextElement();
if (!isFirst) {
encodedURL.append('&');
}
encodedURL.append(p.getNam
e()).appen
d('=').
append(p.getValue());
isFirst = false;
}
}
try {
HttpServletResponse res =
(HttpServletResponse) pageContext.getResponse();
JspWriter out = pageContext.getOut();
out.print(res.encodeURL(en
codedURL.t
oString())
);
}
catch (IOException e) {}
return EVAL_PAGE;
}
/**
* Releases all instance variables.
*/
public void release() {
url = null;
params = null;
super.release();
}
/**
* This is a helper class that holds the name and value of a
* parameter.
*/
class Param {
private String name;
private String value;
public Param(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
________
ParamParent.java
__________________________
_______
package dvdshop.tags;
/**
* <p>Interface for tag handlers implementing valid parent tags for
* <c:param>.</p>
*
* @author Shawn Bayern
*/
public interface ParamParent {
/**
* Adds a parameter to this tag's URL. The intent is that the
* <param> subtag will call this to register URL parameters.
* Assumes that 'name' and 'value' are appropriately encoded and do
* not contain any meaningful metacharacters; in order words, escaping
* is the responsibility of the caller.
*
* @see ParamSupport
*/
void addParameter(String name, String value);
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
ParamSupport.java
__________________________
________
package dvdshop.tags;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
import java.net.URLEncoder;
import java.lang.*;
/**
* <p>Support for tag handlers for <param>, the URL parameter
* subtag for <import> in JSTL 1.0.</p>
*
* @see ParamParent, ImportSupport, URLEncodeSupport
* @author Shawn Bayern
*/
public abstract class ParamSupport extends BodyTagSupport {
//************************
**********
**********
**********
**********
*****
// Private constants
private static final Class[] URL_ENCODER_PARAM_TYPES =
new Class[] { String.class, String.class };
//************************
**********
**********
**********
**********
*****
// Protected state
protected String name; // 'name' attribute
protected String value; // 'value' attribute
/**
* There used to be an 'encode' attribute; I've left this as a
* vestige in case custom subclasses want to use our functionality
* but NOT encode parameters.
*/
protected boolean encode = true;
//************************
**********
**********
**********
**********
*****
// Private state
private static Method encodeMethod1_4 = null;
//************************
**********
**********
**********
**********
*****
// Constructor and initialization
// URLEncoder.encode(String) has been deprecated in J2SE 1.4.
// Take advantage of the new method URLEncoder.encode(String, enc)
// if J2SE 1.4 is used.
static {
try {
Class urlEncoderClass = Class.forName("java.net.UR
LEncoder")
;
encodeMethod1_4 =
urlEncoderClass.getMethod(
"encode",
new Class[] {String.class, String.class});
} catch (Exception ex) {} // encodeMethod1_4 will be null if exception
}
public ParamSupport() {
super();
init();
}
private void init() {
name = value = null;
}
//************************
**********
**********
**********
**********
*****
// Tag logic
// simply send our name and value to our appropriate ancestor
public int doEndTag() throws JspException {
Tag t = findAncestorWithClass(this
, ParamParent.class);
if (t == null)
throw new JspTagException(
Resources.getMessage("PARA
M_OUTSIDE_
PARENT"));
// take no action for null or empty names
if (name == null || name.equals(""))
return EVAL_PAGE;
// send the parameter to the appropriate ancestor
ParamParent parent = (ParamParent) t;
String value = this.value;
if (value == null) {
if (bodyContent == null || bodyContent.getString() == null)
value = "";
else
value = bodyContent.getString().tr
im();
}
if (encode) {
if (encodeMethod1_4 != null) {
Object[] methodArgsName = new Object[2];
methodArgsName[0] = name;
methodArgsName[1] = pageContext.getResponse().
getCharact
erEncoding
();
Object[] methodArgsValue = new Object[2];
methodArgsValue[0] = value;
methodArgsValue[1] = pageContext.getResponse().
getCharact
erEncoding
();
try {
parent.addParameter(
(String)encodeMethod1_4.in
voke(null,
methodArgsName),
(String)encodeMethod1_4.in
voke(null,
methodArgsValue));
} catch (Exception ex) {
throw new JspException("System error invoking URLEncoder.encode() by reflection.");
}
} else {
// must use J2SE 1.3 version
parent.addParameter(
URLEncoder.encode(name), URLEncoder.encode(value));
}
} else {
parent.addParameter(name, value);
}
return EVAL_PAGE;
}
// Releases any resources we may have (or inherit)
public void release() {
init();
}
//************************
**********
**********
**********
**********
*****
// Support for parameter management
/**
* Provides support for aggregating query parameters in URLs.
* Specifically, accepts a series of parameters, ensuring that
* - newer parameters will precede older ones in the output URL
* - all supplied parameters precede those in the input URL
*/
public static class ParamManager {
//************************
*********
// Private state
private List names = new LinkedList();
private List values = new LinkedList();
private boolean done = false;
//************************
*********
// Public interface
/** Adds a new parameter to the list. */
public void addParameter(String name, String value) {
if (done)
throw new IllegalStateException();
if (name != null) {
names.add(name);
if (value != null)
values.add(value);
else
values.add("");
}
}
/**
* Produces a new URL with the stored parameters, in the appropriate
* order.
*/
public String aggregateParams(String url) {
/*
* Since for efficiency we're destructive to the param lists,
* we don't want to run multiple times.
*/
if (done)
throw new IllegalStateException();
done = true;
//// reverse the order of our two lists
// Collections.reverse(this.n
ames);
// Collections.reverse(this.v
alues);
// build a string from the parameter list
StringBuffer newParams = new StringBuffer();
for (int i = 0; i < names.size(); i++) {
newParams.append(names.get
(i) + "=" + values.get(i));
if (i < (names.size() - 1))
newParams.append("&");
}
// insert these parameters into the URL as appropriate
if (newParams.length() > 0) {
int questionMark = url.indexOf('?');
if (questionMark == -1) {
return (url + "?" + newParams);
} else {
StringBuffer workingUrl = new StringBuffer(url);
workingUrl.insert(question
Mark + 1, (newParams + "&"));
return workingUrl.toString();
}
} else {
return url;
}
}
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
______
ParamTag.java
__________________________
__________
_____
package dvdshop.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
//import org.apache.taglibs.standar
d.tag.comm
on.core.*;
//import org.apache.taglibs.standar
d.resource
s.Resource
s;
/**
* <p>A handler for <param> that accepts attributes as Strings
* and evaluates them as expressions at runtime.</p>
*
* @author Shawn Bayern
*/
public class ParamTag extends ParamSupport {
//************************
**********
**********
**********
**********
*****
// 'Private' state (implementation details)
private String name_; // stores EL-based property
private String value_; // stores EL-based property
//************************
**********
**********
**********
**********
*****
// Constructor
/**
* Constructs a new ParamTag. As with TagSupport, subclasses
* should not provide other constructors and are expected to call
* the superclass constructor
*/
public ParamTag() {
super();
init();
}
//************************
**********
**********
**********
**********
*****
// Tag logic
// evaluates expression and chains to parent
public int doStartTag() throws JspException {
// evaluate any expressions we were passed, once per invocation
// evaluateExpressions();
// chain to the parent implementation
return super.doStartTag();
}
// Releases any resources we may have (or inherit)
public void release() {
super.release();
init();
}
//************************
**********
**********
**********
**********
*****
// Accessor methods
// for EL-based attribute
public void setName(String name_) {
this.name_ = name_;
}
public void setValue(String value_) {
this.value_ = value_;
}
//************************
**********
**********
**********
**********
*****
// Private (utility) methods
// (re)initializes state (during release() or construction)
private void init() {
// null implies "no expression"
name_ = value_ = null;
}
/* Evaluates expressions as necessary */
// private void evaluateExpressions() throws JspException {
/*
* Note: we don't check for type mismatches here; we assume
* the expression evaluator will return the expected type
* (by virtue of knowledge we give it about what that type is).
* A ClassCastException here is truly unexpected, so we let it
* propagate up.
*/
// name = (String) ExpressionUtil.evalNotNull
(
// "import", "name", name_, String.class, this, pageContext);
// value = (String) ExpressionUtil.evalNotNull
(
// "import", "value", value_, String.class, this, pageContext);
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
______
UsePropertyTag.java
__________________________
__________
_____
package dvdshop.tags;
//
// Write your code here
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
/**
* This class is a custom action for making a bean property value
* available to other actions and scripting code as a variable.
* The property must be a multi-value property. The getter
* method may take a String argument identifying the one value
* to return.
* @WebService
* @tagName useProperty
* @displayName <{UsePropertyTag}>
* @TEIClass dvdshop.tags.UsePropertyTa
gExtraInfo
* @tagBodyContent TAGDEPENDENT
*
*/
public class UsePropertyTag extends TagSupport {
private String id;
private String name;
private String property;
private String arg;
private String className;
/**
* Sets the id attribute, i.e. the name of the variable to hold the
* reference to the selected property value.
*
* @param id the variable name
*/
public void setId(String id) {
this.id = id;
}
/**
* Sets the name attribute, i.e. the name of the variable holding the
* reference to the bean with the property to retrieve.
*
* @param name the bean name
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the property attribute, i.e. the name of the property to
* retrieve.
*
* @param property the property name
*/
public void setProperty(String property) {
this.property = property;
}
/**
* Sets the arg attribute, i.e. the String argument value used
* by the property getter method to select on of multiple property
* values.
*
* @param arg the String argument value
*/
public void setArg(String arg) {
this.arg = arg;
}
/**
* Sets the class attribute, i.e. the class name for the property
* value.
*
* @param className the property class name
*/
public void setClassName(String className) {
this.className = className;
}
/**
* Retrieves one value of a multi-valued property in the specified
* bean using a getter method with a String argument. The value is
* saved with the specified variable name in the page scope.
*/
public int doEndTag() throws JspException {
Object obj = pageContext.findAttribute(
name);
if (obj == null) {
throw new JspException("Variable " + name + " not found");
}
Object propObj = getProperty(obj, property, className);
pageContext.setAttribute(i
d, propObj);
return SKIP_BODY;
}
/**
* Releases all instance variables.
*/
public void release() {
id = null;
name = null;
property = null;
arg = null;
className = null;
super.release();
}
/**
* Returns the value of the specified property from the
* specified bean.
*
* @param bean the bean
* @param property the property name
* @param propertyClassName the property class name (type)
*/
private Object getProperty(Object bean, String property,
String propClassName) throws JspException {
Object propObj = null;
Class beanClass = bean.getClass();
Class[] params = null;
if (arg != null) {
// If an arg is specified, it must be a String arg
params = new Class[1];
params[0] = String.class;
}
Method method = null;
try {
/*
* Since the method may have an arg, look for it explicitly
* instead of using the standard property lookup method
*/
method = beanClass.getMethod("get" +
property.substring(0, 1).toUpperCase() + property.substring(1),
params);
}
catch (NoSuchMethodException e) {
throw new JspException("A property getter for " + property +
(arg != null ? " with a String argument" : "") +
" not found in " + name);
}
Class propClass = null;
try {
propClass = Class.forName(propClassNam
e);
}
catch (ClassNotFoundException e) {
throw new JspException("Property class " + propClassName + " not found");
}
Class returnType = method.getReturnType();
if (!propClass.isAssignableFr
om(returnT
ype)) {
throw new JspException("Property " + property + " is not a " + className);
}
Object[] args = null;
if (arg != null) {
args = new Object[1];
args[0] = arg;
}
try {
propObj = method.invoke(bean, args);
}
catch (Exception e) {
throw new JspException("Failed to get property " + property + " from " + name);
}
return propObj;
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_______
UsePropertyTagExtraInfo.ja
va
__________________________
__________
____
/* Generated by Together */
package dvdshop.tags;
import javax.servlet.jsp.tagext.T
agExtraInf
o;
import javax.servlet.jsp.tagext.V
ariableInf
o;
import javax.servlet.jsp.tagext.T
agData;
public class UsePropertyTagExtraInfo extends TagExtraInfo {
public VariableInfo[] getVariableInfo(TagData data) {
return new VariableInfo[]
{
new VariableInfo (data.getAttributeString("
id"),
data.getAttributeString("c
lassName")
,
true,
VariableInfo.AT_END)
};
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_____
RedirectTag.java
__________________________
__________
_____
package dvdshop.tags;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
/**
* This class is a custom action for sending a redirect request,
* with possible parameter values URL encoded and the complete URL
* encoded for URL rewriting (session tracking).
* @tagName redirect
* @displayName <{RedirectTag}>
* @persistent
* @WebService
*/
public class RedirectTag extends TagSupport implements ParamParent {
private String page;
private Vector params;
/**
* Sets the page attribute.
*
* @param page the page URL to redirect to
*/
public void setPage(String page) {
this.page = page;
}
/**
* Adds a parameter name and value. This method is called by param
* tags in the action body.
*
* @param name the parameter name
* @param value the URL encoded parameter value
*/
public void addParameter(String name, String value) {
if (params == null) {
params = new Vector();
}
Param param = new Param(name, value);
params.addElement(param);
}
/**
* Override the default implementation so that possible
* param actions in the body are processed.
*/
public int doStartTag() {
// Reset per-use state set by nested elements
params = null;
return EVAL_BODY_INCLUDE;
}
/**
* Appends possible URL encoded parameters to the main URL,
* encodes the result for URL rewriting. Clears the out buffer
* and sets the redirect response headers. Returns SKIP_PAGE
* to abort the processing of the rest of the page.
*/
public int doEndTag() throws JspException {
StringBuffer encodedURL = new StringBuffer(page);
if (params != null && params.size() > 0) {
encodedURL.append('?');
boolean isFirst = true;
Enumeration e = params.elements();
while (e.hasMoreElements()) {
Param p = (Param) e.nextElement();
if (!isFirst) {
encodedURL.append('&');
}
encodedURL.append(p.getNam
e()).appen
d('=').app
end(p.getV
alue());
isFirst = false;
}
}
try {
JspWriter out = pageContext.getOut();
out.clear();
HttpServletResponse res = (HttpServletResponse) pageContext.getResponse();
res.sendRedirect(res.encod
eURL(encod
edURL.toSt
ring()));
}
catch (IOException e) {}
return SKIP_PAGE;
}
/**
* Releases all instance variables.
*/
public void release() {
page = null;
params = null;
super.release();
}
/**
* This is a helper class that holds the name and value of a
* parameter.
*/
class Param {
private String name;
private String value;
public Param(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
DVDCartBean.java
__________________________
______
package dvdshop;
import java.io.*;
import java.util.*;
/**
* This class represents a shopping cart. It holds a list of products.
* @persistent
*
*/
public class DVDCartBean implements Serializable {
private Vector cart = new Vector();
/**
* Adds a product to the cart, if it's not already there.
*
* @param product the DVDProductBean
*/
public void setProduct(DVDProductBean product) {
if (product != null && cart.indexOf(product) == -1) {
cart.addElement(product);
}
}
/**
* Returns the product list.
*
* @return an Enumeration of DVDProductBeans
*/
public Enumeration getProducts() {
return cart.elements();
}
/**
* Returns the total price for all products in the cart
*
* @return the total price
*/
public float getTotal() {
float total = 0;
Enumeration prods = getProducts();
while (prods.hasMoreElements()) {
DVDProductBean product = (DVDProductBean) prods.nextElement();
float price = product.getPrice();
total += price;
}
return total;
}
/**
* Returns true if the cart is empty
*
* @return true if the cart is empty
*/
public boolean isEmpty() {
return cart.size() == 0;
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
________
DVDCatalogBean.java
__________________________
__________
__
package dvdshop;
import java.io.*;
import java.util.*;
/**
* This class represents a dvd product catalog. It holds a list of
* products available for sale.
* <p>
* This is just a demo so the product list is hardcoded, created
* at instantiation. A real version would get the information from
* an external data source.
* @persistent
*
*/
public class DVDCatalogBean implements Serializable {
/*
public static void main(String[] args)
{
DVDCatalogBean db = new DVDCatalogBean();
for(int i = 0; i < db.catalog.size(); i++)
System.out.println(db.cata
log.elemen
tAt(i));
}
*/
private Vector catalog = new Vector();
/**
* Constructor. Creates all ProductBean objects and adds them
* to the catalog.
*/
public DVDCatalogBean() {
DVDProductBean prod = new DVDProductBean();
prod.setId("1");
prod.setName("Robotech");
prod.setDescr("One of my favorite animated series growing up where robots turn into jet planes and defends the Earth.");
prod.setPrice(32.95f);
catalog.addElement(prod);
prod = new DVDProductBean();
prod.setId("2");
prod.setName("Transfomer")
;
prod.setDescr("Ever wondered what those stupid robotic symbols on cars meant? Well, you'll find the answer to this on my wall or here where robots battle each
other in disguise as automobiles and deceptive planes for the control of Earth.");
prod.setPrice(32.95f);
catalog.addElement(prod);
prod = new DVDProductBean();
prod.setId("3");
prod.setName("Indiana Jones");
prod.setDescr("A classic. This unique trilogy stars Harrison Ford and is directed by Steven Spielberg and produced by George Lucas- 'nough said (somethig about
saving the planet Earth).");
prod.setPrice(32.95f);
catalog.addElement(prod);
}
/**
* Returns a list of all products.
*
* @return a Enumeration with ProductBean elements
*/
public Enumeration getProductList() {
System.out.println("Produc
tList");
return catalog.elements();
}
/**
* Returns one product, or throws an exception if not found
*
* @param id the product id. The String version is to be able
* to use the useProperty action
* @return a ProductBean
* @exception Exception if the id doesn't match a product
*/
public DVDProductBean getProduct(String id) throws Exception {
boolean isFound = false;
DVDProductBean product = null;
Enumeration prods = getProductList();
while (prods.hasMoreElements()) {
product = (DVDProductBean) prods.nextElement();
if (product.getId().equals(id
)) {
isFound = true;
break;
}
}
if (!isFound) {
throw new Exception("Product id " + id + " doesn't match a product");
}
return product;
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_______
DVDProductBean.java
__________________________
__________
____
package dvdshop;
import java.io.*;
/**
This class represents a product. It holds information about the
product's name, description and price. All setter methods have
package scope, since they are only used by the the CatalogBean.
@persistent
*/
public class DVDProductBean implements Serializable {
private String id;
private String name;
private String descr;
private float price;
/**
* Returns the product id.
*
* @return the product id
*/
public String getId() {
return id;
}
/**
* Returns the product name.
*
* @return the product name
*/
public String getName() {
return name;
}
/**
* Returns the product description.
*
* @return the product description
*/
public String getDescr() {
return descr;
}
/**
* Returns the product price.
*
* @return the product price
*/
public float getPrice() {
return price;
}
/**
* Sets the product id.
*
* @param id the product id
*/
void setId(String id) {
this.id = id;
}
/**
* Sets the product name.
*
* @param name the product name
*/
void setName(String name) {
this.name = name;
}
/**
* Sets the product description.
*
* @param descr the product description
*/
void setDescr(String descr) {
this.descr = descr;
}
/**
* Sets the product price.
*
* @param price the product price
*/
void setPrice(float price) {
this.price = price;
}
public String toString()
{
return "" + this.getId() + this.getName() + this.getPrice() + this.getDescr();
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
____
All the other classes should not be a concern:
ELException.java
NullAttributeException.jav
a
Resources.java
LoopTag1.java
LoppTag1ExtraInfo.java
But here it is anyway:
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
_________
ELException.java
__________________________
__________
_____
package dvdshop.tags;
import java.text.MessageFormat;
/**
*
* Represents any of the exception conditions that arise during the
* operation evaluation of the evaluator.
*
* @author Nathan Abramson - Art Technology Group
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: arista $
**/
public class ELException
extends Exception
{
//------------------------
----------
---
// Member variables
//------------------------
----------
---
Throwable mRootCause;
//------------------------
----------
---
/**
*
* Constructor
**/
public ELException ()
{
super ();
}
//------------------------
----------
---
/**
*
* Constructor
**/
public ELException (String pMessage)
{
super (pMessage);
}
//------------------------
----------
---
/**
*
* Constructor
**/
public ELException (Throwable pRootCause)
{
mRootCause = pRootCause;
}
//------------------------
----------
---
/**
*
* Constructor
**/
public ELException (String pMessage,
Throwable pRootCause)
{
super (pMessage);
mRootCause = pRootCause;
}
//------------------------
----------
---
/**
*
* Returns the root cause
**/
public Throwable getRootCause ()
{
return mRootCause;
}
//------------------------
----------
---
/**
*
* String representation
**/
public String toString ()
{
if (getMessage () == null) {
return mRootCause.toString ();
}
else if (mRootCause == null) {
return getMessage ();
}
else {
return getMessage () + ": " + mRootCause;
}
}
//------------------------
----------
---
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
___
LoopTag1.java
__________________________
__________
______
package dvdshop.tags;
import java.beans.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*
;
/**
* This class is a custom action for looping through the elements
* of a multi-valued bean or bean property. The bean or bean property
* must be an array, a Vector, a Dictionary or an Enumeration. The
* action body is evaluated once for each element.
* @TEIClass dvdshop.tags.LoopTag1Extra
Info
* @tagName loop
* @displayName <{LoopTag1}>
*
*/
public class LoopTag1 extends BodyTagSupport {
// Property variables
private String name;
private String property;
private String loopId;
private String className;
// Enumeration used for iteration
private Enumeration enum;
/**
* Sets the name attribute, i.e. the name of the variable holding
* a reference to the bean with the multi-value property to loop
* through.
*
* @param name the bean variable name
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the property attribute, i.e. the name of the multi-value
* property to loop through.
*
* @param property the property name
*/
public void setProperty(String property) {
this.property = property;
}
/**
* Sets the loopId attribute, i.e. the name of the variable to
* hold the element reference in the body.
*
* @param property the property name
*/
public void setLoopId(String loopId) {
this.loopId = loopId;
}
/**
* Sets the class attribute, i.e. the name of the class for the
* multi-value property elements.
*
* @param class the element class name
*/
public void setClassName(String className) {
this.className = className;
}
/**
* Creates an Enumeration of all loop values, either using the object
* specified by the name attribute directly, or using the specified
* property. The object or the property must be one of Enumeration,
* Vector, Dictionary or Object[] (no primitive type arrays), or a
* subclass/subinterface of one of them.
*
* Makes the first element available to the body in a variable
* with the name specified by the loopId attribute.
*/
public int doStartTag() throws JspException {
Object obj = pageContext.findAttribute(
name);
if (obj == null) {
throw new JspException("Variable " + name + " not found");
}
Object mvObj = obj;
try {
// Get the multi-value object using the specified property getter
// method, if any
if (property != null) {
mvObj = getProperty(obj, property);
}
enum = getEnumeration(mvObj);
}
catch (JspException e) {
throw new JspException("Error getting loop data from " + name + ": " +
e.getMessage());
}
// Set the first loop value, if any
if (enum != null && enum.hasMoreElements()) {
Object currValue = enum.nextElement();
pageContext.setAttribute(l
oopId, currValue);
return EVAL_BODY_TAG;
}
else {
return SKIP_BODY;
}
}
/**
* Makes the next element available to the body in a variable
* with the name specified by the loopId attribute, or returns
* SKIP_BODY if all elements have been processed.
*/
public int doAfterBody() throws JspException {
if (enum.hasMoreElements()) {
Object currValue = enum.nextElement();
pageContext.setAttribute(l
oopId, currValue);
return EVAL_BODY_TAG;
}
else {
return SKIP_BODY;
}
}
/**
* Writes the accumulated body contents to the JspWriter.
*/
public int doEndTag() throws JspException {
// Test if bodyContent is set, since it will be null if the
// body was never evaluated (doStartTag returned SKIP_BODY)
if (getBodyContent() != null) {
try {
getPreviousOut().print(get
BodyConten
t().getStr
ing());
}
catch (IOException e) {}
}
return EVAL_PAGE;
}
/**
* Releases all instance variables.
*/
public void release() {
name = null;
property = null;
loopId = null;
className = null;
enum = null;
super.release();
}
/**
* Returns an Object representing an Enumeration, a Vector,
* a Dictionary or an array of objects (no primitive types),
* using the specified property getter method on the specified
* object.
*
* @param obj the Object with the multi-value property
* @param property the property name
* @return the multi-value Object
*/
private Object getProperty(Object obj, String property) throws JspException {
Object mvObj = null;
Method method = null;
try {
BeanInfo beanInfo = Introspector.getBeanInfo(o
bj.getClas
s());
PropertyDescriptor[] pds = beanInfo.getPropertyDescri
ptors();
for (int i = 0; pds != null && i < pds.length; i++) {
if (pds[i].getName().equals(p
roperty)) {
method = pds[i].getReadMethod();
break;
}
}
}
catch (IntrospectionException e) {
throw new JspException("Error analyzing the bean class: " +
e.getMessage());
}
if (method == null) {
throw new JspException("Property " + property + " not found");
}
// Make sure the property is not of a primitive type
if (method.getReturnType().is
Primitive(
)) {
throw new JspException("Invalid property data type");
}
// Invoke the method to get the multi-value Object
Object[] args = {};
try {
mvObj = method.invoke(obj, args);
}
catch (Exception e) {
throw new JspException("Failed to get property " + property + ": " +
e.getMessage());
}
return mvObj;
}
/**
* Returns an Enumeration of the values in the specified multi-value
* object, which can be an Enumeration, Vector, Dictionary or array
* of Objects (not primitive types).
*
* @param obj the multi-value Object
* @return an Enumeration
* @exception JspException if invalid type
*/
private Enumeration getEnumeration(Object obj) throws JspException {
if (obj == null) {
return null;
}
Enumeration enum = null;
if (Enumeration.class.isAssig
nableFrom(
obj.getCla
ss())) {
enum = (Enumeration) obj;
}
else if (Vector.class.isAssignable
From(obj.g
etClass())
) {
enum = ((Vector) obj).elements();
}
else if (Dictionary.class.isAssign
ableFrom(o
bj.getClas
s())) {
enum = ((Dictionary) obj).elements();
}
else if (obj.getClass().isArray())
{
Object[] oa = (Object[]) obj;
Vector v = new Vector(oa.length);
for (int i = 0; i < oa.length; i++) {
v.addElement(oa[i]);
}
enum = v.elements();
}
else {
throw new JspException("Invalid data type");
}
return enum;
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
LoopTagExtraInfo.java
__________________________
__________
_____
/* Generated by Together */
package dvdshop.tags;
import javax.servlet.jsp.tagext.T
agExtraInf
o;
import javax.servlet.jsp.tagext.V
ariableInf
o;
import javax.servlet.jsp.tagext.T
agData;
public class LoopTag1ExtraInfo extends TagExtraInfo {
public VariableInfo[] getVariableInfo(TagData data) {
return new VariableInfo[]
{
new VariableInfo(data.getAttri
buteString
("loopId")
,
data.getAttributeString("c
lassName")
,
true,
VariableInfo.NESTED)
};
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
NullAttributeException.jav
a
__________________________
__________
______
package dvdshop.tags;
import javax.servlet.jsp.JspTagEx
ception;
/**
* <p>NullAttributeException is a JspTagException that will be thrown
* by the JSTL RI handlers when a tag attribute illegally evaluates
* to 'null'.</p>
*
* @author Shawn Bayern
*/
public class NullAttributeException extends JspTagException {
/**
* Constructs a NullAttributeException with appropriate information.
*
* @param tag The name of the tag in which the error occurred.
* @param att The attribute value for which the error occurred.
*/
public NullAttributeException(Str
ing tag, String att) {
super(Resources.getMessage
("TAG_NULL
_ATTRIBUTE
", att, tag));
}
}
__________________________
__________
__________
__________
__________
__________
__________
__________
__________
__________
_
Resources.java
__________________________
__________
_____
package dvdshop.tags;
import java.util.*;
import java.text.*;
/**
* <p>Provides locale-neutral access to string resources. Only the
* documentation and code are in English. :-)
*
* <p>The major goal, aside from globalization, is convenience.
* Access to resources with no parameters is made in the form:</p>
* <pre>
* Resources.getMessage(MESSA
GE_NAME);
* </pre>
*
* <p>Access to resources with one parameter works like</p>
* <pre>
* Resources.getMessage(MESSA
GE_NAME, arg1);
* </pre>
*
* <p>... and so on.</p>
*
* @author Shawn Bayern
*/
public class Resources {
//************************
**********
**********
**********
**********
*****
// Static data
/** The location of our resources. */
private static final String RESOURCE_LOCATION
= "org.apache.taglibs.standa
rd.resourc
es.Resourc
es";
/** Our class-wide ResourceBundle. */
private static ResourceBundle rb =
ResourceBundle.getBundle(R
ESOURCE_LO
CATION);
//************************
**********
**********
**********
**********
*****
// Public static methods
/** Retrieves a message with no arguments. */
public static String getMessage(String name)
throws MissingResourceException {
return rb.getString(name);
}
/** Retrieves a message with arbitrarily many arguments. */
public static String getMessage(String name, Object[] a)
throws MissingResourceException {
String res = rb.getString(name);
return MessageFormat.format(res, a);
}
/** Retrieves a message with one argument. */
public static String getMessage(String name, Object a1)
throws MissingResourceException {
return getMessage(name, new Object[] { a1 });
}
/** Retrieves a message with two arguments. */
public static String getMessage(String name, Object a1, Object a2)
throws MissingResourceException {
return getMessage(name, new Object[] { a1, a2 });
}
/** Retrieves a message with three arguments. */
public static String getMessage(String name,
Object a1,
Object a2,
Object a3)
throws MissingResourceException {
return getMessage(name, new Object[] { a1, a2, a3 });
}
/** Retrieves a message with four arguments. */
public static String getMessage(String name,
Object a1,
Object a2,
Object a3,
Object a4)
throws MissingResourceException {
return getMessage(name, new Object[] { a1, a2, a3, a4 });
}
/** Retrieves a message with five arguments. */
public static String getMessage(String name,
Object a1,
Object a2,
Object a3,
Object a4,
Object a5)
throws MissingResourceException {
return getMessage(name, new Object[] { a1, a2, a3, a4, a5 });
}
/** Retrieves a message with six arguments. */
public static String getMessage(String name,
Object a1,
Object a2,
Object a3,
Object a4,
Object a5,
Object a6)
throws MissingResourceException {
return getMessage(name, new Object[] { a1, a2, a3, a4, a5, a6 });
}
}
__________________________
__________
__________
__________
__________
__________
__________
__