#164 Spring Boot version of Petclinic ready to deploy to an external web container (ie Tomcat)

This commit is contained in:
Antoine Rey 2016-06-17 18:38:24 +02:00
parent 76a4ca330b
commit a6e81a51a0
66 changed files with 385 additions and 1964 deletions

View file

@ -0,0 +1,57 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic;
import com.github.dandelion.core.web.DandelionFilter;
import com.github.dandelion.core.web.DandelionServlet;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.PersistenceConfiguration;
import net.sf.ehcache.config.PersistenceConfiguration.Strategy;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.samples.petclinic.model.Vets;
import org.springframework.web.servlet.view.xml.MarshallingView;
/**
* PetClinic Spring Boot Application.
*
*/
@Configuration
@EnableAutoConfiguration
@EnableCaching
@ComponentScan
public class PetClinicApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PetClinicApplication.class);
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.samples.petclinic.model.Vets;
import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.servlet.view.xml.MarshallingView;
/**
*
* {@link BeanNameViewResolver} is used to resolve the Atom and Xml views. So, the
* following beans names must match the name of the JSP you want to override and the
* file extension will indicate which bean to use for resolving.
*
*/
@Configuration
public class CustomViewsConfiguration {
@Bean(name = "vets/vetList.xml")
public MarshallingView vetsXmlView() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(Vets.class);
return new MarshallingView(marshaller);
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.config;
import com.github.dandelion.core.web.DandelionFilter;
import com.github.dandelion.core.web.DandelionServlet;
import com.github.dandelion.datatables.core.web.filter.DatatablesFilter;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
/**
* Java configuration for the Dandelion datatables component.
*
* @author Antoine Rey
*/
@Configuration
public class DandelionConfig {
@Bean
@Description("Dandelion filter definition and mapping")
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new DandelionFilter());
return filterRegistrationBean;
}
@Bean
@Description("Dandelion-Datatables filter, used for basic export")
public FilterRegistrationBean datatablesRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new DatatablesFilter());
return filterRegistrationBean;
}
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new DandelionServlet());
servletRegistrationBean.addUrlMappings("/dandelion-assets/*");
servletRegistrationBean.setName("dandelionServlet");
return servletRegistrationBean;
}
}

View file

@ -103,7 +103,9 @@ public class Owner extends Person {
}
public void addPet(Pet pet) {
getPetsInternal().add(pet);
if (pet.isNew()) {
getPetsInternal().add(pet);
}
pet.setOwner(this);
}

View file

@ -110,4 +110,8 @@ public class Pet extends NamedEntity {
visit.setPet(this);
}
}

View file

@ -18,6 +18,9 @@ package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Owner;
@ -30,35 +33,31 @@ import org.springframework.samples.petclinic.model.Owner;
* @author Sam Brannen
* @author Michael Isvy
*/
public interface OwnerRepository {
public interface OwnerRepository extends Repository<Owner, Integer> {
/**
* Retrieve <code>Owner</code>s from the data store by last name, returning all owners whose last name <i>starts</i>
* with the given name.
*
* Retrieve {@link Owner}s from the data store by last name, returning all owners
* whose last name <i>starts</i> with the given name.
* @param lastName Value to search for
* @return a <code>Collection</code> of matching <code>Owner</code>s (or an empty <code>Collection</code> if none
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
* found)
*/
Collection<Owner> findByLastName(String lastName) throws DataAccessException;
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
Collection<Owner> findByLastName(@Param("lastName") String lastName);
/**
* Retrieve an <code>Owner</code> from the data store by id.
*
* Retrieve an {@link Owner} from the data store by id.
* @param id the id to search for
* @return the <code>Owner</code> if found
* @throws org.springframework.dao.DataRetrievalFailureException if not found
* @return the {@link Owner} if found
*/
Owner findById(int id) throws DataAccessException;
@Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
Owner findById(@Param("id") int id);
/**
* Save an <code>Owner</code> to the data store, either inserting or updating it.
*
* @param owner the <code>Owner</code> to save
* @see BaseEntity#isNew
* Save an {@link Owner} to the data store, either inserting or updating it.
* @param owner the {@link Owner} to save
*/
void save(Owner owner) throws DataAccessException;
void save(Owner owner);
}

View file

@ -18,6 +18,8 @@ package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
@ -31,30 +33,27 @@ import org.springframework.samples.petclinic.model.PetType;
* @author Sam Brannen
* @author Michael Isvy
*/
public interface PetRepository {
public interface PetRepository extends Repository<Pet, Integer> {
/**
* Retrieve all <code>PetType</code>s from the data store.
*
* @return a <code>Collection</code> of <code>PetType</code>s
* Retrieve all {@link PetType}s from the data store.
* @return a Collection of {@link PetType}s.
*/
List<PetType> findPetTypes() throws DataAccessException;
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
List<PetType> findPetTypes();
/**
* Retrieve a <code>Pet</code> from the data store by id.
*
* Retrieve a {@link Pet} from the data store by id.
* @param id the id to search for
* @return the <code>Pet</code> if found
* @throws org.springframework.dao.DataRetrievalFailureException if not found
* @return the {@link Pet} if found
*/
Pet findById(int id) throws DataAccessException;
Pet findById(int id);
/**
* Save a <code>Pet</code> to the data store, either inserting or updating it.
*
* @param pet the <code>Pet</code> to save
* @see BaseEntity#isNew
* Save a {@link Pet} to the data store, either inserting or updating it.
* @param pet the {@link Pet} to save
*/
void save(Pet pet) throws DataAccessException;
void save(Pet pet);
}

View file

@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.Vet;
/**
@ -29,7 +30,7 @@ import org.springframework.samples.petclinic.model.Vet;
* @author Sam Brannen
* @author Michael Isvy
*/
public interface VetRepository {
public interface VetRepository extends Repository<Vet, Integer> {
/**
* Retrieve all <code>Vet</code>s from the data store.

View file

@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Visit;
@ -30,7 +31,7 @@ import org.springframework.samples.petclinic.model.Visit;
* @author Sam Brannen
* @author Michael Isvy
*/
public interface VisitRepository {
public interface VisitRepository extends Repository<Visit, Integer> {
/**
* Save a <code>Visit</code> to the data store, either inserting or updating it.

View file

@ -1,158 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;
/**
* A simple JDBC-based implementation of the {@link OwnerRepository} interface.
*
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
*/
@Repository
public class JdbcOwnerRepositoryImpl implements OwnerRepository {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private SimpleJdbcInsert insertOwner;
@Autowired
public JdbcOwnerRepositoryImpl(DataSource dataSource, NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.insertOwner = new SimpleJdbcInsert(dataSource)
.withTableName("owners")
.usingGeneratedKeyColumns("id");
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
/**
* Loads {@link Owner Owners} from the data store by last name, returning all owners whose last name <i>starts</i> with
* the given name; also loads the {@link Pet Pets} and {@link Visit Visits} for the corresponding owners, if not
* already loaded.
*/
@Override
public Collection<Owner> findByLastName(String lastName) throws DataAccessException {
Map<String, Object> params = new HashMap<>();
params.put("lastName", lastName + "%");
List<Owner> owners = this.namedParameterJdbcTemplate.query(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName",
params,
BeanPropertyRowMapper.newInstance(Owner.class)
);
loadOwnersPetsAndVisits(owners);
return owners;
}
/**
* Loads the {@link Owner} with the supplied <code>id</code>; also loads the {@link Pet Pets} and {@link Visit Visits}
* for the corresponding owner, if not already loaded.
*/
@Override
public Owner findById(int id) throws DataAccessException {
Owner owner;
try {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
owner = this.namedParameterJdbcTemplate.queryForObject(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id",
params,
BeanPropertyRowMapper.newInstance(Owner.class)
);
} catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Owner.class, id);
}
loadPetsAndVisits(owner);
return owner;
}
public void loadPetsAndVisits(final Owner owner) {
Map<String, Object> params = new HashMap<>();
params.put("id", owner.getId());
final List<JdbcPet> pets = this.namedParameterJdbcTemplate.query(
"SELECT pets.id, name, birth_date, type_id, owner_id, visits.id as visit_id, visit_date, description, pet_id FROM pets LEFT OUTER JOIN visits ON pets.id = pet_id WHERE owner_id=:id",
params,
new JdbcPetVisitExtractor()
);
Collection<PetType> petTypes = getPetTypes();
for (JdbcPet pet : pets) {
pet.setType(EntityUtils.getById(petTypes, PetType.class, pet.getTypeId()));
owner.addPet(pet);
}
}
@Override
public void save(Owner owner) throws DataAccessException {
BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(owner);
if (owner.isNew()) {
Number newKey = this.insertOwner.executeAndReturnKey(parameterSource);
owner.setId(newKey.intValue());
} else {
this.namedParameterJdbcTemplate.update(
"UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
"city=:city, telephone=:telephone WHERE id=:id",
parameterSource);
}
}
public Collection<PetType> getPetTypes() throws DataAccessException {
return this.namedParameterJdbcTemplate.query(
"SELECT id, name FROM types ORDER BY name", new HashMap<String, Object>(),
BeanPropertyRowMapper.newInstance(PetType.class));
}
/**
* Loads the {@link Pet} and {@link Visit} data for the supplied {@link List} of {@link Owner Owners}.
*
* @param owners the list of owners for whom the pet and visit data should be loaded
* @see #loadPetsAndVisits(Owner)
*/
private void loadOwnersPetsAndVisits(List<Owner> owners) {
for (Owner owner : owners) {
loadPetsAndVisits(owner);
}
}
}

View file

@ -1,48 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.springframework.samples.petclinic.model.Pet;
/**
* Subclass of Pet that carries temporary id properties which are only relevant for a JDBC implementation of the
* PetRepository.
*
* @author Juergen Hoeller
*/
class JdbcPet extends Pet {
private int typeId;
private int ownerId;
public int getTypeId() {
return this.typeId;
}
public void setTypeId(int typeId) {
this.typeId = typeId;
}
public int getOwnerId() {
return this.ownerId;
}
public void setOwnerId(int ownerId) {
this.ownerId = ownerId;
}
}

View file

@ -1,133 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;
/**
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
*/
@Repository
public class JdbcPetRepositoryImpl implements PetRepository {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private SimpleJdbcInsert insertPet;
private OwnerRepository ownerRepository;
private VisitRepository visitRepository;
@Autowired
public JdbcPetRepositoryImpl(DataSource dataSource, OwnerRepository ownerRepository, VisitRepository visitRepository) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.insertPet = new SimpleJdbcInsert(dataSource)
.withTableName("pets")
.usingGeneratedKeyColumns("id");
this.ownerRepository = ownerRepository;
this.visitRepository = visitRepository;
}
@Override
public List<PetType> findPetTypes() throws DataAccessException {
Map<String, Object> params = new HashMap<>();
return this.namedParameterJdbcTemplate.query(
"SELECT id, name FROM types ORDER BY name",
params,
BeanPropertyRowMapper.newInstance(PetType.class));
}
@Override
public Pet findById(int id) throws DataAccessException {
JdbcPet pet;
try {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
pet = this.namedParameterJdbcTemplate.queryForObject(
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id",
params,
new JdbcPetRowMapper());
} catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Pet.class, id);
}
Owner owner = this.ownerRepository.findById(pet.getOwnerId());
owner.addPet(pet);
pet.setType(EntityUtils.getById(findPetTypes(), PetType.class, pet.getTypeId()));
List<Visit> visits = this.visitRepository.findByPetId(pet.getId());
for (Visit visit : visits) {
pet.addVisit(visit);
}
return pet;
}
@Override
public void save(Pet pet) throws DataAccessException {
if (pet.isNew()) {
Number newKey = this.insertPet.executeAndReturnKey(
createPetParameterSource(pet));
pet.setId(newKey.intValue());
} else {
this.namedParameterJdbcTemplate.update(
"UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " +
"owner_id=:owner_id WHERE id=:id",
createPetParameterSource(pet));
}
}
/**
* Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Pet} instance.
*/
private MapSqlParameterSource createPetParameterSource(Pet pet) {
return new MapSqlParameterSource()
.addValue("id", pet.getId())
.addValue("name", pet.getName())
.addValue("birth_date", pet.getBirthDate().toDate())
.addValue("type_id", pet.getType().getId())
.addValue("owner_id", pet.getOwner().getId());
}
}

View file

@ -1,43 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.jdbc.core.RowMapper;
/**
* {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties
* of the {@link JdbcPet} class.
*/
class JdbcPetRowMapper implements RowMapper<JdbcPet> {
@Override
public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
JdbcPet pet = new JdbcPet();
pet.setId(rs.getInt("pets.id"));
pet.setName(rs.getString("name"));
Date birthDate = rs.getDate("birth_date");
pet.setBirthDate(new LocalDate(birthDate));
pet.setTypeId(rs.getInt("type_id"));
pet.setOwnerId(rs.getInt("owner_id"));
return pet;
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.springframework.data.jdbc.core.OneToManyResultSetExtractor;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.samples.petclinic.model.Visit;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* {@link ResultSetExtractor} implementation by using the
* {@link OneToManyResultSetExtractor} of Spring Data Core JDBC Extensions.
*/
public class JdbcPetVisitExtractor extends
OneToManyResultSetExtractor<JdbcPet, Visit, Integer> {
public JdbcPetVisitExtractor() {
super(new JdbcPetRowMapper(), new JdbcVisitRowMapper());
}
@Override
protected Integer mapPrimaryKey(ResultSet rs) throws SQLException {
return rs.getInt("pets.id");
}
@Override
protected Integer mapForeignKey(ResultSet rs) throws SQLException {
if (rs.getObject("visits.pet_id") == null) {
return null;
} else {
return rs.getInt("visits.pet_id");
}
}
@Override
protected void addChild(JdbcPet root, Visit child) {
root.addVisit(child);
}
}

View file

@ -1,89 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.samples.petclinic.model.Specialty;
import org.springframework.samples.petclinic.model.Vet;
import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;
/**
* A simple JDBC-based implementation of the {@link VetRepository} interface.
*
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
* @author Michael Isvy
*/
@Repository
public class JdbcVetRepositoryImpl implements VetRepository {
private JdbcTemplate jdbcTemplate;
@Autowired
public JdbcVetRepositoryImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* Refresh the cache of Vets that the ClinicService is holding.
*/
@Override
public Collection<Vet> findAll() throws DataAccessException {
List<Vet> vets = new ArrayList<>();
// Retrieve the list of all vets.
vets.addAll(this.jdbcTemplate.query(
"SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
BeanPropertyRowMapper.newInstance(Vet.class)));
// Retrieve the list of all possible specialties.
final List<Specialty> specialties = this.jdbcTemplate.query(
"SELECT id, name FROM specialties",
BeanPropertyRowMapper.newInstance(Specialty.class));
// Build each vet's list of specialties.
for (Vet vet : vets) {
final List<Integer> vetSpecialtiesIds = this.jdbcTemplate.query(
"SELECT specialty_id FROM vet_specialties WHERE vet_id=?",
new BeanPropertyRowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int row) throws SQLException {
return rs.getInt(1);
}
},
vet.getId());
for (int specialtyId : vetSpecialtiesIds) {
Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
vet.addSpecialty(specialty);
}
}
return vets;
}
}

View file

@ -1,105 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.stereotype.Repository;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A simple JDBC-based implementation of the {@link VisitRepository} interface.
*
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
* @author Michael Isvy
*/
@Repository
public class JdbcVisitRepositoryImpl implements VisitRepository {
private NamedParameterJdbcTemplate jdbcTemplate;
private SimpleJdbcInsert insertVisit;
@Autowired
public JdbcVisitRepositoryImpl(DataSource dataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.insertVisit = new SimpleJdbcInsert(dataSource)
.withTableName("visits")
.usingGeneratedKeyColumns("id");
}
@Override
public void save(Visit visit) throws DataAccessException {
if (visit.isNew()) {
Number newKey = this.insertVisit.executeAndReturnKey(
createVisitParameterSource(visit));
visit.setId(newKey.intValue());
} else {
throw new UnsupportedOperationException("Visit update not supported");
}
}
/**
* Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance.
*/
private MapSqlParameterSource createVisitParameterSource(Visit visit) {
return new MapSqlParameterSource()
.addValue("id", visit.getId())
.addValue("visit_date", visit.getDate().toDate())
.addValue("description", visit.getDescription())
.addValue("pet_id", visit.getPet().getId());
}
@Override
public List<Visit> findByPetId(Integer petId) {
Map<String, Object> params = new HashMap<>();
params.put("id", petId);
JdbcPet pet = this.jdbcTemplate.queryForObject(
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id",
params,
new JdbcPetRowMapper());
List<Visit> visits = this.jdbcTemplate.query(
"SELECT id as visit_id, visit_date, description FROM visits WHERE pet_id=:id",
params, new JdbcVisitRowMapper());
for (Visit visit: visits) {
visit.setPet(pet);
}
return visits;
}
}

View file

@ -1,42 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.joda.time.LocalDate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.samples.petclinic.model.Visit;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
/**
* {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties
* of the {@link Visit} class.
*/
class JdbcVisitRowMapper implements RowMapper<Visit> {
@Override
public Visit mapRow(ResultSet rs, int row) throws SQLException {
Visit visit = new Visit();
visit.setId(rs.getInt("visit_id"));
Date visitDate = rs.getDate("visit_date");
visit.setDate(new LocalDate(visitDate));
visit.setDescription(rs.getString("description"));
return visit;
}
}

View file

@ -1,6 +0,0 @@
/**
* The classes in this package represent the JDBC implementation
* of PetClinic's persistence layer.
*/
package org.springframework.samples.petclinic.repository.jdbc;

View file

@ -1,81 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jpa;
import java.util.Collection;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.stereotype.Repository;
/**
* JPA implementation of the {@link OwnerRepository} interface.
*
* @author Mike Keith
* @author Rod Johnson
* @author Sam Brannen
* @author Michael Isvy
* @since 22.4.2006
*/
@Repository
public class JpaOwnerRepositoryImpl implements OwnerRepository {
@PersistenceContext
private EntityManager em;
/**
* Important: in the current version of this method, we load Owners with all their Pets and Visits while
* we do not need Visits at all and we only need one property from the Pet objects (the 'name' property).
* There are some ways to improve it such as:
* - creating a Ligtweight class (example here: https://community.jboss.org/wiki/LightweightClass)
* - Turning on lazy-loading and using {@link OpenSessionInViewFilter}
*/
@SuppressWarnings("unchecked")
public Collection<Owner> findByLastName(String lastName) {
// using 'join fetch' because a single query should load both owners and pets
// using 'left join fetch' because it might happen that an owner does not have pets yet
Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName");
query.setParameter("lastName", lastName + "%");
return query.getResultList();
}
@Override
public Owner findById(int id) {
// using 'join fetch' because a single query should load both owners and pets
// using 'left join fetch' because it might happen that an owner does not have pets yet
Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id");
query.setParameter("id", id);
return (Owner) query.getSingleResult();
}
@Override
public void save(Owner owner) {
if (owner.getId() == null) {
this.em.persist(owner);
} else {
this.em.merge(owner);
}
}
}

View file

@ -1,63 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.stereotype.Repository;
/**
* JPA implementation of the {@link PetRepository} interface.
*
* @author Mike Keith
* @author Rod Johnson
* @author Sam Brannen
* @author Michael Isvy
* @since 22.4.2006
*/
@Repository
public class JpaPetRepositoryImpl implements PetRepository {
@PersistenceContext
private EntityManager em;
@Override
@SuppressWarnings("unchecked")
public List<PetType> findPetTypes() {
return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList();
}
@Override
public Pet findById(int id) {
return this.em.find(Pet.class, id);
}
@Override
public void save(Pet pet) {
if (pet.getId() == null) {
this.em.persist(pet);
} else {
this.em.merge(pet);
}
}
}

View file

@ -1,51 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jpa;
import java.util.Collection;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.samples.petclinic.model.Vet;
import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.stereotype.Repository;
/**
* JPA implementation of the {@link VetRepository} interface.
*
* @author Mike Keith
* @author Rod Johnson
* @author Sam Brannen
* @author Michael Isvy
* @since 22.4.2006
*/
@Repository
public class JpaVetRepositoryImpl implements VetRepository {
@PersistenceContext
private EntityManager em;
@Override
@Cacheable(value = "vets")
@SuppressWarnings("unchecked")
public Collection<Vet> findAll() {
return this.em.createQuery("SELECT distinct vet FROM Vet vet left join fetch vet.specialties ORDER BY vet.lastName, vet.firstName").getResultList();
}
}

View file

@ -1,64 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.stereotype.Repository;
/**
* JPA implementation of the ClinicService interface using EntityManager.
* <p/>
* <p>The mappings are defined in "orm.xml" located in the META-INF directory.
*
* @author Mike Keith
* @author Rod Johnson
* @author Sam Brannen
* @author Michael Isvy
* @since 22.4.2006
*/
@Repository
public class JpaVisitRepositoryImpl implements VisitRepository {
@PersistenceContext
private EntityManager em;
@Override
public void save(Visit visit) {
if (visit.getId() == null) {
this.em.persist(visit);
} else {
this.em.merge(visit);
}
}
@Override
@SuppressWarnings("unchecked")
public List<Visit> findByPetId(Integer petId) {
Query query = this.em.createQuery("SELECT v FROM Visit v where v.pet.id= :id");
query.setParameter("id", petId);
return query.getResultList();
}
}

View file

@ -1,6 +0,0 @@
/**
* The classes in this package represent the JPA implementation
* of PetClinic's persistence layer.
*/
package org.springframework.samples.petclinic.repository.jpa;

View file

@ -1,41 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.springdatajpa;
import java.util.Collection;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
import org.springframework.samples.petclinic.model.Owner;
import org.springframework.samples.petclinic.repository.OwnerRepository;
/**
* Spring Data JPA specialization of the {@link OwnerRepository} interface
*
* @author Michael Isvy
* @since 15.1.2013
*/
public interface SpringDataOwnerRepository extends OwnerRepository, Repository<Owner, Integer> {
@Override
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
public Collection<Owner> findByLastName(@Param("lastName") String lastName);
@Override
@Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
public Owner findById(@Param("id") int id);
}

View file

@ -1,38 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.springdatajpa;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.repository.PetRepository;
/**
* Spring Data JPA specialization of the {@link PetRepository} interface
*
* @author Michael Isvy
* @since 15.1.2013
*/
public interface SpringDataPetRepository extends PetRepository, Repository<Pet, Integer> {
@Override
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
List<PetType> findPetTypes() throws DataAccessException;
}

View file

@ -1,29 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.springdatajpa;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository;
/**
* Spring Data JPA specialization of the {@link VisitRepository} interface
*
* @author Michael Isvy
* @since 15.1.2013
*/
public interface SpringDataVisitRepository extends VisitRepository, Repository<Visit, Integer> {
}

View file

@ -1,97 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.util;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.util.StopWatch;
/**
* Simple aspect that monitors call count and call invocation time. It uses JMX annotations and therefore can be
* monitored using any JMX console such as the jConsole
* <p/>
* This is only useful if you use JPA or JDBC. Spring-data-jpa doesn't have any correctly annotated classes to join on
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Michael Isvy
* @since 2.5
*/
@ManagedResource("petclinic:type=CallMonitor")
@Aspect
public class CallMonitoringAspect {
private boolean enabled = true;
private int callCount = 0;
private long accumulatedCallTime = 0;
@ManagedAttribute
public boolean isEnabled() {
return enabled;
}
@ManagedAttribute
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@ManagedOperation
public void reset() {
this.callCount = 0;
this.accumulatedCallTime = 0;
}
@ManagedAttribute
public int getCallCount() {
return callCount;
}
@ManagedAttribute
public long getCallTime() {
if (this.callCount > 0)
return this.accumulatedCallTime / this.callCount;
else
return 0;
}
@Around("within(@org.springframework.stereotype.Repository *)")
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
if (this.enabled) {
StopWatch sw = new StopWatch(joinPoint.toShortString());
sw.start("invoke");
try {
return joinPoint.proceed();
} finally {
sw.stop();
synchronized (this) {
this.callCount++;
this.accumulatedCallTime += sw.getTotalTimeMillis();
}
}
} else {
return joinPoint.proceed();
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,17 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.springdatajpa;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.Vet;
import org.springframework.samples.petclinic.repository.VetRepository;
package org.springframework.samples.petclinic.web;
/**
* Spring Data JPA specialization of the {@link VetRepository} interface
*
* @author Michael Isvy
* @since 15.1.2013
*/
public interface SpringDataVetRepository extends VetRepository, Repository<Vet, Integer> {
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping(value = "/error")
public String error() {
return "exception";
}
@Override
public String getErrorPath() {
return "/error";
}
}

View file

@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.Formatter;
import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.service.ClinicService;
import org.springframework.stereotype.Component;
/**
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have
@ -37,6 +38,7 @@ import org.springframework.samples.petclinic.service.ClinicService;
* @author Juergen Hoeller
* @author Michael Isvy
*/
@Component
public class PetTypeFormatter implements Formatter<PetType> {
private final ClinicService clinicService;

View file

@ -0,0 +1,14 @@
package org.springframework.samples.petclinic.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class WelcomeController {
@RequestMapping("/")
public String welcome() {
return "welcome";
}
}