Spring MVC - passing variables from one page to anther - java

I need help. I am working on a project where I have multiple pages and multiple forms; each page has one form. I just need to be able to pass values from one jsp to another. What should I do?
I am new to Spring MVC. I am using spring 2.5.6.
Here's my design:
formPage1.jsp --> Controller1 --> formPage2a.jsp --> Controller2 needs val frm pg1 & pg2a.
formPage1.jsp --> Controller1 --> formPage2b.jsp --> Controller3 needs val frm pg1 & pg2b.
formPage1.jsp --> Controller1 --> formPage2c.jsp --> Controller4 needs val frm pg1 & pg2c.
As you can see above, formPage1.jsp can load either formPage2a, formPage2b or formPage2c. Based on the input provided in formPage1.jsp, it goes to the controller (which is an extension of SimpleFormController) and controller get the values entered by user = command object.
I want to be able to use these command object values in either formPage2a, formPage2b or formPage2c when they are submitted to another controller.
here's the current code:
formPage1.jsp:
<form:form method="post" commandName="gainLossRequest">
<form:errors path="*" cssClass="error"/>
<table>
<tr>
<td>
<table>
<tr>
<td><h4>Choose Client</h4></td>
<td style="font-size: medium; font-family: Arial, bold; color: red">*</td>
</tr>
</table>
</td>
<td>
<form:select path="client">
<form:option value="none" label="Select" />
<form:option value="abc" label="abc" />
<form:option value="def" label="def" />
<form:option value="xyz" label="xyz" />
</form:select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="reset" value="Reset" />
<input type="submit" value="Next" />
</td>
</tr>
</table>
</form:form>
Controller1.java
public class TestController extends SimpleFormController {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
public TestController() {
logger.info("entering TestController.constructor..");
setCommandClass(UserPreference.class);
setCommandName("userPreference");
}
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws ServletException {
logger.info("entering TestController.onSubmit all..");
UserPreference userPreference = (UserPreference) command;
ModelAndView view = null;
if ("abc".equals(userPreference.getClient())) {
GainLossRequest gainLossRequest = new GainLossRequest(userPreference);
view = new ModelAndView("redirect:/test/gainLossRequest.htm",
"gainLossRequest", gainLossRequest);
} else if ("def".equals(userPreference.getClient())) {
IncomingPositionsRequest incomingPositionsRequest = new IncomingPositionsRequest();
view = new ModelAndView(
"redirect:/test/incomingPositionsRequest.htm",
"incomingPositionsRequest", incomingPositionsRequest);
} else if ("xyz".equals(userPreference
.getClient())) {
TaxStrategyRequest taxStrategyRequest = new TaxStrategyRequest();
view = new ModelAndView("redirect:/test/taxStrategyRequest.htm",
"taxStrategyRequest", taxStrategyRequest);
}
}
}
formPage2a.jsp
<form:form method="post" commandName="gainLossRequest">
<form:errors path="*" cssClass="error"/>
<table style="width: 60%">
<tr>
<td>Account Number (s):</td>
<td style="font-size: medium; font-family: Arial, bold; color: red">*</td>
</tr>
<tr>
<td>
User Chosen Client:
</td>
<td>
<c:out value="${gainLossRequest.client}"/>
</td>
</tr>
<tr colspan="2">
<td>
<input type="reset" value="Reset" />
<input type="submit" value="Submit" />
</td>
</tr>
dispatcher servlet config
<!-- setupNew.jsp is the first jsp -->
<bean name="/test/setupNew.htm" class="chimeraweb.web.TestController">
<property name="sessionForm" value="true"/>
<property name="commandName" value="userPreference"/>
<property name="commandClass" value="chimeraweb.service.UserPreference"/>
<property name="validator">
<bean class="chimeraweb.service.UserPreferenceValidator"/>
</property>
<property name="formView" value="/test/setupNew"/>
</bean>
<!-- gainLossRequest.jsp is the 2nd jsp where I want to display the values captured in the first jsp page -->
<bean name="/test/gainLossRequest.htm" class="chimeraweb.web.SimpleGainLossController">
<property name="sessionForm" value="true"/>
<property name="commandName" value="gainLossRequest"/>
<property name="commandClass" value="chimeraweb.service.GainLossRequest"/>
<property name="validator">
<bean class="chimeraweb.service.GainLossValidator"/>
</property>
<property name="formView" value="/test/gainLossRequest"/>
</bean>
Please help!!

You could also use session attributes, either manually, such as:
public ModelAndView handleRequest(HttpServletRequest request){
request.getSession().getAttribute("nameOfAttribute");
}
Apologies for writing this as an annotated controller, I do not recall if xml config controllers offer this feature...
There is no Spring code involved for that. The other option is to use the #SessionAttribute annotation on your controller:
#Controller
#SessionAttributes("nameOfAttribute")
public class MyController{
//your session attribute can be accessed in controller methods using #ModelAttribute
public ModelAndView handleRequest(#ModelAttribute("nameOfAttribute")){
session.getAttribute("nameOfAttribute");
}
Note
You will need to clear the session attribute when you are done with it:
request.getSession().setAttribute("nameOfAttribute", null);

You have to persist the user entered information on the first page either using a hidden variable as mentioned above by JB Nizet. Or you can set the value in the model attribute that will be returned on your corresponding controllers.
The pseudo code for you.
formPage1.jsp --> Controller1 --> set the values in this form by retrieving it from the Request object --> formPage2a.jsp --> Controller2 will have val frm both pg1 & pg2a.
In this way there is no need to maintain a session attribute.

The simplest way is to use hidden fields in the second page(s) to store what the user has enetered in the first form. This way, all the fields, inclusing those from the first page, will be submitted with the second form(s).

Related

How to pass data to from view to controller in Spring-MVC?

I have a list of objects as JSON which is inside a workLists. I created a table by iterating using each on workLists and create a table in thymeleaf?
Now how can I pass work that is a single object back to the controller, what I tried is using th:object
I thought it would work but on the controller end null values are coming.
Thymeleaf section
<tr th:each="work , status : ${workLists}">
<td scope="row" th:text="${status.count}"></td>
<td>
<form th:action="#{/edit/work}" th:object="${work}" method="post">
<button type="submit" class="dropdown-item">Edit</button>
</form>
</td>
</tr>
Controller Section
#PostMapping("/edit/work")
public String editWork(#ModelAttribute("work") GetWorkkDto getWorkDto){
logger.debug(" Inside of edit work method");
return "listOfwork";
}
You need to give the contoller 2 attribues which are the workLists and a work. It will be something like:
#GetMapping("/edit/work")
public String editWork(Model model){
model.addAttribute("workLists", workLists);
model.addAttribute("workDTO", new Work());
return "listOfwork";
}
Then in your HTML page through hidden fields you give the values of the work selected:
<table>
<tr th:each="work, stat : ${workLists}">
<td>
<form action="#" th:action="#{/edit/work}" th:object="${workDTO}" method="post">
<input type="hidden" th:attr="name='id'" th:value="${work.id}" />
<input type="hidden" th:attr="name='name'" th:value="${work.name}" />
<input type="hidden" th:attr="name='description'" th:value="${work.description}" />
<p th:text="'Id : '+${work.id}"></p>
<p th:text="'Name : '+${work.name}"></p>
<p th:text="'Description : '+${work.description}"></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</td>
</tr>
</table>
You can see in the proposed code that I give the value of work.id to the workDTO.id through the name attribute (don't ask me why it is like this)
Finaly you retrieve the object in your controller (as you do already) with something like this:
#PostMapping("/edit/work")
public String editWork(#ModelAttribute Work workDTO, Model model){
System.out.println(workDTO.toString());
model.addAttribute("workLists", workLists);
model.addAttribute("workDTO", new Work());
return "listOfwork";
}

Spring MVC form radio input not updating model

I'm creating a web application using Spring MVC framework and forms.
I'm having trouble getting my form to update the field position in my PlayerModel. It simply doesn't save the value when I submit the form (check the controller inline comment on the submit() function).
If I select either radio button (with values 1 and 2) and submit, the model reaches the controller with value 0.
Despite having read countless similar questions/answers here on StackOverflow, I am unable to get this to work. What am I doing wrong here?
[EDIT]
I figured out the problem. For some reason, the value of the name attribute in the radio input is being used to match with the model attribute, instead of using path.
<input type="radio" id="index1" value="1" path="position" name="index" />
So it is trying to match index with the model, which of course does not exist, instead of using the position value in the path attribute.
Shouldn't it be the other way around?
playerView.jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
</head>
<body>
<form:form action="/game/playerView" method="POST" modelAttribute="playerModel">
<table>
<tr>
<th>
<input type="radio" id="index1" value="1" path="position" name="index" />
<input type="radio" id="index2" value="2" path="position" name="index"/>
</th>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</body>
</html>
GameController.java
#Controller
#SessionAttributes("playerModel")
public class GameController {
#RequestMapping(value = "playerView", method = RequestMethod.GET)
public ModelAndView hello(ModelMap map) {
PlayerModel playerModel = new PlayerModel();
playerModel.setPosition(0);
map.addAttribute("playerModel", playerModel);
return new ModelAndView("playerView", "playerModel", playerModel);
}
#RequestMapping(value = "playerView", method = RequestMethod.POST)
public ModelAndView submit(#ModelAttribute("playerModel") PlayerModel playerModel, BindingResult result, ModelMap model){
playerModel.getPosition(); // returns 0
model.addAttribute("playerModel", playerModel);
return new ModelAndView("playerView", "playerModel", playerModel);
}
}
PlayerModel.java
#Resource
public class PlayerModel {
private int position;
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}
You are using Spring-MVC form tag therefore please do not use this <input type="radio" id="index1" value="1" path="position" name="index" /> insted of use like this (For more details)
<tr>
<td>Sex:</td>
<td>
Male: <form:radiobutton path="sex" value="M"/> <br/>
Female: <form:radiobutton path="sex" value="F"/>
</td>
</tr>
and there is no path variable in HTML <input type="radio"> ,
path should be used in the spring type declaration.
eg :
<form:input path="firstName"/> this code is changed to <input name="firstName" type="text"/> by Spring

How to have add and remove buttons in html form handle by spring 5 controller?

I am using Spring 5 and Hibernate 5.
I have got form like below in jsp file:
<form:form action="addUser" method="post" modelAttribute="user">
<table>
<tr>
<td>Name</td>
<td>
<form:input path="name" /> <br />
<form:errors path="name" cssClass="error" />
</td>
</tr>
<tr>
<td>Email</td>
<td>
<form:input path="email" /> <br />
<form:errors path="email" cssClass="error" />
</td>
</tr>
<tr>
<td colspan="1"><button type="submit">Submit</button></td>
<td colspan="1"><button type="???delete???">Remove</button></td>
</tr>
</table>
</form:form>
And UserController.java like below:
#Controller
public class UserController {
#Autowired
private UserService userService;
#GetMapping("/")
public String userForm(Locale locale, Model model) {
model.addAttribute("users", userService.list());
return "editUsers";
}
#ModelAttribute("user")
public User formBackingObject() {
return new User();
}
#PostMapping("/addUser")
public String saveUser(#ModelAttribute("user") #Valid User user, BindingResult result, Model model) {
if (result.hasErrors()) {
model.addAttribute("users", userService.list());
return "editUsers";
}
userService.save(user);
return "redirect:/";
}
}
Right now I have got a submit button which allow me to save name and email of the user.
I would like to add button REMOVE which would also relay on the same form but will instead of adding new user will be removing existing user.
Could you tell how can I do it?
Maybe the first option is to add some attribute like action, but then I need to handle it in controller and I don't know how?
Thank you.
It can be done by changing the form action dynamically based on the button click using some javascript.
<script>
$('#addBtn').click(function(){
$("#userForm").submit();
});
$('#removeBtn').click(function(){
$('#userForm').attr('action', '<your remove action>');
$("#userForm").submit();
});
<script>
<form:form action="addUser" method="post" modelAttribute="user" id="userForm">
...
<td colspan="1"><button type="button" id='addBtn'>Submit</button></td>
<td colspan="1"><button type="button" id='removeBtn'>Remove</button></td>
...
</form:form>

Unable to bind list variable from thymleaf view in spring mvc

I am binding a list to field from thymleaf view, but getting null in the controller. Consider it is not null in view.
<form th:object="${obj}"
<input type="hidden" th:field="*{someList}" th:value="${obj.getSomeList()}">
POJO is like this:
public class Foo {
private int id;
private List<Some> someList;
//setter getter
}
If I bind the id in same way I am getting it in controller, pls help If I have take special care for List.
My controller:
#RequestMapping
public String bar(#ModelAttribute("obj") Foo foo)
Hi Anil after setting the values to a variable you need to iterate through the list using the each tag
Pls find the syntax
<form th:object="${obj}" th:action="#{/list}" action="void(0)" method="post">
<tr>
<td th:field="*{id}" th:text="${obj.id}" />
</tr>
<tr th:each="l , i : ${obj.someList}">
<input type="hidden" th:field="*{someList[__${i.index}__].something}" />
</tr>
<input type="submit" class="btn btn-success" />
</form>

Spring MVC getting value of element that is not an object property on the server

I have a jsp page which uses spring tag lib. I have elements on he page that is bind to properties of an object. I also have button values that are not bind to the POJO i am trying to get these values on the server. Under is the code
JSP
<body>
<form:form id="monitoringList" name="monitoringList" commandName="monitoring">
<h3>Monitoring For Criminals Victims/Wittiness</h3>
<h3>Crime Record - ${crimeRecNo}</h3>
<div id="victims">
<h3>Victims</h3>
<hr>
<input type="hidden" id="records" value="${records}"/>
<div id="citizen_row">
<label class="name"></label>
<form:input class="citizen" type="hidden" name="socialSecurityNumber" path="socialSecurityNumber"/>
<table border="1">
<tr>
<td><form:input type="hidden" path="crimeRecNo" name = "crimeRecNo"/>
<canvas id="photoCvs${citizen.socialSecurityNumber}" class="canvas" height="200" width="200"></canvas></td>
<td><label>Start Date : </label><form:input name= "monitoringStDate" path="monitoringStDate" id="monitoringStDate"/></td>
<td><label>End Date : </label><form:input name="monitoringEndDate" path="monitoringEndDate" id="monitoringEndDate"/></td>
<td>
<label>Monitoring Type : </label>
<form:select path="monitoringTypeId" name="monitoringTypeId" id="monitoringTypeId" title="Monitoring Type">
<form:options items="${monitoringType.monitoringTypeList}" itemValue="monitoringTypeId" itemLabel="monitoringTypeDesc" />
</form:select>
</td>
</tr>
</table>
<div><button id="action" onclick="submitPage('${pageContext.request.contextPath}/monitoringList.htm','POST');" type="button">Create Monitoring Records</button></div>
</div>
<!-- MySql first record starts at 0. So we need to send in the value 0 to get the first record. Create Record Navigation based on record count -->
<div id= "recordNavigation">
<c:forEach begin="0" end="${records - 1}" var="i">
<input type="submit" class="navigationbtns" id="page" onclick="submitPage('${pageContext.request.contextPath}/monitoringList.htm','POST');" value="${i}"/>
</c:forEach>
</div>
</div>
</form:form>
</body>
This is the controller and i am using request.getParameter to get the value of the button however the value id null when i click on the button which post me to the server
Controller
#RequestMapping(value = "monitoringList.htm", method = RequestMethod.POST)
public ModelAndView handleNextMonitoringPage(#ModelAttribute("crimeRecNo")Integer crimeRecNo, Model model,#ModelAttribute Monitoring monitoring, BindingResult result,ModelMap m,HttpServletRequest request,SessionStatus status, HttpSession session) throws Exception {
String p_page = request.getParameter("page");
logger.info("Page request was ::" + p_page);
//int page = 0;
myMonitoringTypeList.put("monitoringTypeList",this.monitoringTypeManager.getListOfMonitoringType());
model.addAttribute("monitoringType",myMonitoringTypeList);
Monitoring aMonitoringRecord = new Monitoring();
aMonitoringRecord = this.monitoringManager.getAMonitoringRecByCrimeRecNo(crimeRecNo, page);
int recordCount = this.monitoringManager.MonitoringRecords_RecordCount(crimeRecNo);
model.addAttribute("records",recordCount);
model.addAttribute("crimeRecNo", crimeRecNo);
model.addAttribute("monitoring", aMonitoringRecord);
return new ModelAndView(new RedirectView("monitoringList.htm"),"page",page);
}
you are missing the name attribute under which the value is being submitted
<button name="page" ....>
and
<input type="submit" name="page" ..../>

Categories