Saturday, August 29, 2009

Keep Your Complexity Out of My JSP View - JavaBeans



Perhaps the most easiy understood of the view helper Core J2EE patterns is the Javabean helper strategy. This one is fairly straight forward. Its also used by a variety of frameworks.

To get started first you need a java bean. I know the word has been overused, with EJB and similar technologies but what I'm refering to is what Faisal Khan describes

You need 3 things.
1. Implements java.io.Serializable interface

2. A no argument constructor - this comes by default unless you define another argument constructor. Then you have to explicitly declare one

3. And provide getters and setters to properties

And here is the java code.
package viewhelper.javabeans;

import java.io.Serializable;
public class MySimpleBean implements Serializable {
private String propertyOne;
private Integer propertyTwo;

public String getPropertyOne() {
return propertyOne;
}

public void setPropertyOne(String propertyOne) {
this.propertyOne = propertyOne;
}

public Integer getPropertyTwo() {
return propertyTwo;
}

public void setPropertyTwo(Integer propertyTwo) {
this.propertyTwo = propertyTwo;
}

//I get the no argument default without declaring, but
//I have to explicitly declare if I have another argument constructor
public MySimpleBean() {
super();
}

public MySimpleBean(String propertyOne, Integer propertyTwo) {
super();
this.propertyOne = propertyOne;
this.propertyTwo = propertyTwo;
}

}




Fairly simple code, right? And this is how we access it from the JSP page. Notice that we don't use getPropertyOne, but propertyOne. This is javabeans naming convention, if we name our methods in the java code (get + camel case method name), to access we drop the get or set and make the first letter lower case.

<html>
<head>
<title>Using the bean</title>
</head>
<body>
<jsp:useBean id="beanHelper" scope="request"
class="viewhelper.javabeans.MySimpleBean" >
<jsp:setProperty name="beanHelper" property="propertyOne" value="My Name"/>
<jsp:setProperty name="beanHelper" property="propertyTwo" value="10"/>
</jsp:useBean>
<h1>First Property ${beanHelper.propertyOne}</h1>
<h3>Second Property ${beanHelper.propertyTwo}</h3>
</body>
</html>



This is a simple example and really doesn't show all the benefits of using JavaBeans. They are really great if you have complex view preparation logic, maybe a custom sorting code or text transformations. The ultimate goal is to streamline the view so that JSP is strictly more of a template engine like it was designed to be. JavaBeans are just another tool to work towards that goal.



Thursday, August 6, 2009

Keep Your Complexity Out of My JSP View - JSP tags files



When I was writing a previous post I came across the notion of tag files. Some people don't like the notion of tlds and compiled Java files and find them too complex. Well in JSP 2.0 there is the ability to write tag files. This has been out for awhile and honestly I haven't seen it used in a production environment before. However it looks like could be very useful.

OK we first need to create some files under WEB-INF, in this example I created a folder called tags and 2 tag files.
stringTag.tag


<%
String aString = "I am a String within a scriptlet";
%>

Hello There, <%= aString %>



and uppercase.tag
<jsp:doBody var="body"/>
Hey You!
<br>
<%
String msg = (String) jspContext.getAttribute("body");
%>
<%= msg.toUpperCase() %>


And now the JSP that uses the tags.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<%@ taglib uri="/WEB-INF/tlds/mytags.tld" prefix="mytag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>

<body>

Wow, you can do that
<br>
<mytag:myfirsttag name="what is my tag doing here"/>

<tags:stringTag/>
<br/>
<tags:uppercase>
I really want to be in capital letters.
</tags:uppercase>

</body>
</html>


We can also have attributes passed to the tag to allow us to change the behavior appearance here is
new_uppercase.tag
Notice also that you can use EL to streamline your tags

<%@attribute name="size" required="true"  %>
<font size="${pageScope.size}">
<jsp:doBody/>
</font>
</div>


and adding it to the JSP, , I bolded the lines I added from the previous JSP

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<%@ taglib uri="/WEB-INF/tlds/mytags.tld" prefix="mytag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>

<body>
Wow, you can do that
<br>
<mytag:myfirsttag name="what is my tag doing here"/>

<tags:stringTag/>
<br/>
<tags:uppercase>
I really want to be in capital letters.
</tags:uppercase>

<br>

<tags:new_uppercase size="1">
Really I do
</tags:new_uppercase>

<br>


<tags:new_uppercase size="15">
I said really I do
</tags:new_uppercase>

</body>
</html>


I haven't worked out all the details here, like how does a tag within a tag behave. It seems to work, but what happens if you redefine a html attribute, what is the order that the nested tags fire, etc. I want to look at this a little further and I'll post what I learn.

If you want to read more, I took these from the J2EE blue patterns site, This pattern is called JSP View Helper Strategy.

Here is a post on getting started that is more detailed than what I covered.

Look at the comments on this post, some of the people make good arguments about when to use tag files.

Saturday, August 1, 2009

Keep Your Complexity Out of My JSP View


As a web developer I spend way too much of my time tracking down defects in the UI. Many of these involve big complex pieces of business logic that represent untested code or complex pieces of html. As a result I'm always trying to find ways to get some of that complexity out of the view layer. This is often the advice other people give you, keep your view simple. What they don't offer are some ways to actually do it.

One way we can get some of that logic out of our html pages is JSP tags. I don't see this used very often, but it can provide a clean separation between your code and your html and allows you to introduce some unit testing.  That's not to say you can't have html code in your JSP tags, the article on best practices is OK with this. They make 2 points, one is that the tag is a custom tag,  with the key word being custom, so its only useful to a specific page, if you want to generalize some code they suggest some kind of helper class. Secondly, they say that it's better to have html in your Java than Java code in your JSP. I kind of agree with that, however this should be done carefully, the current project I'm on has a custom button tag that everyone avoids because it has alot of table html and css code in it. It tends to break when we use it with frameworks such as ExtJs that use alot of divs, and it is very difficult to get it positioned properly.

OK, time to code, the first step is to create our tld file. It should look something like below. Make sure you follow the format for the correct DTD. Now save it in your WEB-INF directory, I created a folder called tlds and created a file named mytags.tld. We also declare any attributes we want to use, I created one called name. I also can make it required if I want, by changing the required tag to true.


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">


<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>HelloWorldTags</short-name>
<uri>http://daneking.blogspot.com</uri>
<description>A simple tag </description>
<tag>
<name>myfirsttag</name>
<tag-class>com.mytags.MyCustomTag</tag-class>
<body-content>empty</body-content>
<description>Your first JSP Tag</description>
<attribute>
<name>name</name>
<required>false</required>
</attribute>
</tag>
</taglib>


Now we have to declare it in the JSP. Notice the bold lines, the first bolded line is the import and the second bolded line is where I use the tag. I also pass the value "what is my tag doing" as the name attribute that I declared in the tld file above.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

<%@ taglib uri="/WEB-INF/tlds/mytags.tld" prefix="mytag" %>

<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Wow, you can do that<br>

<mytag:myfirsttag name="what is my tag doing"/>


</body>
</html>

Now for the Java code. I downloaded the Tomcat 6.0 source code and looked at the tags that were available. I decided to keep it simple and use the implementation of SimpleTag called SimpleTagSupport. It already has alot of the trivial getters and setters implemented. So I only needed to override the method I was interested in. I'm using Apache Commons WordUtils to capitalize the words. So if you're following along add commons-lang-2.4.jar and add it to your web library. Eclipse EE users can add a J2EE Module Dependency

package com.mytags;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.apache.commons.lang.WordUtils;



public class MyCustomTag extends SimpleTagSupport {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = WordUtils.capitalizeFully(name);
}

@Override
public void doTag() throws JspException, IOException {
super.doTag();
getJspContext().getOut().print("Hello There<br>");
getJspContext().getOut().print(name);
}


}



And of course the test.
package com.mytags;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.apache.commons.lang.WordUtils;



public class MyCustomTag extends SimpleTagSupport {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = WordUtils.capitalizeFully(name);
}

@Override
public void doTag() throws JspException, IOException {
super.doTag();
getJspContext().getOut().print("Hello There<br>");
getJspContext().getOut().print(name);
}


}


I know this is a trivial example, but if you need some complex html code, especially things like looping this would be an ideal solution. You could also send in attributes such as the style sheet or html templates to further abstract the html from the code.