Spring Petclinic

PetClinic demonstrates the use of a Spring Boot with Spring MVC and Spring Data. The PetClinic has an old and varied history dating right back to the beginning of the Spring Framework. It started life as a demonstration of nearly all the common things that you could do with Spring, back when it was possible to conceive of such a demonstration. These days it is a very small slice of what you could achieve, but the community has a soft spot for it, so it's nice to see it still going after all this time, so we hope you enjoy it too.

Quick Start
Fork me on GitHub

Quick Start

You need Java 1.8 and git:

$ git clone https://github.com/spring-projects/spring-petclinic.git
$ cd spring-petclinic
$ ./mvnw spring-boot:run

You can then access petclinic here: http://localhost:8080/

petclinic-screenshot

Other Technology and Spring Features

The Spring Petclinic master branch in the main spring-projects GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are quite a few forks with different flavours of implementation in a special GitHub org spring-petclinic. If you have a special interest in a different technology stack that could be used to implement the Pet Clinic then please join the community there.

The Musem Section

For posterity: here is the text of the old https://springframework.org/docs/petclinic.html. Thankfully, much of it is irrelevant or inaccurate now, but it might be an interesting historical document one day. A monument to all those who served in this vessel…

The Spring PetClinic Application

Updated: 21.OCT.2007 Sam Brannen
30.JUN.2006 Costin Leau
01.DEC.2004 Ken Krebs
16.AUG.2003 Ken Krebs

Note: This document covers the PetClinic sample application distributed with the Spring Framework 2.5 and earlier. With the introduction of Spring Framework 3.0 this sample application is no longer part of the distribution. The code is now maintained as part of a separate source repository for samples.

Introduction

The Spring Framework is a collection of small, well-focused, loosely coupled Java frameworks that can be used independently or collectively to build industrial strength applications of many different types. The PetClinic sample application is designed to show how the Spring application frameworks can be used to build simple, but powerful database-oriented applications. It will demonstrate the use of Spring's core functionality:

JavaBeans based application configuration using Inversion-Of-Control Model-View-Controller web Presentation Layer Practical database access through JDBC, Hibernate, or Java Persistence API Application monitoring based on JMX Declarative Transaction Management using AOP Data Validation that supports but is not dependent on the Presentation Layer The Spring frameworks provide a great deal of useful infrastructure to simplify the tasks faced by application developers. This infrastructure helps developers to create applications that are:

  • concise by handling a lot of the complex control flow that is needed to use the Java API's, such as JDBC, JNDI, JTA, RMI, and EJB.
  • flexible by simplifying the process of external application configuration through the use of Reflection and JavaBeans. This allows the developer to achieve a clean separation of configuration data from application code. All application and web application objects, including validators, workflow controllers, and views, are JavaBeans that can be configured externally.
  • testable by supplying an interface based design to maximize pluggability. This facilitates unit testing of Business Logic without requiring the presence of application or live database servers.
  • maintainable by facilitating a clean separation of the application layers. It most importantly helps maintain the independence of the Business Layer from the Presentation layer. PetClinic demonstrates the use of a Model-View-Controller based web presentation framework that can work seamlessly with many different types of view technologies. The Spring web application framework helps developers to implement their Presentation as a clean and thin layer focused on its main missions of translating user actions into application events and rendering model data.
  • It is assumed that users of this tutorial will have a basic knowledge of object-oriented design, Java, Servlets, JSP, and relational databases. It also assumes a basic knowledge of the use of a Java EE web application container.

Since the purpose of the sample application is tutorial in nature, the implementation presented here will of course provide only a small subset of the functionality that would be needed by a real world version of a PetClinic application.

PetClinic Sample Application Requirements

The application requirement is for an information system that is accessible through a web browser. The users of the application are employees of the clinic who in the course of their work need to view and manage information regarding the veterinarians, the clients, and their pets. The sample application supports the following:

Use Cases

  • View a list of veterinarians and their specialties
  • View information pertaining to a pet owner
  • Update the information pertaining to a pet owner
  • Add a new pet owner to the system
  • View information pertaining to a pet
  • Update the information pertaining to a pet
  • Add a new pet to the system
  • View information pertaining to a pet's visitation history
  • Add information pertaining to a visit to the pet's visitation history

Business Rules

An owner may not have multiple pets with the same case-insensitive name. PetClinic Sample Application Design & Implementation

Server Technology

The sample application should be usable with any Java EE web application container that is compatible with the Servlet 2.4 and JSP 2.0 specifications. Some of the deployment files provided are designed specifically for Apache Tomcat. These files specify container-supplied connection-pooled data sources. It is not necessary to use these files. The application has been configured by default to use a data source without connection pooling to simplify usage. Configuration details are provided in the Developer Instructions section. The view technologies that are to be used for rendering the application are Java Server Pages (JSP) along with the Java Standard Tag Library (JSTL).

Database Technology

The sample application uses a relational database for data storage. Support has been provided for a choice of 1 of 2 database selections, MySql or HypersonicSQL. HypersonicSQL version 1.8.0 is the default choice and a copy is provided with the application. It is possible to easily configure the application to use either database. Configuration details are provided in the Developer Instructions section.

Development Environment

A copy of the Spring runtime library jar file is provided with the sample application along with some of the other required jar files. The developer will need to obtain the following tools externally, all of which are freely available:

  • Java SDK 1.5.x
  • Ant 1.7.x
  • Tomcat 5.x.x, or some other web application container
  • JUnit 4.4 - needed to run the tests
  • (Optional) MySQL 5.x with MySQL Connector/J 5.x

NOTE: The version numbers listed are those that were used in the development of the PetClinic application. Other versions of the same tools may or may not work.

Download links for the various tools needed are provided in the Developer Instructions section.

PetClinic Database

The following is an overview of the database schema used in PetClinic. Detailed field descriptions can be found in the "initDB.txt" SQL script files in the database-specific "db" sub-directories. All "id" key fields are of Java type int.

TABLE: owners
    PRIMARY KEY id

TABLE: types
    PRIMARY KEY id

TABLE: pets
    PRIMARY KEY id
    FOREIGN KEY type_id references the types table id field
    FOREIGN KEY owner_id references the owners table id field

TABLE: vets
    PRIMARY KEY id

TABLE: specialties
    PRIMARY KEY id
TABLE: vet_specialties - a link table for vets and their specialties
    FOREIGN KEY vet_id references the vets table id field
    FOREIGN KEY specialty_id references the specialties table id field

TABLE: visits
    PRIMARY KEY id
    FOREIGN KEY pet_id references the pets table id field

Directory Structure

  • d– indicates a directory holding source code, configuration files, etc.
  • D– indicates a directory that is created by the build script
d-- petclinic: the root directory of the project contains build related files
    d-- src: contains Java source code files and ORM configuration files
    d-- war: contains the web application resource files
        d-- html: contains tutorial files
        D-- docs: contains Javadoc files
        d-- web-inf: contains web application configuration files and application context files
              d-- jsp: contains Java Server Page files
              D-- lib: contains application dependencies
    d-- test: contains testing related Java source code files
    d-- db: contains database SQL scripts and other related files/directories
        d-- hsqldb: contains files related to HSQL, contains scripts and a Tomcat context definition file
        d-- mysql: contains files related to MySQL, contains scripts and a Tomcat context definition file
    D-- .classes: contains compiled Java class files
    D-- .testclasses: contains compiled testing related Java class files
    D-- junit-reports: contains generated xml-formatted test reports
         D-- reports/html: contains generated html-formatted test reports
    D-- dist: contains packaged archives of files

Clinic Application Design

Logging

Spring supports the use of the Apache Commons Logging API. This API provides the ability to use Java 1.4 loggers, the simple Commons loggers, and Apache Log4J loggers. PetClinic uses Log4J to provide sophisticated and configurable logging capabilities. The file, war/WEB-INF/log4j.properties configures the definition of Log4jloggers.

Business Layer

The Business Layer consists of a number of basic JavaBean classes representing the application domain objects and associated validation objects that are used by the Presentation Layer. The validation objects used in PetClinic are all implementations of the org.springframework.validation.Validator interface.

  • org.springframework.samples.petclinic.Entity is a simple JavaBean superclass used for all persistable objects.
  • org.springframework.samples.petclinic.NamedEntity is an extension of Entity that adds a name property.
  • org.springframework.samples.petclinic.Specialty is an extension of NamedEntity.
  • org.springframework.samples.petclinic.PetType is an extension of NamedEntity.
  • org.springframework.samples.petclinic.Person is an extension of Entity that provides a superclass for all objects that implement the notion of a person.
  • org.springframework.samples.petclinic.Vet is an extension of Person that implements a veterinarian. It holds a List of specialties that the Vet is capable of.
  • org.springframework.samples.petclinic.Owner is an extension of Person that implements a pet owner. It holds a List of pets owned.
  • org.springframework.samples.petclinic.Pet is an extension of NamedEntity that implements a pet. It holds a List of visits made concerning the pet.
  • org.springframework.samples.petclinic.Visit is a simple JavaBean that implements the notion of a clinic visit for a pet.
  • org.springframework.samples.petclinic.util.EntityUtils provides utility methods for handling entities.
  • org.springframework.samples.petclinic.validation.OwnerValidator is a Spring Validator that verifies correct data entry for the Add and Edit Owner forms.
  • org.springframework.samples.petclinic.validation.PetValidator is a Spring Validator that verifies correct data entry for the Add and Edit Pet forms.
  • org.springframework.samples.petclinic.validation.VisitValidator is a Spring Validator that verifies correct data entry for the AddVisit form.

Business / Persistence Layer

Since the PetClinic application is all about database access and there is very little business logic in the application outside of that, there is no separation of the primary Business and Persistence Layer API's. While this design technique should not be used for an application with more complex business logic, it is acceptable here because all of the non-persistence related business rules have been implemented in business objects and have not leaked into the Persistence Layer. The most important facet of the design is that the Business and Persistence Layers are COMPLETELY independent of the Presentation Layer.

The Persistence Layer can be configured to use either HSQL or MySQL with any one of the following data access technologies aided by infrastructure provided by Spring:

  • JDBC
  • Hibernate 3
  • Java Persistence API

NOTE: Spring also provides infrastructure for using other Object/Relational Mapping frameworks such as JDO and iBATIS SqlMaps, but these are not demonstrated in PetClinic. (See the 'jpetstore' sample application that ships with the full Spring Framework distribution for an example of using iBatis and Spring.)

One of the key elements provided by Spring is the use of a common set of meaningful data access exceptions that can be used regardless of which database or access strategy is used. All of these exceptions derive from org.springframework.dao.DataAccessException. Since most exceptions encountered during database access are indicative of programming errors, DataAccessException is an abstract RuntimeException whose derivatives only need to be caught by application code to handle recoverable errors when it makes sense to do so. This greatly simplifies application code compared to, for example, code using JDBC directly where SqlExceptions must be caught and database specific error codes must be decoded. Examination of the PetClinic source code will show that the persistence-oriented code is completely focused on the relevant transfer of data to/from the referenced objects without extraneous error handling.

The high-level business/persistence API for PetClinic is the org.springframework.samples.petclinic.Clinic interface. Each persistence strategy in PetClinic is a different implementation of the Clinic interface. In each case, the Clinic implementation is fronted by a transactional proxy, configured via the @Transactional annotation, that also implements Clinic. These objects are standard Java dynamic proxies which are created by an instance of org.springframework.transaction.interceptor.TransactionProxyFactoryBean. These proxies are configured in the respective application context file via <tx:annotation-driven /> and specify that all Clinic methods are run in a transactional context. The transaction managers used in PetClinic are all implementations of the org.springframework.transaction.PlatformTransactionManager interface. All of the implementations are by default configured to use a local DataSource that will work in any environment through the use of an instance of org.springframework.jdbc.datasource.DriverManagerDataSource. While this is appropriate for use in a demo or single user program, a connection pooling DataSource, such as an instance of org.apache.commons.dbcp.BasicDataSource, is more appropriate for use in a multi-user application. Another alternative is to obtain one through the Java EE environment using an instance of org.springframework.jndi.JndiObjectFactoryBean.

JDBC Clinic Implementation

Spring provides a number of high-level database access convenience classes in the package org.springframework.jdbc.object. These classes and the lower-level Spring classes that they use in the org.springframework.jdbc.core package provide a higher level of abstraction for using JDBC that keeps the developer from having to correctly implement the handling of the checked SqlExceptions with ugly error-prone nested try-catch-finally blocks. Using the classes in this package allows the developer to focus efforts on the functionality being implemented rather than the mechanics of error handling. When using these classes, it is the responsibility of the developer to provide the SQL needed and to map the parameters to/from the respective domain object. This typically is done by extending one of the org.springframework.jdbc.object classes, initializing its SQL, and overriding a method that takes care of the mapping. In this way, the developer gets to focus on implementing functionality rather than application plumbing. These classes also take care of closing connections to prevent hard to find resource leakage problems. It should be noted that instances of these classes are lightweight, reusable, and threadsafe.

The JDBC implementation of the Clinic interface is org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic, which uses Java 5 language features, org.springframework.jdbc.core.simple.SimpleJdbcTemplate, and org.springframework.jdbc.core.simple.SimpleJdbcInsert. It also takes advantage of classes like org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource and org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper which provide automatic mapping between JavaBean properties and JDBC parameters or query results. SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base class for JDBC implementations of the Clinic interface for Spring 2.0.

The transaction manager used in the JDBC Clinic Implementation is an instance of org.springframework.jdbc.datasource.DataSourceTransactionManager that can be used for local transactions.

Hibernate 3 Clinic Implementation

The Hibernate 3 implementation of the Clinic interface is org.springframework.samples.petclinic.hibernate.HibernateClinic. To simplify using Hibernate, Spring provides the org.springframework.orm.hibernate3.LocalSessionFactoryBean. The Hibernate configuration is provided by the file src/petclinic.hbm.xml.

Java Persistence API (JPA) Clinic Implementation

The JPA implementation of the Clinic interface is org.springframework.samples.petclinic.jpa.EntityManagerClinic, which is based on native JPA usage combined with Spring's @Repository and @Transactional annotations but otherwise has no dependencies on any Spring API's. To simplify JPA usage, Spring provides (among other classes) the org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. The JPA configuration is provided by src/META-INF/orm.xml and src/META-INF/persistence.xml.

ApplicationContext

A Spring org.springframework.context.ApplicationContext object provides a map of user-defined JavaBeans that specify either a singleton object or the initial construction of prototype instances. These beans constitute the Business/Persistence Layer of PetClinic. The following beans are defined in all 3 versions (1 per access strategy) of the PetClinic war/WEB-INF/applicationContext-*.xml file:

  • A PropertyPlaceholderConfigurer, which is configured via <context:property-placeholder … /> and is a singleton bean that replaces ${…} placeholders with values from a properties file, in this case, JDBC-related settings for the dataSource bean described below (see src/jdbc.properties).
  • dataSource, which is a singleton bean that defines the implementation of the source of database connections used by the application.
  • transactionManager, which is a singleton bean that defines the implementation of the transaction management strategy for the application.
  • clinic, which is a singleton bean that defines the implementation of the Clinic interface that provides the primary Business Layer API of the application.

Presentation Layer

The Presentation Layer is implemented as a Java EE Web Application and provides a very thin and concise Model-View-Controller type user interface to the Business and Persistence Layers.

The PetClinic web application is configured via the following files:

  • war/WEB-INF/web.xml: the web application configuration file.
  • war/WEB-INF/petclinic-servlet.xml: configures the petclinic dispatcher servlet and the other controllers and forms that it uses. The beans defined in this file reference the Business/Persistence Layer beans defined in applicationContext-*.xml.
  • war/WEB-INF/classes/messages*.properties: configures the definition of internationalizable message resources.

Examine the comments provided in each of these files for a more in-depth understanding of the details of how the application is configured.

General

  • In web.xml, a context-param, "webAppRootkey", provides the key for a system property that specifies the root directory for the web application. This parameter, "petclinic.root", can be used to aid in configuring the application.
  • In web.xml, a org.springframework.web.context.ContextLoaderListener is defined that loads the root ApplicationContext object of this webapp at startup, by default from the designated /WEB-INF/applicationContext-*.xml. The root org.springframework.web.context.WebApplicationContext of PetClinic is an instance of org.springframework.web.context.support.XmlWebApplicationContext and is the parent of all servlet-specific ApplicationContexts. The Spring root ApplicationContext object provides a map of user-defined JavaBeans that can be used in any and all layers of the application. Beans defined in the root ApplicationContext are automatically available in all child ApplicationContext objects as (external) bean references. Beans defined in an ApplicationContext can also be accessed directly by Java code through getBean(name) method calls.
  • In web.xml, a Servlet named "petclinic" is specified to act as a dispatcher for the entire application. This org.springframework.web.servlet.DispatcherServlet is used to handle all URL's matching the pattern "*.do". As with any Servlet, multiple URL mappings may be defined. It is also possible to define multiple instances of DispatcherServlet. Each DispatcherServlet dispatches requests to registered handlers (Controller interface implementations or POJOs annotated with @Controller) indirectly through a org.springframework.web.servlet.handler.HandlerMapping implementation. Each DispatcherServlet has its own ApplicationContext, by default defined in "{servlet-name}-servlet.xml". In this case, it is in the file "petclinic-servlet.xml". This ApplicationContext is used to specify the various web application user interface beans and the URL mappings that are used by the DispatcherServlet to control the handling of requests.
  • The files web.xml and log4j.properties specify the configuration of logging in the system:
  • In web.xml, a "log4jConfigLocation" context-param is specified that sets the location of the Log4j configuration file. The default location for this file is /WEB-INF/classes/log4j.properties. Specifying this parameter explicitly allows the location to be changed from the default and is also used to cause periodic Log4j configuration refresh checks.
  • In web.xml, a Log4jConfigListener is specified that will initialize Log4j using the specified configuration file when the web app starts. The Log4jConfigListener is commented out in the file because of a conflict when using JBoss. It should also be noted that if the container initializes Servlets before Listeners as some pre-Servlet 2.4 containers do, a Log4jConfigServlet should be used instead.
  • In log4j.properties, the following loggers are specified: - "stdout" provides logging messages to the container's log file. - "logfile" provides logging messages to a rolling file that is specified using the previously defined "petclinic.root". Examination and study of these logging files will provide insight into the operation of the Spring framework and the application as well as valuable troubleshooting information should something not work correctly.

DispatcherServlet

The following beans are accessible to the DispatcherServlet and are defined in the PetClinic petclinic-servlet.xml file. This dispatcher uses these definitions to delegate actual display and form processing tasks to implementations of the Spring org.springframework.web.servlet.mvc.Controller interface. The DispatcherServlet acts as the main application Front Controller and is responsible for dispatching all requests to the appropriate Controller indirectly through a URL mapping handler. These Controllers are responsible for the mechanics of interaction with the user and ultimately delegate action to the Business/Persistence Layers.

  • messageSource is a singleton bean that defines a message source for this ApplicationContext. Messages are loaded from localized "messages_xx" files in the classpath, such as "/WEB-INF/classes/messages.properties" or "/WEB-INF/classes/messages_de.properties". getMessage() calls to this context will use this source. Child contexts can have their own message sources, which will inherit all messages from this source and are able to define new messages and override ones defined in the primary message source.
  • InternalResourceViewResolver is a singleton bean that defines the view mappings used by the dispatcher. Specifically, logical view names returned by Controllers will be mapped to physical paths using the configured 'prefix' and 'suffix' properties. For example, a logical view name of "vets" will be mapped to "/WEB-INF/jsp/vets.jsp".
  • SimpleMappingExceptionResolver is a singleton bean that defines how exceptions are propagated. Exceptions encountered that are not specified are propagated to the servlet container.
  • <context:component-scan ... /> is used to autodetect the controllers in the org.springframework.samples.petclinic.web package, which are POJOs labeled with the @Controller annotation.
  • ClinicController is a singleton, annotation-driven MultiActionController that is used by the dispatcher to handle non-form based display tasks. A method is provided to handle each type of request that is supported.
  • In addition, there are 6 singleton, annotation-driven Form controllers, which are used to handle the various Search, Add and Edit form processing tasks for the dispatcher.
  • The form-based controllers within the PetClinic application provide @RequestMapping annotations at the type level for path mapping URLs and @RequestMapping at the method level for request type mappings (e.g., GET and POST). In contrast, ClinicController – which is not form-based – provides @RequestMapping only at the method level for path mapping URLs. DefaultAnnotationHandlerMapping is driven by these annotations and is enabled by default with Java 5+.

Views

The Controllers used by the dispatcher handle the work flow of the application. The actual display tasks are delegated by the Controllers to implementations of the Spring View interface. These View objects are themselves beans that can render a particular type of view. The handling Controller supplies the View with a data model to render. The data model is provided to the View as a Map of objects. Views are only responsible for rendering a display of the data model and performing any display logic that is particular to the type of View being rendered. Spring provides support for rendering many different types of views: JSP, XSLT, PDF, Velocity templates, Excel files, and others. By using a View mapping strategy, Spring supplies the developer with a great deal of flexibility in supporting easily configurable view substitution.

ClinicController relies on RequestToViewNameTranslator to automatically infer the logical view name from the incoming request URL; whereas, all Form controllers in the PetClinic application return logical view names as Strings. These logical view names are then mapped to physical paths via the configured InternalResourceViewResolver (see the DispatcherServlet section above for further details). Logical view names that are prepended with "redirect:" will be resolved to instances of RedirectView, which simply redirects to another URL. The other resolved Views will be instances of JstlView, which provides some handy support for internationalization & localization in JSP pages that use JSTL.

Messages

The messages*.properties files are loaded from the classpath to provide localized messages for the supported languages. PetClinic supplies a localized "welcome" message as well as localized form entry error messages in the default (i.e., English) and German properties files. See the "countries" sample application for a more detailed example of Spring's support for internationalization.

Presentation Layer classes

  • org.springframework.samples.petclinic.web.ClinicController is an annotation-driven, POJO MultiActionController that is used to handle simple display-oriented URLs.
  • org.springframework.samples.petclinic.web.FindOwnersForm is an annotation-driven, POJO Form controller that is used to search for Owners by last name.
  • org.springframework.samples.petclinic.web.AddOwnerForm is an annotation-driven, POJO Form controller that is used to add a new Owner to the system.
  • org.springframework.samples.petclinic.web.EditOwnerForm is an annotation-driven, POJO Form controller that is used to edit an existing Owner. A copy of the existing Owner is used for editing.
  • org.springframework.samples.petclinic.web.AddPetForm is an annotation-driven, POJO Form controller that is used to add a new Pet to an existing Owner.
  • org.springframework.samples.petclinic.web.EditPetForm is an annotation-driven, POJO Form controller that is used to edit an existing Pet. A copy of the existing Pet is used for editing.
  • org.springframework.samples.petclinic.web.AddVisitForm is an annotation-driven, POJO Form controller that is used to add a new Visit to an existing Pet.

Logical Views & Implemented Use Cases

  • welcome is the "home" screen. It provides links to display a list of all vets, find an owner, or view documentation.
  • vets displays all vets and their specialties.
  • findOwners is used to find owners by last name.
  • findOwnersRedirect redirects to findOwner.
  • selectOwner allows user to select from a list of multiple owners with the same last name.
  • owner displays a owner's data and a list of the owner's pets and their data.
  • ownerRedirect redirects to owner.
  • owner supports AddOwnerForm and EditOwnerForm
  • pet supports AddPetForm and web.EditPetForm
  • visit supports AddVisitForm
  • dataAccessFailure displays a stacktrace

Java Server Pages

  • index.jsp redirects to the "welcome" page.
  • includes.jsp is statically included in all JSP's used in the application. It specifies the taglibs that are in use.
  • header.jsp and footer.jsp display info common to virtually all pages. Spring also supplies support for the integration of Tiles (included in Struts) but this is not used in PetClinic.
  • dataAccessFailure.jsp is the error page configured via SimpleMappingExceptionResolver, which displays a stack trace and normally wouldn't be used in a production version of an application. It can be seen in action by entering a URL of "editOwner.do" or "editPet.do" with an invalid request parameter, for example: /petclinic/owner.do?ownerId=-1. The handlers for these URLs normally expect to see a respective "ownerId" or "petId" request parameter corresponding to an Owner or Pet in the database. Thus, these handlers will throw a DataAccessException when such a request parameter is provided which references a non-existing entity.
  • uncaughtException.jsp is the web.xml configured "error-page". It displays a stack trace and normally wouldn't be used in a production version of an application. It can be seen in action by entering a URL of "editOwner.do" or "editPet.do" without a valid request parameter, for example: /petclinic/owner.do. The handlers for these URLs normally expect to see a respective "ownerId" or "petId" request parameter and throw a ServletException when such a request parameter is not found.
  • welcome.jsp implements welcome.
  • vets.jsp implements vets.
  • findOwners.jsp implements findOwners.
  • owners.jsp implements selectOwner.
  • owner.jsp implements owner.
  • ownerForm.jsp implements ownerForm.
  • petForm.jsp implements petForm.
  • visitForm.jsp implements visitForm.

The following items should be noted regarding the web application implementation design:

  • all JSP's are stored under /WEB-INF/jsp except for index.jsp which is the configured "welcome-file"
  • The use of JSP technology in the application is not exposed to the user, i.e., the end user never sees a URL ending in ".jsp".
  • By convention, all URL's in the application ending in ".do" are handled by web application controllers. Static html pages ending in ".html", such as Javadoc, will be directly served to the end user.
  • The results of all form entries are handled using browser round trip redirection to minimize possible end user confusion.
  • All pages are extremely simple JSP implementations that focus only on providing the necessary functionality.
  • References to Entity objects are passed around in the application by supplying the object's ID as a request parameter.

Testing

  • org.springframework.samples.petclinic.OwnerTests is a simple JUnit 4 based TestCase that supports Business Rule #1.
  • org.springframework.samples.petclinic.AbstractClinicTests is a JUnit 4 based TestCase requiring a live database connection that is used to confirm correct operation of the database access objects in the various implementations of the Clinic interface. "AbstractClinicTests-context.xml" declares a common javax.sql.DataSource. Subclasses specify additional context locations which declare a org.springframework.transaction.PlatformTransactionManager and a concrete implementation of Clinic.
  • AbstractClinicTests extends AbstractTransactionalJUnit4SpringContextTests, one of the valuable testing support classes provided by the Spring TestContext Framework found in the org.springframework.test.context package. The annotation-driven configuration used here represents best practice for integration tests with Spring. Note, however, that AbstractTransactionalJUnit4SpringContextTests serves only as a convenience for extension. For example, if you do not wish for your test classes to be tied to a Spring-specific class hierarchy, you may configure your tests with annotations such as @ContextConfiguration, @TestExecutionListeners, @Transactional, etc.

AbstractClinicTests and its subclasses benefit from the following services provided by the Spring TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up time between test execution.
  • Dependency Injection of test fixture instances, meaning that we don't need to perform application context lookups. See the use of @Autowired on the clinic instance variable, which uses autowiring by type. As an alternative, we could annotate clinic with JSR 250's @Resource to achieve dependency injection by name. (see: @ContextConfiguration, DependencyInjectionTestExecutionListener)
  • Transaction management, meaning each test method is executed in its own transaction, which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there is no need for a teardown or cleanup script. (see: @TransactionConfiguration, @Transactional, TransactionalTestExecutionListener)
  • Useful inherited protected fields, such as a SimpleJdbcTemplate that can be used to verify database state after test operations or to verify the results of queries performed by application code. An ApplicationContext is also inherited and can be used for explicit bean lookup if necessary. (see: AbstractJUnit4SpringContextTests, AbstractTransactionalJUnit4SpringContextTests)
  • The Spring TestContext Framework and related unit and integration testing support classes are shipped in spring-test.jar.

Downloads

  • Download and install the Spring Framework (examples, including PetClinic are provided)
  • Download and install a Java Software Developer Kit, version 1.5 or later
  • Download and install Apache Ant, preferably version 1.7.0 or later
  • Download and install JUnit, preferably version 4.4 or later
  • Download and install Apache Tomcat, preferably version 5.5.x or later
  • Download and install MySQL, preferably version 5.0.x or later (optional)
  • Hypersonic SQL, and Hibernate are provided with the application.
  • PetClinic and Spring use the Apache Commons Logging and Log4J packages

Ant Setup

Make sure that the Ant executable is in your command shell path. Ant will need to reference classes from JUnit and the database(s) of interest. Place a copy of any needed jar files in Ant's /lib directory, i.e.:

  • JUnit - junit.jar
  • HSQL - hsqldb.jar
  • MYSQL - mysql-connector-java-5.1.5-bin.jar or other

HSQL Setup

Create a new directory containing a copy of the entire contents of the directory petclinic/db/hsqldb. The file petclinic.script is the data file that will be used by the server. It has been initialized with some sample data. Start a server on the standard port by executing server.sh(Unix) or server.bat (Windows) or alternatively edit the file to select a port of your choosing. A useful database manager can be started by executing manager.sh (Unix) or manager.bat (Windows). When the application opens, connect to the "HSQL Database Engine Server" using the default parameters. This tool can also be used to manage other databases. To use a different port, it will be necessary to change the PetClinic Database Setup. It may also be necessary to consult the HSQL documentation for instructions on how to change the port the server uses.

MYSQL Setup (optional)

Add the PetClinic database to a running MySQL server by following the explicit instructions found in db/mysql/petclinic_db_setup_mysql.txt. PetClinic expects by default to be able to access the server via the standard port 3306. To use a different port, it will be necessary to change the PetClinic Database Setup.

PetClinic Database Setup

To use a Java EE server supplied connection-pooled data source with Tomcat, it will be necessary to use and possibly edit the appropriate context definition file for the petclinic webapp. To use it, deploy a copy of the appropriate context definition file in Tomcat's webapps directory and restart the server. Consult the Tomcat log files if something goes wrong when starting either Tomcat or the PetClinic application. The context files are named petclinic_tomcat_*.xml, where * is either "hsqldb" or "mysql". There is a context file supplied for each database in its respective directory. There is also a context file db/petclinic_tomcat_all.xml that will provide a JNDI connection-pooled DataSource for all supported databases. Should you use this file, you must of course make sure that all the database servers are running when you restart Tomcat.

NOTES

  • Should you deploy one of the context files or define a context in Tomcat's server.xml, Tomcat will not automatically deploy the webapp from the petclinic.war file. The webapp will then need to be manually extracted to the target directory.
  • The context files will also configure logging to supply a separate log file for the petclinic context. This will separate the container logging for petclinic from that of the other webapps. This should not be confused with the application log file provided through Log4j.
  • An Ant script (db/build.xml) has been provided that can be used to re-initialize either database. To select or configure the data source and database used for the webapp and for testing, you will need to edit the following files:
  • war/WEB-INF/applicationContext-*.xml: for configuring the DataSource in the webapp
  • src/jdbc.properties: for configuring JDBC connection settings for both the webapp and testing
  • build.properties: for running the "tests" target in Ant

Building the PetClinic Application

Open a command line shell and navigate to the directory containing PetClinic and execute "ant". This will display a list of the Ant targets that are available. Make sure the database is running and execute "ant all". This will run the Ant "all" target which will clean and compile everything, generate Javadoc, and execute the tests, including a live test using the database. The other Ant targets provide subsets of this functionality.

Deploying the PetClinic Application

Deploy the web application to the server in the usual way (see notes regarding database setup). If you need instructions for web application deployment, see the Tomcat documentation for details. The Web ARchive file is petclinic.war and can be found in the dist directory.

Using the PetClinic Application

Make sure the PetClinic web application is running and browse to http://localhost:8080/petclinic.