Nathan Andelin skrev den 06-07-2008 00:08:
Thorbjørn Ravn Andersen wrote:
But for presentation purposes Maps do nicely :)

I actually wanted to bring this up at some point, Thorbjørn. I assumed that the reason for mapping SQL result sets to objects had something to do with implementing business rules and procedures. And I asked Sarah about that. But I also wanted to find out about the next step, which is mapping objects to whatever is streamed to the browser. And your message implies that objects are mapped to JSF components. Would you care to elaborate? Is the mapping automatic, for example?
I can give it a try.

(While brushing up on this I found some good links you might be interested in:

Get something working: http://www.exadel.com/web/portal/tutorials
An overview over tags: http://www.horstmann.com/corejsf/jsf-tags.html
)


Normally in JSP to display a value you do something like <%= foo.getBar() %> which is directly mapped by thSee JSP compiler to something like "System.out.print(foo.getBar())". You then must have a "foo" object in scope to refer to, which in turn must have a bar getter to call. If not, you will get an error.

There is nothing wrong with having a map in scope and print out values from it with e.g <%= map.get("Name") %>. Most documentation just talk about POJO's (plain old java objects) with getters and setters, which most likely is to enforce new learners to think statically typed but as always there is more than one way to do it.

In JSF there are several scopes - application, session, request (plus some more) - which refer to how long JSF holds on to them. See http://www.java-samples.com/showtutorial.php?tutorialid=472

For presentation purposes the request scope is perfect. Let us look at a case where the user selects a link to display a table of names. This looks like

<h:commandLink id="link" action="#{F.goB}" value="go" />

where F is defined in faces-config.xml as

<managed-bean>
<managed-bean-name>F</managed-bean-name>
<managed-bean-class>test.F</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

(note that the class is also named F, helps a LOT) and the test.F class looks like

==
package test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class F {
List l = new ArrayList();
public F() {
System.out.println("F " + new java.util.Date());
}
public String goA() {
System.out.println("goA()");
HashMap map = new HashMap();
map.put("name", "Alice");
map.put("place", "Living room");
l.add(map);
map = new HashMap();
map.put("name", "Bob");
map.put("place", "Next door");
l.add(map);
return "b";
}
public String goB() {
System.out.println("goB()");
HashMap map = new HashMap();
map.put("name", "Bob");
map.put("place", "Home");
l.add(map);
map = new HashMap();
map.put("name", "Christine");
map.put("place", "The Opera");
l.add(map);
return "a";
}
public List getL() {
System.out.println("F.l = " + l);
return l;
}
}
==

The link will call F.goB() which prepares the field l as an arraylist with two map elements (the return value b is used to navigate to the presentation page b.jsp)

b.jsp looks like:
==
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html"; prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core"; prefix="f"%>
<html>
<body>
<f:view>
Page B<h:form id="foob">
<h:commandLink id="link" action="#{F.goB}" value="go" />
</h:form>
<h:dataTable border="1" var="i" value="#{F.l}" rendered="#{not empty F.l}">
<h:column>
<f:facet name="header"><h:outputText value="Name" /></f:facet>
<h:outputText value="#{i.name}" />
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="Place" /></f:facet>
<h:outputText value="#{i.place}" />
</h:column>
</h:dataTable>
</f:view>
</body>
</html>
==
Note there is a link back to a.jsp (which renders the table in another way), and the h:dataTable presents the list in F.l with each item in it as a row. BUT the table is not rendered at ALL unless "not empty F.l" is true. So no table unless there is anything to show.

var="i" binds the variable i to the current item in the list, and "i.name" and "i.place" expressions look "name" and "place" up in the map directly, so it is just outputting them in the appropriate column. The same syntax had been used if the list had consisted of POJO's with getName() and getPlace(). That is pretty nifty.

The result looks like

Name Place
Alice Living room
Bob Next door



So, it _is_ very simple when you get all the JSF-scaffolding up and running correctly (sigh).


====================================================================

I created a small sample project in MyEclipse which I have zipped and attached for those curious. It contains the above mentioned jsp files for those without MyEclipse.


(To load project into MyEclipse)

Save the attached map.zip
Start MyEclipse
File->Import->General->Existing Projects into Workspace
Select "Select archive file" and browse to the map.zip saved above
In the Projects panel, the "map" project should appear and be checked.
Click "Finish"

(Setup deployment)
Click button in toolbar with the tooltip "Deploy MyEclipse J2EE Project to Server..." (two black things with arrows between)
Ensure that "map" is the selected project
Click "Add"
In "Server" select "MyEclipse Tomcat"
Ensure that the Deploy Type is Exploded Archive
Click "Finish"
Click "Ok" to close the remaining dialogue box.

(Start server)
Click dropdown arrow next to button in toolbar with the tooltip "Run/Stop/Restart MyEclipse Servers..." (computer with green arrow in front)
Select "MyEclipse Tomcat Server" -> "Start"

(Start browser)
Open a browser to "http://localhost:8080/map";
You should _see_ the contents of a.jsp as rendered by JSF.

Try clicking around and see what happens...

Hope this helps some :)


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.