Archive for the 'Web Apps' Category

JSP Documents and valid HTML

Wednesday, August 15th, 2007

I have never been a fan of JavaServer Pages (JSP) but I have used them on a few projects. When JSP Documents (JSPs with XML syntax) were added in version 1.2 I thought if you had to do JSP then JSP Documents were the way to go. I prefer the uniform XML syntax to all the crazy syntax in JSP Pages.

Recently I’ve been focused on producing valid HTML. Perhaps too focused. A while back I bought into the XHTML is the wave of the future so we should all start using XHTML now hype. Now I see that serving good old HTML 4.01 is the best choice. See Sending XHTML as text/html Considered Harmful for why. My old habit of using XML style empty elements such as <br /> was getting me into trouble with HTML validators. The HTML Validator Firefox extension (using Tidy) will flag the slash in red even though it doesn’t give a written error. The W3C validator gives an error if the /> results in character data where it isn’t allowed. This can happen on the empty meta tag.

After reading about empty elements and what <br /> really means in HTML I wondered how is it even possible for a JSP Document to generate valid HTML.

Because JSP Documents must be valid XML an empty tag like meta must end with /> (or </meta> which doesn’t help) and this results in a validation error because character data is not allowed within the head tag.

This really surprised me. I looked and looked for a way to tell the JSP Document to output valid HTML but couldn’t find one. If you know of a way please tell me. The jsp:output action gives you control over the DOCTYPE and XML declaration. I was expecting it to also let you specify that the output method is HTML just like XSLT does. But it doesn’t.

Unless I’m missing something obvious JSP Documents should come with a warning - “Warning JSP Documents don’t output valid HTML by default”. I wonder why the oversight. Did the JSP designers buy into the XHTML hype as well?

There are two ways I know of to work around this issue. One is to use a CDATA section. For example:

  <head>
    <![CDATA[<meta http-equiv="Content-Type" content="text/html">]]>
    ...

The other is to use a tag library such as Struts HTML that knows how to output either HTML or XHTML. But this doesn’t help with the meta tag.

Even with this minor snag I still prefer JSP Documents to JSP pages but that isn’t saying much.

HTML button is not useful

Tuesday, February 27th, 2007

Sometimes things seem so obvious once you learn them the hard way that you wonder why there aren’t big signs everywhere making it clear from the start. The HTML button element is useless when used with a server side controller. I got my information on the button element from the HTML specification and was happily using it with Firefox as my client. (I have found Firefox with key extensions to be an indispensable tool in developing web applications.) When I tried my app with IE 6 I quickly found that my servlets couldn’t distinguish which button was pressed.

My testing shows that in IE 6 all <button type=”submit”> values are submitted any time the form is submitted. In addition the content is used as the value rather than the value attribute. I searched for more information to see if I was missing something. I wondered how could IE get it so wrong and if it was wrong how could I have not heard about this problem before. Most of the articles I found about button talked about how great it was because it gave so much control over the content and style of the button. The best evidence I found that button was indeed broken in IE came from comments to the article “Push my button”. Standard vs. quirks mode makes no difference. I have not tested IE 7 yet. I did notice that some articles say that the button element is just for use with JavaScript but they don’t say it is because of the IE bug.

The thing that originally attracted me to the button element is that it allowed specifying the value of the button independent of the button label. The input element of type button has the problem that the label can’t easily be used to distinguish which button was pressed when the button label is localized. You could have the controller test the button value using the localized label string but yuck! In general internal tokens and display text should be kept separate.

The general requirements for using buttons are:

  • Multiple submit buttons on a form and it must be possible to distinguish which was pressed.
  • The button text must be localizable so you can’t rely on the button label to distinguish the button.
  • The solution must not require JavaScript. This would break the principal of progressive enhancement.

I can’t use <button name=”submit” type=”submit” value=”v1″>Label</button> because IE returns the content “Label” rather than the value “v1″ and because all buttons of type submit are returned so you can’t tell which button was pressed. I also can’t use <input name=”submit” type=”submit” value=”Label” /> (where multiple buttons use the same name) because the buttons cannot be reliably distinguish. The value is “Label” in English but may be different when localized.

I see two options and both use the input element of type button. One is to use a different name for each submit button. The draw back is slightly messy code on the back end where you have to check for the presence of different parameters. The second option and the one I use is to encode the intended value of the button in the name.

For example: rather than
<button name=”submit” type=”submit” value=”v1″>Label</button>
I would use
<input name=”submit_v1″ type=”submit” value=”Label” />

In the controller servlet I have common code to look at the parameter prefix “submit_” and extract the button value.

The main thing you loose out on is the styling ability of the button element. Progressive enhancement can be used to swap input for button and add the needed JavaScript to submit the correct parameters. This will give correct behavior for clients without JavaScript and provide a nicer look for clients with JavaScript

Both approaches have their problems. To implement the first in a common controller servlet would require that the controller know about all the names that could be used on submit buttons. With the second approach the controller pollutes the namespace of form properties.

Using JSON with StringTemplate

Tuesday, December 12th, 2006

I looked at a few of the Java libraries for JSON and finally choose org.json. It’s small and does just what I need it to, no more, no less. Well a little less. See, I decided to replace some of my existing value objects with JSON objects. (They were going to need to be serialized to/from JSON format anyway.) I am using StringTemplate (ST) to generate the HTML presentation so now my templates will need to get data from the JSON objects. The trouble is that the org.json implementation is not ST friendly.

ST knows how to get data from scalar types like String and Integer, and from object properties, Maps, and Collections. JSONObject wraps a HashMap but does not implement Map or extend HashMap so ST cannot get at the items it holds. I could have modified ST to treat JSONObject and JSONArray special but there is no reason for ST to know anything about these specific classes. The simple thing to do is have JSONObject implement Map and this is what I did. Most of the methods are a trivial call to the underlying HashMap method. A few methods must go through existing JSONObject methods to maintain the intended semantics. For example, get(Object key) calls opt(String key) because get should return null if the key is not found.

A similar thing was done for JSONArray. I made it implement Collection and Iterable. Since JSONArray has a put(Collection) method and JSONObject has a put(String, Map) method this caused infinite recursion because JSONArray is now a Collection and JSONObject is a Map. The solution was to add more specific methods put(JSONArray) and put(String, JSONObject) so that JSONObjects and JSONArrays can be added to each other.

There is one more problem to solve. Sometimes I need to access the contents of the JSON object structure and sometimes I need to serialize it as a JSON string (after all, that’s what JSON is for). JSONObject has a toString method which ST will generally use but not if the object is a Map. Once ST sees an object is a Map it will not use it any other way. That means you can’t call toString on it or access any other properties. This is a good thing in general but I sill need the JSON string. I could have the controller call toString and stuff the result into another ST attribute but that puts more burden on the controller and requires that the controller know if the presentation is going to need the JSON string. I decided to create a pseudo key called “JSONString”. In the get method I check if the key is equal to “JSONString” and if it is I return the output of toString. Normally this would be a bad idea but in this case I think it is the best option. Note: ST already pollutes the name space of keys. In ST $mymap.keys$ returns a collection of all the key names and not the map item with key “keys”. It would be nice if $mymap.(”keys”)$ gave you the map item but it doesn’t. I think of both JSONString and keys as a hack but I don’t have a better way right now. ST has no problem with additional properties on Collections so I was able to add a getJSONString method to JSONArray.

Examples of use

this code

JSONObject jo = new JSONObject();
jo.put("long", 4);
jo.put("string", "some string");
JSONArray ja = new JSONArray();
ja.put("one");
ja.put("two");
ja.put("three");
jo.put("array", ja);

StringTemplate st = new StringTemplate(
"l=$jo.long$ s=$jo.string$n" +
"keys: $jo.keys : {[$it$] }$n" +
"array: $jo.array;separator=\", \"$n" +
"json=$jo.JSONString$n" +
"json array=$jo.array.JSONString$n");
st.setAttribute("jo", jo);
String text = st.toString();

produces this output:

l=4 s=some string
keys: [string] [array] [long]
array: one, two, three
json={"string":"some string","array":["one","two","three"],"long":4}
json array=["one","two","three"]

What I did with JSON is an example of a general principle of using ST: Wrap (or change) your existing object structures in a way that ST already deals with rather than change ST to understand your data.

I can make my changes to org.json available if anyone is interested.

Web app investigation part 2 - StringTemplate

Monday, December 11th, 2006

In a recent post I talked about implementing a very simple web app with different frameworks and why JSF isn’t for me. This post will describe my experience with StringTemplate. I also give some informal performance numbers.

Continue reading…

Web app investigation part 1 - JSF

Tuesday, November 28th, 2006

One of my main interests right now is web application development. About 8 or 9 years ago I created my first simple web application (just a few pages) as an ISAPI DLL. I was not paying any attention to HTML standards at this time. It didn’t seem like many people were. I don’t think I even knew what CSS was back then.

Continue reading…