Title: Tutorial Webapp
Now we'll convert the tutorial that we created to a web application. The web part of it is done in JSP and is intentionally primitive from the UI perspective, to concentrate on Cayenne integration aspect. There may be some specifics depending on the web framework used (JSP, Struts, JSF, Click, WebWork, Tapestry, etc.), still the procedure outlined here is quite universal as it relies on the J2EE servlet specification.
A typical Cayenne web application works like this:
For detailed discussion of web application deployment, check this page.
To run the web application from Eclipse, we will use JettyLauncher plugin. If you are using something else (e.g. a Tomcat plugin) it should probably work as well.
The following is the contents of web.xml. All the DataContext magic described above is achieved by WebApplicationContextFilter.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Cayenne Tutorial</display-name> <filter> <filter-name>CayenneFilter</filter-name> <filter-class>org.apache.cayenne.conf.WebApplicationContextFilter</filter-class> </filter> <filter-mapping> <filter-name>CayenneFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
<%@ page language="java" contentType="text/html" %> <%@ page import="cayenne.tutorial.*" %> <%@ page import="org.apache.cayenne.*" %> <%@ page import="org.apache.cayenne.query.*" %> <%@ page import="org.apache.cayenne.exp.*" %> <%@ page import="org.apache.cayenne.access.*" %> <%@ page import="java.util.*" %> <% SelectQuery query = new SelectQuery(Artist.class); query.addOrdering(Artist.NAME_PROPERTY, true); DataContext context = DataContext.getThreadDataContext(); List artists = context.performQuery(query); %> <html> <head> <title>Main</title> </head> <body> <h2>Artists:</h2> <% if(artists.isEmpty()) {%> <p>No artists found</p> <% } else { Iterator it = artists.iterator(); while(it.hasNext()) { Artist a = (Artist) it.next(); %> <p><a href="detail.jsp?id=<%=DataObjectUtils.intPKForObject(a)%>"> <%=a.getName()%> </a></p> <% } } %> <hr> <p><a href="detail.jsp">Create new artist...</a></p> </body> </html>
<%@ page language="java" contentType="text/html" %> <%@ page import="cayenne.tutorial.*" %> <%@ page import="org.apache.cayenne.*" %> <%@ page import="org.apache.cayenne.access.*" %> <%@ page import="java.util.*" %> <%@ page import="java.text.*" %> <% DataContext context = DataContext.getThreadDataContext(); String id = request.getParameter("id"); // find artist for id Artist artist = null; if(id != null && id.trim().length() > 0) { artist = (Artist) DataObjectUtils.objectForPK(context, Artist.class, Integer.parseInt(id)); } if("POST".equals(request.getMethod())) { // if no id is saved in the hidden field, we are dealing with // create new artist request if(artist == null) { artist = (Artist) context.newObject(Artist.class); } // note that in a real application we would so dome validation ... // here we just hope the input is correct artist.setName(request.getParameter("name")); artist.setDateOfBirthString(request.getParameter("dateOfBirth")); context.commitChanges(); response.sendRedirect("index.jsp"); } if(artist == null) { // create transient artist for the form response rendering artist = new Artist(); } String name = artist.getName() == null ? "" : artist.getName(); String dob = artist.getDateOfBirth() == null ? "" : new SimpleDateFormat("yyyyMMdd").format(artist.getDateOfBirth()); %> <html> <head> <title>Artist Details</title> </head> <body> <h2>Artists Details</h2> <form name="EditArtist" action="detail.jsp" method="POST"> <input type="hidden" name="id" value="<%= id != null ? id : "" %>" /> <table border="0"> <tr> <td>Name:</td> <td><input type="text" name="name" value="<%= name %>"/></td> </tr> <tr> <td>Date of Birth (yyyyMMdd):</td> <td><input type="text" name="dateOfBirth" value="<%= dob %>"/></td> </tr> <tr> <td></td> <td align="right"><input type="submit" value="Save" /></td> </tr> </table> </form> </body> </html>
INFO QueryLogger: --- will run 1 query. INFO QueryLogger: Opening connection: jdbc:derby:/Users/andrus/Desktop/testdb;create=true Login: null Password: ******* INFO QueryLogger: +++ Connecting: SUCCESS. INFO QueryLogger: --- transaction started. INFO QueryLogger: Detected and installed adapter: org.apache.cayenne.dba.derby.DerbyAdapter INFO QueryLogger: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 ORDER BY t0.NAME - prepared in 32 ms. INFO QueryLogger: === returned 0 rows. - took 461 ms. INFO QueryLogger: +++ transaction committed.
You are done with the tutorial!