Polishing the new RESTful interface to the petclinic webapp (SPR-5487):

* Eliminated redundant 'clinic' servlet mapping (was: http://localhost:8080/petclinic/clinic/owners; now: http://localhost:8080/petclinic/owners)
* A parameterless GET for /owners now returns the list of all owners, rather than an error.
* /owners/form is now /owners/search (distinguishes the 'search form' resource from the 'edit owner form' resource)
* Eliminated any need for redirects, <welcome-file-list/>, and index.jsp. Deleted all of them.
* Updated /owners/{oid}/edit to submit using PUT instead of POST
* Updated URI for edit pet form from /owners/{oid}/pets/{pid} to /owners/{oid}/pets/{pid}/edit (the edit form is a distinct resource)
* Updated /owners/{oid}/pets/{pid}/edit to submit using PUT instead of POST

Changes unrelated to the web interface:

* Partitioned up JSPs into new owners, pets, and vets folders.
* Renamed those JSPs, e.g. ownerForm.jsp -> owners/form.jsp; findOwners.jsp -> owners/search.jsp; owners.jsp -> owners/list.jsp
* Updated various controllers to respect the changes to the URI templates, etc.
* Updated .classpath to include all necessary projects and libs to run the webapp successfully in WTP
* Updated JSP error checking rules to relax validation of fragments like header.jsp and footer.jsp
This commit is contained in:
Chris Beams
2009-02-14 09:11:14 +00:00
parent da2175c0b7
commit 3ddd08942c
23 changed files with 89 additions and 57 deletions

View File

@@ -44,19 +44,19 @@ public class AddOwnerForm {
public String setupForm(Model model) {
Owner owner = new Owner();
model.addAttribute(owner);
return "ownerForm";
return "owners/form";
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) {
new OwnerValidator().validate(owner, result);
if (result.hasErrors()) {
return "ownerForm";
return "owners/form";
}
else {
this.clinic.storeOwner(owner);
status.setComplete();
return "redirect:/clinic/owners/" + owner.getId();
return "redirect:/owners/" + owner.getId();
}
}

View File

@@ -56,19 +56,19 @@ public class AddPetForm {
Pet pet = new Pet();
owner.addPet(pet);
model.addAttribute("pet", pet);
return "petForm";
return "pets/form";
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
return "pets/form";
}
else {
this.clinic.storePet(pet);
status.setComplete();
return "redirect:/clinic/owners/" + pet.getOwner().getId();
return "redirect:/owners/" + pet.getOwner().getId();
}
}

View File

@@ -48,19 +48,19 @@ public class AddVisitForm {
Visit visit = new Visit();
pet.addVisit(visit);
model.addAttribute("visit", visit);
return "visitForm";
return "pets/visitForm";
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("visit") Visit visit, BindingResult result, SessionStatus status) {
new VisitValidator().validate(visit, result);
if (result.hasErrors()) {
return "visitForm";
return "pets/visitForm";
}
else {
this.clinic.storeVisit(visit);
status.setComplete();
return "redirect:/clinic/owners/" + visit.getPet().getOwner().getId();
return "redirect:/owners/" + visit.getPet().getOwner().getId();
}
}

View File

@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.Clinic;
import org.springframework.samples.petclinic.Vets;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -38,8 +39,9 @@ public class ClinicController {
* determine the logical view name based on the request URL: "/welcome.do"
* -&gt; "welcome".
*/
@RequestMapping("/welcome")
public void welcomeHandler() {
@RequestMapping("/")
public String welcomeHandler() {
return "welcome";
}
/**
@@ -53,10 +55,11 @@ public class ClinicController {
* @return a ModelMap with the model attributes for the view
*/
@RequestMapping("/vets")
public ModelMap vetsHandler() {
public String vetsHandler(Model model) {
Vets vets = new Vets();
vets.getVetList().addAll(this.clinic.getVets());
return new ModelMap(vets);
model.addAttribute(vets);
return "vets/list";
}
/**
@@ -67,7 +70,7 @@ public class ClinicController {
*/
@RequestMapping("/owners/{ownerId}")
public ModelAndView ownerHandler(@PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owner");
ModelAndView mav = new ModelAndView("owners/show");
mav.addObject(this.clinic.loadOwner(ownerId));
return mav;
}

View File

@@ -44,19 +44,19 @@ public class EditOwnerForm {
public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.clinic.loadOwner(ownerId);
model.addAttribute(owner);
return "ownerForm";
return "owners/form";
}
@RequestMapping(method = RequestMethod.POST)
@RequestMapping(method = RequestMethod.PUT)
public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) {
new OwnerValidator().validate(owner, result);
if (result.hasErrors()) {
return "ownerForm";
return "owners/form";
}
else {
this.clinic.storeOwner(owner);
status.setComplete();
return "redirect:/clinic/owners/" + owner.getId();
return "redirect:/owners/" + owner.getId();
}
}

View File

@@ -27,7 +27,7 @@ import org.springframework.web.bind.WebDataBinder;
* @author Arjen Poutsma
*/
@Controller
@RequestMapping("/owners/*/pets/{petId}")
@RequestMapping("/owners/*/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {
@@ -52,19 +52,19 @@ public class EditPetForm {
public String setupForm(@PathVariable("petId") int petId, Model model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
return "pets/form";
}
@RequestMapping(method = RequestMethod.POST)
@RequestMapping(method = {RequestMethod.PUT, RequestMethod.POST})
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
return "pets/form";
}
else {
this.clinic.storePet(pet);
status.setComplete();
return "redirect:/clinic/owners/" + pet.getOwner().getId();
return "redirect:/owners/" + pet.getOwner().getId();
}
}
@@ -72,7 +72,7 @@ public class EditPetForm {
public String deletePet(@PathVariable int petId) {
Pet pet = this.clinic.loadPet(petId);
this.clinic.deletePet(petId);
return "redirect:/clinic/owners/" + pet.getOwner().getId();
return "redirect:/owners/" + pet.getOwner().getId();
}
}

View File

@@ -36,30 +36,36 @@ public class FindOwnersForm {
dataBinder.setDisallowedFields(new String[] {"id"});
}
@RequestMapping(value = "/owners/form", method = RequestMethod.GET)
@RequestMapping(value = "/owners/search", method = RequestMethod.GET)
public String setupForm(Model model) {
model.addAttribute("owner", new Owner());
return "findOwners";
return "owners/search";
}
@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processSubmit(Owner owner, BindingResult result, Model model) {
// allow parameterless GET request for /owners to return all records
if(owner.getLastName() == null) {
owner.setLastName(""); // empty string signifies broadest possible search
}
// find owners by last name
Collection<Owner> results = this.clinic.findOwners(owner.getLastName());
if (results.size() < 1) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "findOwners";
return "owners/search";
}
if (results.size() > 1) {
// multiple owners found
model.addAttribute("selections", results);
return "owners";
return "owners/list";
}
else {
// 1 owner found
owner = results.iterator().next();
return "redirect:/clinic/owners/" + owner.getId();
return "redirect:/owners/" + owner.getId();
}
}