In a spring-mvc application, I am getting the following error:
HTTP Status 400 - Required String parameter 'ownerID' is not present
When I try to load the following url:
http://localhost:8080/petclinic/owners
It is expecting
http://localhost:8080/petclinic/owners?ownerID=1 or some other valid number.
How can I change the code so that it loads the expected content when an ownerID is specified, but also loads some other specified content when there is no ownerID specified, or when the ownerID is not valid? Is this something I need to change in jstl in the jsp or in the controller class?
Here is the part of OwnerController.java that handles the /owners url pattern:
@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(@RequestParam("ownerID") String ownerId, Owner owner, BindingResult result, Map<String, Object> model) {
Collection<Owner> results = this.clinicService.findOwnerByLastName("");
model.put("selections", results);
int ownrId = Integer.parseInt(ownerId);
Owner sel_owner = this.clinicService.findOwnerById(ownrId);//jim added this
model.put("sel_owner",sel_owner);
return "owners/ownersList";
}
And here is the code for ownersList.jsp. Note that it is not accepting the choose...when block that I tried to use to solve this problem:
<body>
<div class="container">
<table>
<tr>
<td></td>
<td>
<spring:url value="/owners/new" var="owner_newUrl"></spring:url>
<a href="${fn:escapeXml(owner_newUrl)}" class="btn btn-info" >Add New Owner</a>
</td>
</tr>
<tr>
<td width=160 valign="top">
<datatables:table id="owners" data="${selections}" cdn="true" row="owner" theme="bootstrap2"
cssClass="table table-striped" paginate="true" info="false"
cssStyle="width: 150px;" align="left" >
<datatables:column title="Name" cssStyle="width: 150px;" display="html">
<spring:url value="/owners?ownerID={ownerId}" var="ownerUrl">
<spring:param name="ownerId" value="${owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(ownerUrl)}"><c:out value="${owner.firstName} ${owner.lastName}"/></a>
</datatables:column>
</datatables:table>
</td>
<c:choose>
<c:when test="${!empty sel_owner}">
<td valign="top">
<table class="table table-striped" style="width:600px;">
<tr>
<td><b><c:out value="${sel_owner.firstName} ${sel_owner.lastName}"/></b></td>
<td></td>
</tr>
<tr>
<td><c:out value="${sel_owner.address}"/></td>
<td><c:out value="${sel_owner.city}"/></td>
</tr>
<tr>
<td><c:out value="${sel_owner.telephone}"/></td>
<td></td>
</tr>
<tr>
<td colspan=2>
<spring:url value="/owners/{ownerId}/edit" var="owner_editUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_editUrl)}" class="btn btn-info" >Edit This Owner</a>
<spring:url value="/owners/{ownerId}/pets/new" var="owner_newpetUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_newpetUrl)}" class="btn btn-info" >Add New Pet</a>
<spring:url value="/owners?ownerID={ownerId}&type=cats" var="owner_catsUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_catsUrl)}" class="btn btn-info" >Show Cats</a>
<spring:url value="/owners?ownerID={ownerId}&type=dogs" var="owner_dogsUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_dogsUrl)}" class="btn btn-info" >Show Dogs</a>
<spring:url value="/owners?ownerID={ownerId}&type=all" var="owner_allUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_allUrl)}" class="btn btn-info" >Show All Pets</a>
</td>
</tr>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'all')}">
<tr>
<td colspan=2>
<p>Pets</p>
<datatables:table id="pets" data="${sel_owner.pets}" cdn="true" row="pet" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${pet.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${pet.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${pet.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'cats')}">
<tr>
<td colspan=2>
<p>Cats</p>
<datatables:table id="cats" data="${sel_owner.cats}" cdn="true" row="cat" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${cat.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${cat.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${cat.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'dogs')}">
<tr>
<td colspan=2>
<p>Dogs</p>
<datatables:table id="dogs" data="${sel_owner.dogs}" cdn="true" row="dog" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${dog.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${dog.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${dog.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
</table>
</td>
</tr>
</c:when>
<c:otherwise>
Print this content if there is no ownerID.
</c:otherwise>
EDIT:
As per advice from Sotirios and Loc, I changed my code to the following, but it is still throwing the same error. Can someone show me explicitly how to fix this so that the /owners url pattern can deliver "some text" along with the list of owners instead of either throwing an error or delivering a default owner's details?
Here is the relevant method in OwnerController.java:
public String processFindForm(@RequestParam(value="ownerID", required=false) String ownerId, Owner owner, BindingResult result, Map<String, Object> model) {
Collection<Owner> results = this.clinicService.findOwnerByLastName("");
model.put("selections", results);
boolean ownerIDValid;
if(ownerId==null){ownerIDValid = false;}
else{//I added this if test
ownerIDValid=true;
Integer ownrId = null;
try {
ownrId = Integer.parseInt(ownerId);
Owner sel_owner = this.clinicService.findOwnerById(ownrId);//jim added this
if (sel_owner == null) ownerIDValid = false;
model.put("sel_owner",sel_owner);
catch( Exception ex) {
ownerIDValid = false;
}
}
model.put("ownerIDValid", ownerIDValid);
return "owners/ownersList";
}
And here is the ownersList.jsp:
<html><head>tags and stuff</head>
<body>
<div class="container">
<table>
<tr>
<td></td>
<td>
<spring:url value="/owners/new" var="owner_newUrl"></spring:url>
<a href="${fn:escapeXml(owner_newUrl)}" class="btn btn-info" >Add New Owner</a>
</td>
</tr>
<tr>
<td width=160 valign="top">
<datatables:table id="owners" data="${selections}" cdn="true" row="owner" theme="bootstrap2"
cssClass="table table-striped" paginate="true" info="false"
cssStyle="width: 150px;" align="left" >
<datatables:column title="Name" cssStyle="width: 150px;" display="html">
<spring:url value="/owners?ownerID={ownerId}" var="ownerUrl">
<spring:param name="ownerId" value="${owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(ownerUrl)}"><c:out value="${owner.firstName} ${owner.lastName}"/></a>
</datatables:column>
</datatables:table>
</td>
<c:if test="${ownerIDValid}">
<td valign="top">
<table class="table table-striped" style="width:600px;">
<tr>
<td><b><c:out value="${sel_owner.firstName} ${sel_owner.lastName}"/></b></td>
<td></td>
</tr>
<tr>
<td><c:out value="${sel_owner.address}"/></td>
<td><c:out value="${sel_owner.city}"/></td>
</tr>
<tr>
<td><c:out value="${sel_owner.telephone}"/></td>
<td></td>
</tr>
<tr>
<td colspan=2>
<spring:url value="/owners/{ownerId}/edit" var="owner_editUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_editUrl)}" class="btn btn-info" >Edit This Owner</a>
<spring:url value="/owners/{ownerId}/pets/new" var="owner_newpetUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_newpetUrl)}" class="btn btn-info" >Add New Pet</a>
<spring:url value="/owners?ownerID={ownerId}&type=cats" var="owner_catsUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_catsUrl)}" class="btn btn-info" >Show Cats</a>
<spring:url value="/owners?ownerID={ownerId}&type=dogs" var="owner_dogsUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_dogsUrl)}" class="btn btn-info" >Show Dogs</a>
<spring:url value="/owners?ownerID={ownerId}&type=all" var="owner_allUrl">
<spring:param name="ownerId" value="${sel_owner.id}"/>
</spring:url>
<a href="${fn:escapeXml(owner_allUrl)}" class="btn btn-info" >Show All Pets</a>
</td>
</tr>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'all')}">
<tr>
<td colspan=2>
<p>Pets</p>
<datatables:table id="pets" data="${sel_owner.pets}" cdn="true" row="pet" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${pet.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${pet.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${pet.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'cats')}">
<tr>
<td colspan=2>
<p>Cats</p>
<datatables:table id="cats" data="${sel_owner.cats}" cdn="true" row="cat" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${cat.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${cat.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${cat.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
<c:if test="${fn:endsWith(requestScope['javax.servlet.forward.query_string'], 'dogs')}">
<tr>
<td colspan=2>
<p>Dogs</p>
<datatables:table id="dogs" data="${sel_owner.dogs}" cdn="true" row="dog" theme="bootstrap2"
cssClass="table table-striped" paginate="false" info="false" filter="false"
cssStyle="width: 350px;" align="left" >
<datatables:column title="Name" cssStyle="width: 200px;" display="html">
<c:out value="${dog.name}"/>
</datatables:column>
<datatables:column title="BirthDate" cssStyle="width: 300px;" display="html">
<joda:format value="${dog.birthDate}" pattern="yyyy-MM-dd"/>
</datatables:column>
<datatables:column title="Type" cssStyle="width: 200px;" display="html">
<c:out value="${dog.type.name}"/>
</datatables:column>
</datatables:table>
</td>
</tr>
</c:if>
</table>
</td>
</tr>
</c:if>
<c:if test="${!ownerIDValid}">
Print this content if there is no ownerID.
</c:if>
</table>
</div>
</body>
</html>