Tutorial Webapp has been edited by Andrus Adamchik (May 17, 2009).

(View changes)

Content:

Now we'll convert the tutorial that we created to a web application. The web part of it is done in JSP, which is the least common denominator of the Java web technologies, and is intentionally simplistic from the UI perspective, to concentrate on Cayenne integration aspect, rather than the interface. Other web frameworks may have some specifics, still the procedure outlined here is quite universal as it is based on the Java servlet specification.

A typical Cayenne web application works like this:

  • Cayenne files are loaded when an application context is started, using a special servlet filter.
  • User requests are intercepted by the filter, and the DataContext is bound to the request thread, so the application can access it easily from anywhere.
  • The same DataContext instance is reused within a single user session; different sessions use different DataContexts (and therefore different sets of objects).

For detailed discussion of web application deployment, check this page.

To run the web application from Eclipse, we will use run-jetty-run plugin. If you prefer another way to start web applications (e.g. via Eclipse WTP), it should work as well.

  • In Eclipse under "cayenne-tutorial" project folder create a new folder called "webapp" and a subfolder called "WEB-INF".
  • Under "WEB-INF" create a new file "web.xml". This is a standard web deployment descriptor:

The following is the contents of web.xml. All the DataContext magic described above is achieved by WebApplicationContextFilter.

web.xml
<?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>

  • Create the artist browser page - webapp/index.jsp file with the following contents:
webapp/index.jsp
<%@ 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="" class="code-quote">"detail.jsp?id=<%=DataObjectUtils.intPKForObject(a)%>"> <%=a.getName()%> </a></p>
        <%
            }
            } %>
        <hr>
        <p><a href="" class="code-quote">"detail.jsp">Create new artist...</a></p>
    </body>	
</html>
  • Create the artist editor page webapp/detail.jsp with the following content:
webapp/detail.jsp
<%@ 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="" class="code-quote">"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>
  • Run the application. Go to "Run > Run..." menu, select "Jetty Web", right click and select "New"
  • Make sure project is "cayenne-tutorial", webapp root is "webapp" and Jetty home points to a directory where you unpacked Jetty:

  • Click "Apply" and "Run".
  • You will see some Cayenne logs, indicating that the filter was loaded and Cayenne is successfully runing in web app.
  • Now go to http://localhost:8080/ URL. You should see "No artists found message" in the web browser and the following output in the Eclipse console:
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 can click on "Create new artist" link to create artists. Existing artists can be edited by clicking on their name:

You are done with the tutorial!

Reply via email to