Tuesday, November 10, 2009

Keep Your Complexity Out of My JSP View - JSP Functions



The JSTL library comes with built in functions that are very useful. Hopefully these functions meet your needs, but sometimes you need to write your own. Sometimes you might want to expose some static util functions to your page. Well with JSP 2.0 you can write you own.

In my example I'm going to write a debug tag to be able to print out session and request variables. It also gives you a convenient point to set a debug point so you can inspect context variables.

The first thing to do is to write a tld file. This is just like we do for old JSP tags. I put the tld under WEB-INF/tld/ and I will reference that path when I declare it in the JSP page.

Here is my tld file
The main parts are under the function node. There is the name that you will use to call the function, the function-class is the java class that contains the function and the function-signature is the signature of the function. We need to use fully qualified names for the return and parameters.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<jsp-version>2.1</jsp-version>
<short-name>fnt</short-name>
<uri>http://daneking.blogspot.com</uri>
<description>A debug function</description>
<function>
<name>debugPage</name>
<function-class>
viewhelper.JSPMethodCall
</function-class>
<function-signature>
java.lang.String callFactoryMethod(javax.servlet.jsp.PageContext)
</function-signature>
</function>
</taglib>



Now here is the java code to create a string of the session and request variables. I bolded the call to the implementation of the my method.

package viewhelper;

import java.util.Enumeration;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;

public class JSPMethodCall {

private static final String CR = "<br/>";

private static String printSessionAttributes(HttpSession s,String header){
StringBuffer sb=new StringBuffer(header);
sb.append(CR);
Enumeration e=s.getAttributeNames();
while(e.hasMoreElements()){
String var=(String)e.nextElement();
sb.append(var);
sb.append(" = " + s.getAttribute(var));
sb.append(CR);
}
return sb.toString();

}
private static String printRequestAttributes(ServletRequest r,String header){
StringBuffer sb=new StringBuffer(header);
sb.append(CR);
Enumeration e=r.getAttributeNames();
while(e.hasMoreElements()){
String var=(String)e.nextElement();
sb.append(var);
sb.append(" = " + r.getAttribute(var));
sb.append(CR);
}
return sb.toString();

}
public static String callFactoryMethod(PageContext ctx){
HttpSession session =ctx.getSession();

StringBuffer sb=new StringBuffer(CR + "--- Debug Values ---" + CR);
sb.append(printSessionAttributes(session,"---Session ---"));
ServletRequest servletRequest = ctx.getRequest();
sb.append(printRequestAttributes(servletRequest,"---Request ---"));
return sb.toString();
}

}


And the finally the call from the JSP page. I've bolded the important parts where we call the function and the declaration of the tld page where we defined our function.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="/WEB-INF/tlds/fntags.tld" prefix="fnt" %>


<!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>Calling Functions</title>
</head>
<body>
<c:set scope="session" var="sessionVar" value="sessionValue"/>
<c:set scope="request" var="requestVar" value="requestValue"/>
This is my function .....
${fnt:debugPage(pageContext)}

</body>
</html>


Many times we get so caught up in the latest widgets and technologies that we don't look at some of the basic things we can do to refactor out som complexity out of our views. Hopefully this is another tool to help you do that.

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.

Friday, July 24, 2009

Keep Your Privates Private

On my current project, some developers discovered that they could test private methods using reflection. I asserted my opinion(which of course rarely happens) that we shouldn't be testing private methods. My point was that my public methods are my interface to let others know how to use my class. My tests are a verification of that contract. If something changes to break that contract it will let me know. Its sort of a contract on a contract. So after a lively discussion about it, I did some research (I googled) and found that there is indeed some debate on the matter.
Instead of rehashing that debate, I would like to add another view, that once developers can test private methods, they do it without thinking of alternatives. I never say never, so I'm not totally against the idea of testing these private methods, but it just feels wrong. I think once developers have a test around a complex method they stop. My mantra is if its hard to test, then something is wrong with your design.
The methods I have seen with private methods tested usually have some side effects. They are changing class level variables or the arguments of the method without any return values. Sometime they are just encapsulating some complex behavior that should moved into another class.
Test Driven Development (TDD) is not so much about testability but about designing for testability. A application that is redesigned to be easily testable is an application with less coupling, more focused objects and less side effects of the methods.
I realize that with the pressures of deadlines and legacy code, its not always possible to refactor and testing private methods could be a solution to get more test coverage. I just think we should first try to refactor and only if that isn't feasible should we test private methods.
If you do find that you must test private methods, Bill Venners has a good article on testing private methods, I particularly like his translating the reflection exceptions into assert exceptions. He also has a good example of the kind of private methods that are hard to test.

Tuesday, July 21, 2009

Always Something to Learn

I am always ready to learn although I do not always like being taught. ~Winston Churchill

I'm always surprised at the number of people in the software industry that don't strive to learn. Programmers that brag that they don't touch a computer at home or read a computer book. A programmer that doesn't like to learn is like a doctor that doesn't like the sight of blood. I think that with a constant barrage of new frameworks, technologies and the pressures of deadlines we not only should always be learning something new, but its a necessary part of our job.

I understand it's not always useful to learn Widget 0.9 framework that will be obsolute when TheNextBigThing 1.2 comes out. But that's not an excuse to then not learn anything. There are still many things to learn to make you more productive.

What about the programming language you use, are you up on the latest features? What about just basic programming techniques? Reading code from open source projects or the the code of the language itself if possible is a great way to learn.

What about testing your code or learning different programming methodologies? What about your IDE of choice, do you know all the shortcuts and plugins that can help you?

Learning shouldn't be an either/or proposition. It should be more of a Return on Investment (ROI), if I invest (x) hours, I should be able to save (y) time. I find that learning time tested concepts give me more bang for the buck than learning the latest framework or technology. Also a better understanding of the concepts makes working with the frameworks easier.

Topics like testing, refactoring and design patterns seem to stay around longer. Also the books for these topics can be found fairly cheap in used, but like new condition on Amazon or Alibris, or if your lucky at you're local Half price bookstore.

The shelf life for a developers knowledge is extremely short, however if we concentrate on concepts that are time tested, ones that have been around for awhile, and topics that make us more productive, we should be able to maximize our learning and be more professional in our jobs.

By the way, I put together an Amazon list of some of the books I have enjoyed that haven't "depreciated" over time.

Wednesday, July 1, 2009

Re-Finding Tools in My Toolbox

As developers, especially Java developers, we are always looking for the next big thing. I like nice new shiny things as much as the next programmer, but I think its extremely valuable to learn the what our basic tools can do. We don't seem to study the basics anymore like Java, HTML, JSTL, JSP. I started this blog as a way to go back and make sure that I know the fundamentals of what I'm doing before I reach for another tool to solve my problem. Who knows I just might already have the tool in my toolbox.