Reputation: 9191
I am working with the master branch of this version of the spring PetClinic sample application. I added the following method to the OwnerController class:
@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(Map<String, Object> model) {
// find owners of a specific type of pet
Integer typeID = 1;//this is just a placeholder
Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
model.put("selections", results);
return "owners/catowners";
}
I mapped out the flow of control through the various resources in the application, and seem to have the other code changes I made working, so that now the error that comes up seems to be related to URL mapping.
When I type the following url in my browser:
http://localhost:8080/petclinic/owners/catowners
I get a 400 error message stating that:
"The request sent by the client was syntactically incorrect."
I want the method above to utilize a file called catowners.jsp, which I located at WEB-INF/jsp/owners/catowners.jsp
Can anyone show me how to fix the code above so that I am able to type in a reasonable url and get the content that is rendered through catowners.jsp?
EDIT:
As per lebolo's request, I am including the entire OwnerController class as follows:
package org.springframework.samples.petclinic.web;
@Controller
@SessionAttributes(types = Owner.class)
public class OwnerController {
private final ClinicService clinicService;
@Autowired
public OwnerController(ClinicService clinicService) {
this.clinicService = clinicService;
}
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
@RequestMapping(value = "/owners/new", method = RequestMethod.GET)
public String initCreationForm(Map<String, Object> model) {
Owner owner = new Owner();
model.put("owner", owner);
return "owners/createOrUpdateOwnerForm";
}
@RequestMapping(value = "/owners/new", method = RequestMethod.POST)
public String processCreationForm(@Valid Owner owner, BindingResult result, SessionStatus status) {
if (result.hasErrors()) {
return "owners/createOrUpdateOwnerForm";
} else {
this.clinicService.saveOwner(owner);
status.setComplete();
return "redirect:/owners/" + owner.getId();
}
}
@RequestMapping(value = "/owners/find", method = RequestMethod.GET)
public String initFindForm(Map<String, Object> model) {
model.put("owner", new Owner());
return "owners/findOwners";
}
@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> 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.clinicService.findOwnerByLastName(owner.getLastName());
if (results.size() < 1) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "owners/findOwners";
}
if (results.size() > 1) {
// multiple owners found
model.put("selections", results);
return "owners/ownersList";
} else {
// 1 owner found
owner = results.iterator().next();
return "redirect:/owners/" + owner.getId();
}
}
//'''''''''CodeMed added this next method 9/5/2013
@RequestMapping(value = "/owners/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(Map<String, Object> model) {
// find owners of a specific type of pet
Integer typeID = 1;//this is just a placeholder
Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
model.put("selections", results);
return "owners/catowners";
}
//'''''''''''''''''''
@RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.GET)
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.clinicService.findOwnerById(ownerId);
model.addAttribute(owner);
return "owners/createOrUpdateOwnerForm";
}
@RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.PUT)
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, SessionStatus status) {
if (result.hasErrors()) {
return "owners/createOrUpdateOwnerForm";
} else {
this.clinicService.saveOwner(owner);
status.setComplete();
return "redirect:/owners/{ownerId}";
}
}
@RequestMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owners/ownerDetails");
mav.addObject(this.clinicService.findOwnerById(ownerId));
return mav;
}
}
Typing in the following url:
http://localhost:8080/petclinic/owners/catowners
Now gives a 404 message as follows:
message /petclinic/WEB-INF/jsp/owners/catowners.jsp
description The requested resource is not available.
However, there is DEFINITELY a file called catowners.jsp located at WEB-INF/jsp/owners/catowners.jsp
Any more suggestions?
SECOND EDIT:
As per Sotirios' question, the following code in mvc-view-config.xml spells out InternalResourceResolver:
<property name="viewResolvers">
<list>
<!-- Default viewClass: JSTL view (JSP with html output) -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- Example: a logical view name of 'vets' is mapped to '/WEB-INF/jsp/vets.jsp' -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- Used here for 'xml' and 'atom' views -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
</list>
</property>
Upvotes: 0
Views: 507
Reputation: 2150
I'm not sure which version of the OwnerController you're using. So it may help if you post the whole class (or at least the signature of the class, e.g. any annotations at the class level).
If you're using a version that doesn't have a class level @RequestMapping
(like this one), then your method level mapping should be
@RequestMapping(value = "/owners/catowners", method = RequestMethod.GET)
since your url (post petclinic app context) is /owners/catowners
Upvotes: 2