SpringMVC - JSP Iteration Issue - model-view-controller

I have the following class that I am attempting to use as a command object
public class Member {
private String datePeriod;
private String status;
private ArrayList <Project> projectList;
}
On the JSP, I would like the form to prefill with a pre-existing values.
<c:forEach items="${member.projectList}" var="project">
<tr>
<td><form:input path="**<var???>**" value="${project.projectEntry.projectDesc}" /></td>
</tr>
</c:forEach>
I am making an error with path which is causing an error in jsp. Does anyone know the proper syntax with regards to each iteration? Thanks.

My Spring MVC is bit rusty but if I remember correctly, path gets translated as the input name property in HTML eventually. So you can put any Label value in there and that should work.
<form:input path="ProjectDescription" value="${project.projectEntry.projectDesc}" type="text" />
This should get translated to:
<input name="ProjectDescription" type="text" value="<whatever_you_have_in_backing_bean>"/>
Do you want to look up name from a backing bean instead? If so you should be able to do something like below. Without knowing your data structure I am assuming it to be status.
<form:input path="member.status" value="${project.projectEntry.projectDesc}" type="text" />
More on the form tag here.

Related

Spring - How to bind form data to a List in model

I have a User model which has a list of address, on User form person can add as many as addresses he wants, how can I bind this data directly to address list?
one way I found is to do like below in jsp, but this requires index variable to add.
<form:input path="address[0].street" type="text"/>
<form:input path="address[0].state" type="text"/>
<form:input path="address[0].postalcode" type="text"/>
Is there any way to set this data dynamically
One workaround you can try, create an AddressWrapper object which accepts list of address . And use this AddressWrapper object inside user model
class AddressWrapper{
private List<Address> addressWrapper;
//generate getters and setters
}
Use this wrapper object for binding address.
class User{
private AddressWrapper addressWrapper;
//generate getters and setters
}
you can use foreach like below code
<c:forEach items="${allAdresses}" var="address" varStatus="status">
<form:input path="address[${status.index}].street" type="text"/>
<form:input path="address[${status.index}].state" type="text"/>
<form:input path="address[${status.index}].postalcode" type="text"/>
</c:forEach>
and if you have new Address you just add new object in allAdresses Array

Spring MVC: (If is possible) search form on submit event generate a URI instead of URL pattern format

I have a #Controller with the following #RequestMapping annotation
#RequestMapping(value={"somevalue"},
method=RequestMethod.GET,
produces=MediaType.TEXT_HTML_VALUE)
public String findOneById(#PathVariable String id, Model model){
model.addAttribute(findOneById(id));
return "some view";
}
Observe it uses #PathVariable, based on URI, it works around /persons/{id}, for example for:
/persons/100
/persons/200
it retrieves an expected person.
that #RequestMapping method works fine when:
I put the URL/URI in the same Web Browser address bar (.../persons/200)
when I generate a report of items including for each one a link to see the details (.../persons/200).
I am trying to create a search form such as follows:
<body>
<spring:url var="findOne" value="/persons/" >
</spring:url>
<form action="${findOne}" method="get">
<table>
<tr>
<td><label for="id"><spring:message code="persona.id.label"/></label></td>
<td><input name="id" id="id" value=""/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="search"/></td>
</tr>
</table>
</form>
</body>
My problem is, when I press submit the form always generates/creates the URL to do the search in the format /persons?id=100. I know it is normal and is expected.
But just being curious and of course if is possible:
Question:
What would be the new configuration to generate a URI pattern such as /persons/100 instead of /persons?id=100 when I press the submit button?
I want avoid create a new #RequestMapping method working around with a #RequestParam (it for ?id=100). It to complement the #RequesMapping method working with #PathVariable (it for /100) version.
Thanks

Simple JSP-Spring 3 dropdown list not working

I know this should be pretty easy but I'm stuck after trying several things.
I'm only trying to display in my jsp a basic dropdown list. Spring version is 3 so I want everything to work with annotations.
JSP form with dropdown list:
<form:form method="post" commandName="countryForm">
<table>
<tr>
<td>Country :</td>
<td><form:select path="country">
<form:option value="Select" label="Select" />
</form:select>
</td>
<tr>
<td colspan="3"><input type="submit" /></td>
</tr>
</table>
</form:form>
CountryForm.java is a plain object with a single String attribute "country", with its getters and setters.
Controller who deals with the GET request is the following:
#Controller
public class CountryFormController {
#RequestMapping(value = "MainView", method = RequestMethod.GET)
public String showForm(Map model) {
CountryForm cform = new CountryForm();
model.put("countryForm", cform);
return "MainView";
}
}
However, when I redirect to the JSP "MainView" I get the typical error:
org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'countryForm' available as request attribute
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:502)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:424)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
What am I doing wrong?
The select tag in the Spring TagLib needs to be provided with a collection, map or array of options. I'm not sure what you would like these to be so I will make some assumptions.
You need to include a collection, map or array of objects in your controller. Ideally you would have a Country class and create new instances for a set of countries. For the example to work with your code, I just created a static list of countries. Add the list to your model and then modify the select tag, setting the options to ${countries}. Assuming country is a field of type String on CountryForm with appropriate get/set methods, the country should data-bind to field when the form is submitted.
Controller
#Controller
public class CountryFormController {
#RequestMapping(value = "MainView", method = RequestMethod.GET)
public String showForm(Map model) {
List<CountryForm> cfs = new ArrayList<CountryForm>();
cfs.add("United States");
cfs.add("Canada");
model.put("countries", cfs);
model.put("countryForm", cform);
return "MainView";
}
}
JSP
<form:select path="countryForm.country" options="${countries}"/>
I have sample code at GitHub, try it an let me know. Look at landing.jsp and UserController
<form:select path="users[${status.index}].type" >
<form:option value="NONE" label="--- Select ---"/>
<form:options itemValue="name" itemLabel="description" />
</form:select>
HTH

Creating a form in Spring

I have a simple contact form in my spring project, which is meant to access a backing object, but I get this error
"Neither BindingResult nor plain target object for bean name 'indexBacking' available as request attribute"
My form looks like this:
<form:form action="index.htm" enctype="multipart/form-data" method="post" commandName="indexBacking" accept-charset="UTF-8">
<form:label path="personName">Name</form:label>
<form:input id="personName" path="personName" autocomplete="false" /><br />
<form:label path="personEmail">Email</form:label>
<form:input id="personEmail" path="personEmail" autocomplete="false" /><br />
<form:label path="personComments">Your Comments</form:label>
<form:input id="personComments" path="personComments" autocomplete="false" /><br />
<input type="submit" alt="Submit"/>
</form:form>
Which is meant to access my controller and save the fields "personName", "personEmail" and "personComments" into my backing object called "indexBacking".
My controller method that I am trying to access is here:
#RequestMapping(value = PAGE_NAME, method = RequestMethod.POST)
public String handleContactForm(ModelMap map, HttpServletRequest request, #ModelAttribute("indexBacking") IndexBacking bo, BindingResult result) {
return MODEL_NAME;
}
But I am not sure hot it links with the backing object. Any ideas what I am doing wrong?
Thanks
Jon
Try using modelAttribute="indexBacking" on form:form instead of commandName="indexBacking".
Also, take a look at this answer; it might have useful information for your case.
The problem was very simple, I was just being an idiot. I saw a colleague of mine working on a form and assumed a few of his classes were part of Spring as default. All I had to do was handle the received data at the other end properly (by calling the appropriate methods in the controller) and it worked fine.
Thanks for your help chaps - credit to #nobeh for pointing me in the right direction.
The problem is in your controller!
The following may help you much for your request Check This

Spring MVC spring:bind tag

Trying to get hold of <spring:bind> tag. I am trying to print a String value. The code looks something like:
mySimpleBean myBean = presentStudent.getSubjects().getTeacherName();
String firstName = myBean.getTeacherFirstName()
Where I get "myBean" from another bean "presentStudent". On jsp I am trying:
<spring:bind path="presentStudent.subjects.teacherName.teacherFirstName">
<input type="text" name="${status.expression}" value="${status.value}">
But it doesnt print anything.
Also "presentStudent" is commandObject for this form:
<form:form id="stuTeachForm" name="stuTeachForm" method="post" commandName="presentStudent"
action="getStuTeachData.html">
You can use the sping input tag instead of the bind tag
<form:form id="stuTeachForm" name="stuTeachForm" method="post" commandName="presentStudent" action="getStuTeachData.html">
<form:input type="text" path="subjects.teacherName.teacherFirstName"/>
Might also be worth outputting the desired value to check your bean has been properly populated
First name is ${presentStudent.subjects.teacherName.teacherFirstName}

Resources