String
instead
of calling out.println
if ..else if ... else if ... else
to test for buttons.
Problem: The primary problem is that all properties that are defined in BeanInfo, must also be defined in the Bean.
Solution 1: Carefully inspect the BeanInfo and be sure that you have not defined property descriptors for properties that do not exist in the Bean.
Solution 2: See: Avoid BeanInfo
Problem: Using complex Beans without using a BeanInfo class
Solution: Do not call populateBean. Do the initialization yourself. If you
have a String[]
for a multiple selection list or a checkbox,
then you normally need to use populateBean and a BeanInfo class to initialize
your Bean. It is possible to use request.getParameter
and
request.getParamterValues
to initialize the Bean yourself.
Example: Using BidServlet with the complexBean BidInfo that has a
String[]
of options.
BidInfo bid = new BidInfo();
bid.setBidPrice( request.getParameter("bidPrice") );
bid.setItemName( request.getParameter("itemName") );bid.setOptions( request.getParameterValues("options") );
etc.
Notice that the options
property is filled using
getParamterValues
. You could actually use
getParameterValues
for all properties, since this method will
return a single value or an array.
See: BeanInfo doesn't work.
String
Trick: Instead of displaying output when it is created, accumulate the output
in a String
, and display it later.
Advantage: This gives you more control over the appearance of the output. It is possible to create all of the output in different strings, and then to display them in any order you wish.
Example: Here is a method that generates its output as it is testing.
public void isValid(BidInfo bid) { if (bid.getPrice() < 1.0) { out.println("Price must be at least $1.0"); } if (bid.getItemName().trim().indexOf(" ") >= 0) { out.println("ItemNames must be one word"); } }
Here is a more flexible version that stores the output in a
String
and returns it to the calling method. This gives the
calling method more control over when the output will be displayed.
public String isValid(BidInfo bid) { String result = ""; if (bid.getPrice() < 1.0) { result += "Price must be at least $1.0"; } if (bid.getItemName().trim().indexOf(" ") >= 0) { result += "ItemNames must be one word"; } return result; }
It has the further advantage of being able to test if an error existed. If the return value is "", then no errors were generated, so the input data must be valid.
Problem: If nothing is selected in a multiple selection list or checkbox, then a Null Pointer exception occurs.
Solution: If a radio, checkbox or option is not selected, then there is nothing
in the Query String for these form elements. This means that
getParamterValues
will return null
. It also means
that a bean property for any of these will also return null
.
Any time you have a possiblity of a null
, you must guard against
it.
Example:
String[] options = bid.getOptions();
if (options != null) { for (i=0; i<options.length; i++) { .... } }
Without the explicit test for null
, this code would crash if
no options were selected.
if
..else if ... else if
... else
to test for buttons
Trick: Using if .. else if
insures that only one page is being
called.
Suppose you have three buttons in your form
<input type="submit" name="edit" value="Edit"> <input type="submit" name="confirm" value="Confirm"> <input type="submit" name="update" value="Update">The following code in your servlet would test which button was pressed
if (request.getParameter( "edit" ) != null) { //code for edit } else if (request.getParameter( "confirm" ) != null) { //code for confirm } else if (request.getParameter( "update" ) != null) { //code for update } else { //default }
Trick: Place validation routines in the bean so that they can be accessed anywhere that the bean can be accessed
Advantage: All the variables and methods of the Bean are available.
Example:
public String validPrice() { String result = ""; if (this.price < 1.00) { result += "Price must be at least $1.00"; } return result; }
Trick: For each property that is being validated, create error properties as well. They can be accessed anywhere that the bean can be accessed.
Advantage: All the variables and methods of the Bean are available. They can be incorporated with validation routines to simplify error processing.
Note: This does not have to be the actual error message that is displayed in the validataion routine. It could be anything (like a style?????).
Example:
private String priceError = ""; public void setPriceError(String error) {
priceError = error; } public String getPriceError() { return priceError; }
Example of a validation routine that uses this
public String validPrice() { String result = ""; setPriceError(""); if (this.price < 1.00) { setPriceError("Bad dog, no biscuit"); //or something more useful????? result += "Price must be at least $1.00"; } return result; }
Trick: Sometimes, it is easier to do all the logic in the servlet and then send output to the JSP.
Advantage: It is easier to write code in the servlet and the JSP is easier to read.
Example:
Code in servlet
String message = ""; if ( bid.isPartlyComplete() ) { message = "Please fill in all the data"; address = "/Form.jsp"; } else { message = "Welcome to this site"; address = "/Form.jsp"; } request.setAttribute("message", message); request.getRequestDispatcher(address).forward(request, response);
Code in JSP
<%= request.getAttribute("message") %>
Try renaming your servlet. The problem might be that Tomcat needs to be restarted. If you find that renaming the servlet fixes the problem, then restart your Tomcat, or ask me to reset your webapp if you are running your servlet off of otter. Usually the message you will see is that the INVOKER is not available for your servlet. There will not be a stack trace for an error, it will only state that the servlet is unavailable.
If you have the permissions wrong on your .class file, then Tomcat marks your servlet as unavailable. Even if you fix the permissions, Tomcat will still think that the servlet is unavailable. The only way to fix this is to restart Tomcat. If you are running your servlet from localhost, then you can restart Tomcat and the probem should be fixed. If you are running your servlet through my Tomcat on otter, then you will need to ask me to reset your webapp. In the meantime, you can work on your renamed servlet.
After you recompile your servlet, be sure that the permissions are correct before you access your servlet.