Monday, March 20, 2006

Struts, Tiles and Validator

Just a bit of background for my next few entries: At work, I've been designing the front end structure for some new pages that we are introducing. We have decided to start using some new technology (for us), namely Tiles and Validator. Since the existing framework is using Struts 1.1, I am confined to using earlier versions of Tiles and Validator. For the new designs, I have kept several goals in mind:
  • Separation of business and view
  • Reuse of components
  • More configuration, less hard coding
First things first, creating a stand alone application to play around with the various technologies: Struts, Tiles, Validator, JSTL. I am using the Struts 1.1 package
  • The basic web app

    First things first, creating a basic webapp to play around with. For this step, I started out by using the struts-blank .war file included in the struts package (/webapps/struts-blank.war).

    Since getting compiling in eclipse was a bit of a hassle (at least it was for the one included in the 1.1 package), I'll go over it here. unzip the struts-blank.war file into a working folder, start up eclipse, create a New Java Project, pick a project name (e.g. struts-test), select "Create project from existing source" and using the directory that you expanded your struts-blank into, click on "finish".

    Next, right click on the /WEB-INF/src folder in the Package Explorer view and select build path > Use as Source Folder. For this project, we'll use Ant to build the project, go ahead and show the ant view (Window > Show View > Ant). You should see an ant view on the right side of your main editor, drag the /WEB-INF/src/build.xml file into the ant panel.

    Using the default build script, if you try to generate a war file using the dist target, you'll get the following warning: Warning: selected war files include a WEB-INF/web.xml which will be ignored (please use webxml attribute to war task), if you then try to deploy the generated war file, the application won't deploy property. To fix this, add an <exclude name="**/web.xml" /> line in the <war> task in the dist target. This will prevent duplicate web.xml files.

  • How hard is it to get JSTL to work.. Properly!?

    There are four main parts to getting JSTL working, if you leave out one or more of these, like I did, you're page will most likely not work. First, you need both jstl.jar and standard.jar, in addition you need to declare the taglib at the top of any JSP pages that you intend to use JSTL on:


    <%@ taglib prefix="c" uri="http://java.sun.com/jspjstl/core" %>

    or


    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

    if you are using an older version. For the other, non-core, JSTL tags, you'll need to add/use their respective taglib declarations.
    You can put a taglib declaration in your web.xml file, but I've got my applications working without them:


    <taglib>
    <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
    <taglib-location>/WEB-INF/c.tld</taglib-location>
    </taglib>

    Personally, I like to keep my *.tld files in their own seperate folder, but the sample struts-blank webapp puts them in the WEB-INF directory along with the XML configuration files.
  • Playing With JSTL

    Now that we finally have JSTL set up, let's experiment and see what it can do.

    I started out using a single JSP, the index.jsp file found in the root project folder. I set up some classes that I wanted to play with inside a java scriptlet at the top of the JSP file:

    <%
    class Outer {
    private String name;
    private java.util.List inners;

    public String getName() {
    return name;
    }

    public java.util.List getInners() {
    return inners;
    }

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

    public void setInners(java.util.List inners) {
    this.inners = inners;
    }
    }

    class Inner {
    private String value;

    public String getValue() {
    return value;
    }

    public void setValue(String value) {
    this.value = value;
    }
    }

    Outer o1 = new Outer();
    o1.setName("outer 1");

    Inner i1 = new Inner();
    Inner i2 = new Inner();
    Inner i3 = new Inner();

    i1.setValue("inner 1");
    i2.setValue("inner 2");
    i3.setValue("inner 3");

    java.util.List ins = new java.util.LinkedList();
    ins.add(i1);
    ins.add(i2);
    ins.add(i3);

    o1.setInners(ins);

    pageContext.setAttribute("out1", o1);
    pageContext.setAttribute("test", "Testing String");
    %>

    I also included some code to set up a few objects. To access the objects, we have to place them into the session in one of the scopes: application, session, page or request

    I'll place my object in the default (page) scope and try to access it using the JSTL c:out tag:

    <c:out value="${test}"></c:out>

    Works fine and displays "Testing String" as we would expect, but:

    <c:out value="${out1.name}"></c:out>

    will, instead of accessing the getName() Javabean method and returning our name, reward us with a JspException:

    javax.servlet.ServletException: javax.servlet.jsp.JspException: An error occurred while evaluating custom action attribute "value" with value "${out1.name}": An error occurred while getting property "name" from an instance of class org.apache.jsp.index_jsp$1$Outer (java.lang.IllegalAccessException: Class org.apache.taglibs.standard.lang.jstl.ArraySuffix can not access a member of class org.apache.jsp.index_jsp$1$Outer with modifiers "public")

    What happens here is the tag tries to access the getName() method of the class, but cannot because the class is not public. This is easy enough to fix, just extract our two classes into their own Java class files. We then import these classes into our JSP and our code works as expected:

    <%@page import="com.adamdou.fronts.dummy.Outer"%>
    <%@page import="com.adamdou.fronts.dummy.Inner"%>

    Next, try doing some fancier things like displaying all the Inner items in our Outer item:

    <h2><c:out value="${out1.name}"></c:out></h2>
    <ol>
    <c:forEach var="in" items="${out1.inners}">
    <li><c:out value="${in.value}" /> </li>
    </c:forEach>
    </ol>

    Once you get JSTL up and running, it's pretty simple to experiment with different things, there's also a plethora of tutorials online such as the IBM JSTL Primer, a simple online search should turn up quite a few more.

That's it for now, next time I'll talk about some interesting adventures I've had with the Commons Validator.

expand post

3 Comments:

Anonymous Anonymous said...

Good design!
[url=http://iexxwgxa.com/hobg/litq.html]My homepage[/url] | [url=http://eayxrdwd.com/niee/zdrt.html]Cool site[/url]

3:12 PM  
Anonymous Anonymous said...

Nice site!
My homepage | Please visit

3:12 PM  
Anonymous Anonymous said...

Thank you!
http://iexxwgxa.com/hobg/litq.html | http://zwcqupzn.com/gqxm/mudu.html

3:12 PM  

Post a Comment

Links to this post:

Create a Link

<< Home