• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

CastMap getTrimmedString() error?

 
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Did anyone who did the Servlets class have a problem with the CastMap getTrimmed String()? My servlet is just blowing down if I don't specify a value for the form checkbox field I am testing. Works fine for yes but just stops if I leave the associated checkbox blank.

if the "dvd" string does not equals("yes"), the servlet exits with an unknown error.
 
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What does getTrimmedString (or getString) actually return for an unchecked box?
 
Greg Neef
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

[ November 15, 2003: Message edited by: Greg Neef ]
Looks better - let's keep it to ourselves.
-Barry
[ November 15, 2003: Message edited by: Barry Gaunt ]
 
whippersnapper
Posts: 1843
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
GN: Did anyone who did the Servlets class have a problem with the CastMap getTrimmed String()? My servlet is just blowing down if I don't specify a value for the form checkbox field I am testing. Works fine for yes but just stops if I leave the associated checkbox blank.
if the "dvd" string does not equals("yes"), the servlet exits with an unknown error.
Deep down I'd bet that unknown error is really a NullPointerException. Your original code
parms.getTrimmedString( "dvd" ).equals( "yes" )
doesn't gracefully allow for the possibility of nulls -- and null is exactly what parms.getTrimmedString( "dvd" ) resolves to if the associated checkbox is blank. So when .equals() is called on null, a NPE gets thrown. Your second version of the code *does* handly nulls gracefully (albeit somewhat verbosely). I'll show you a less verbose way to do the same thing (but you must first suffer through one of my famous explanation-through-demonstration posts). Then I'll challange you do to some detective work and find a third way of doing the same thing (if you want).
Why do you have to care about nulls when working with these checkboxes? First you have to understand how the parameters from the web page form are packaged up by LogServlet for you to use in your servlet code. These parameters and values from posting the form are put in a Map (actually a CastMap). The parameter names are map keys and the parameter values are name values. There's a bit of trickiness with checkboxes though. You've already seen, for example, that if the checkbox with the name "dvd" and value "yes" is checked, the map will contain an entry with "dvd" as the key and "yes" as the value. But if that checkbox is *not* checked, the map will contain *no entry at all* for "dvd". If you try to retrieve and use a value from a nonexisting entry, you get a null back. Your code must be able to handle those nulls gracefully, otherwise you'll have code throwing NullPointerExceptions and crashing.
Here's some code that illustrates my point.
A web page in html (call it showParameters.html):
<code>
<html>
<head>
<title>Show Parameters Servlet</title>
</head>
<body>
<h1>Show Parameters Servlet</h1>
<form method = 'POST' action = '/servlet/ShowParametersServlet'>
<p>Thread participants:
<br><input type = 'checkbox' name = 'Greg' value = 'yes'>Greg
<br><input type = 'checkbox' name = 'Pauline' value = 'yes'>Pauline
<br><input type = 'checkbox' name = 'Barry' value = 'yes'>Barry
<br><input type = 'checkbox' name = 'Carol' value = 'yes'>Carol
<br><input type = 'checkbox' name = 'Mike' value = 'yes'>Mike
<br><input type = 'checkbox' name = 'Jason' value = 'yes'>Jason
</p>
<p><input type=submit value='showWhatsBeingPassed'></p>
</form>
</body>
</html>
</code>
And the servlet this web page calls:
<code>
import java.io.PrintWriter ;
import java.util.Iterator ;
import java.util.Map ;
import com.javaranch.common.* ;
public class ShowParametersServlet extends LogServlet
{
public void doPost( PrintWriter out , CastMap parameters )
{
out.println( "Er, check the console because I didn't feel like dealing with html." );
for ( Iterator iterator = parameters.entrySet().iterator() ; iterator.hasNext() ; )
{
Map.Entry entry = (Map.Entry)iterator.next() ;
System.out.println( "( " + entry.getKey() + " , " + entry.getValue() + " )" ); // (A)
}
System.out.println( parameters.getString( "The Moose" ) ); // (B)
}
}
</code>
Access showParameters.html served from Orion or suchlike. Check some of the checkboxes and leave others blank. Then click the "showWhatsBeingPassed" button. In the console output generated by code at (A), you should be able to see exactly what I'm saying about checkboxes. There are entries for the checked ones, but no entries for the unchecked ones. So if you had left checkbox Pauline blank and called getString( "Pauline" ) or getTrimmedString( "Pauline" ), you'd have a null on your hands because there's no "Pauline" entry in that parameters map. Just like there's no entry for "The Moose" at line (B). (If showParameters.html is the only page posting to ShowParametersServlet, there would never be a "The Moose" entry because there's no "The Moose" html input control on the form.)
(If you're wondering why System.out.println() can just print "null" for nulls, but method calls on null cause your program to blow up, that's because there's some special magic behind System.out.println() to do just that. Otherwise debugging would be a major pain.)
So if getString( "dvd" ) (or getTrimmedString( "dvd" )) has the possibility of returning null, how do you safely call equals() on it? There's the way you proposed, but why not just try flipping things around:
"yes".equals( parms.getString( "dvd" ) )
(Yes, you can do method calls on string literals!)
(Note also that this whole thing resolves to a boolean -- which could come in *very* handy. Depending of course on what you doing with it.)
Can't remember whether this calling-equals-on-"yes" trick gets an OK from the nitpickers though, but it's worth a try.
The other way of handling this I'm not going to tell you because it's sitting right there in the javaranch.common.com package just waiting for you to find it. Happy hunting!
[ November 15, 2003: Message edited by: Michael Matola ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The String.equals(Object o) is documented to return true only if o is not null and o is a String representing the same characters contained in the String it is called upon. So to me (not being a nitpicker) it is OK to use it. Good tip, I reckon, Mike.
The second (in com.javaranch.common.* somewhere) way of doing things, is a bit dodgey. Why? Well, first you have to read the source code (nothing wrong with that for education reasons) to find it - if you have the time.
And second, its behaviour does not conform to its Javadoc so it could be considered a "bug". So if the "bug" is fixed one day - all the programs depending on it go poof. It is also a "suprising" behaviour because it does not conform to the expectations based on knowledge of the java.lang.String class.
That's if we are talking about the same thing. Over...
[ November 16, 2003: Message edited by: Barry Gaunt ]
 
Greg Neef
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Michael for your excellent explanation. This makes perfect sense to me that I have a null pointer exception since there is no "dvd" entry at all. I knew, but was forgetting that the CastMap does not bother to include these items at all. I was a bit confused I think by the PrintWriters display of null. Personally I find the syntax a bit tortured but the nitpickers have clearly established that my taste in code and theirs diverge significantly on many occasions. To me (knowing as I now do that the unchecked box has no entry in the cast map) a null test makes perfect sense. We shall see what they say.
I do still wonder why the value for the checkbox is not "true" instead of "yes" in the provided html. Then one could assign said value directly to a boolean if not null and forgo testing for equality at all as I am in effect doing now.
Back to the null pointer exception though, how should I have debugged this? If I had known what the error was, I imagine the light would have gone off (although who knows at 11PM). I realize there is a logging function with the common javaranch servlet classes but I am unclear how it gets used. Should I try to start using an IDE for debugging servlets?
 
Michael Matola
whippersnapper
Posts: 1843
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The second (in com.javaranch.common.* somewhere) way of doing things, is a bit dodgey....
That's if we are talking about the same thing.
Actually, I don't think we are. I've checked the Javadoc for the thing I have in mind and unless I'm missing something fundamental, the behavior and doco do match.
I was thinking that this technique I'm thinking of appears for the first time in the instructor's solution for Servlets-4a, which Greg wouldn't immediately benefit from because he hasn't seen the instructor's solution yet. But I went and double-checked and found that it was used in an early instructor's solution, which Greg *has* seen. So go study those instructor's solutions again!
If folks will allow, let me revise my hinting a little bit.
I said
And find a third way of doing the same thing and
the other way of handling this.
There's a method out there in javaranch.common.com code that essentially does something that would be helpful in these cases where you need to handle these nulls. It actually does a little more than what we need here (something vaguely similar to what we're doing here and also useful at times) but that little more bit doesn't interfere here so we're OK using it if that's the route you chose to go.
So how's that for cryptic!
 
Michael Matola
whippersnapper
Posts: 1843
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey, we crossed!
Personally I find the code "yes".equals(getString("dvd")) syntax a bit tortured but the nitpickers have clearly established that my taste in code and theirs diverge significantly on many occasions.
LOL. Yes, I would say tastes do diverge. I think the the "yes".equals(String) business is quite elegant and really comes in handy from time to time.
Will you indulge me a not-officially-sanctioned nitpick of your:

This code seems a bit verbose to me. It says essentially if a block of code evaluates to the boolean literal true then pass the boolean literal true as a parameter to another method. (Then don't do anything else in that if-block.) Why not just collapse it to
video.setDVD( parms.getString( "dvd" ) != null );
If you don't like that all on one line it could be broken up
String dvd = parms.getString( "dvd" );
video.setDVD( dvd != null );
(But then the nitpickers *might* ask "Why declare 'dvd'? Does it get used again?" or suchlike.)
My tortured syntax dodges some of these issues. Oh, heh heh heh. I just tracked down my nitpicks for Servlets-4a. Turns out I *did* get nitpicked for the "yes".equals(String) business and a hint about using the javaranch.common.com stuff I've been getting at all along.
Oh, well. Keep the "yes".equals(String) in your general arsenal, but probably don't use it here.
I do still wonder why the value for the checkbox is not "true" instead of "yes" in the provided html. Then one could assign said value directly to a boolean if not null and forgo testing for equality at all as I am in effect doing now.
I don't have a *good* answer for that, but let me provide a somewhat snarky one: HTTP was not designed for the pleasure and convenience of Java servlet programmers. In other words, the servlet engine stuff (whether it ends up being a CastMap in our case because we're subclassing LogServlet, or HttpServletRequest stuff when we're not) can only pass into our servlet space what HTTP captures and passes along. In no way am I apologizing for "yes" getting passed here instead of "true" but I will ask, why "true" and not "T" or "1" or some other general-purpose indicator of boolean truthfullness? Remember: HTTP post parameters can be used by any number of programming languages, not just Java.
Back to the null pointer exception though, how should I have debugged this?
I don't have a good answer for that either. At the time when I was working on these assignments I probably put together some code like I posted above to dump the contents of the map. It was then I started to realize how the form parameter passing work ed(and read up to confirm my suspicions). There was also discussion here in the Cattle Drive forum at the time about whether we even had to check for "yes" exactly or if it was OK just to check for not null. I'll do some searching a little later to see if I can find that old thread.
I realize there is a logging function with the common javaranch servlet classes but I am unclear how it gets used.
I know I posted here once about how to turn on the logging stuff. Let me dig that out later and see if is helpful here.
Should I try to start using an IDE for debugging servlets?
That's up to you of course. I never used an IDE for the Cattle Drive assignments, but I have gotten in the habit (not just in the Cattle Drive) of writing code (such as ShowParametersServlet) that tests out my assumptions about what's going on.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just to confuse things a bit further: Mike and me are talking about different things. But I does know what he is hinting about now, wink, wink.
Used it meself.
 
Sheriff
Posts: 9109
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Michael Matola:
I know I posted here once about how to turn on the logging stuff. Let me dig that out later and see if is helpful here.


How to use the logging of LogServlet
 
Michael Matola
whippersnapper
Posts: 1843
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And here's the thread on checkboxes I was thinking about.
 
reply
    Bookmark Topic Watch Topic
  • New Topic