how can i store the value of path variable and use it in my controller method? - spring

When i launch the below url
http://localhost:8090/QuickStartConsulting/quickstart/email?key=6226f7cbe59e99a90b5cef6f94f966fd
The following controller method is invoked
#RequestMapping(value = "/quickstart/email")
public String viewQuickStartEmailForm(#ModelAttribute(value = "quickbean")
QuickStartBean quickbean,BindingResult result,Model model) {
try {
//System.out.println(quickbean.getKey());
email=quickbean.getEmail();
model.addAttribute("email", email);
model.addAttribute("quickstartdatabean",new QuickStartBean() );
} catch (Exception e) {
e.printStackTrace();
}
return "quickstart/emaillogin";
}
Here is my emaillogin jsp page
<form:form id="requestForm" method="GET" modelAttribute="quickbean" ACTION="${pageContext.request.contextPath}/quickstart/email" >
<form:hidden path="key" />
<table>
<tr>
<td><span><img src="<c:url value="/views/images/youremailid.png"/>"> </img></span></td>
<td>
<form:input type="text" style="width: 300px;" id="name" path="email" title="xyz#email.com"/>
</td></tr>
<tr>
<td>
<input type="image" id="invite_btn" src="<c:url value="/views/images/submit.png"/>" title="create invite" width="170" height="32"/>
</td>
</tr>
</table>
</form:form>
How can i store the value of path variable 'key' and use it in my controller method? the emaillogin page is the first page and is not redirected from any other jsp page.

Use the #RequestParam annotation
public String viewQuickStartEmailForm(#RequestParam("key") String key, ....) {...}
Btw: #See #RequestParam vs #PathVariable for details and difference between request params and path variables

First define pathVariables as follows:
public String viewQuickStartEmailForm(#PathVariable Map pathVariables,..)
You can get the values by using below code snippet:
if (pathVariables != null) {
if (pathVariables.containsKey("fieldName") &&
!"undefined".equals(
(String)pathVariables.get("fieldName")) &&
!"null".equals(
(String)pathVariables.get("fieldName"))) {
params.setFieldName((String)pathVariables.get("fieldName"));
}
}

There is a difference between #PathVariable and #RequestParam. For example :
#RequestParam used for accessing the values of the query parameters.
URL : http://localhost:8081/Test/card?cardId=1012111
#RequestMapping("/card")
public String getCard(#RequestParam(value="cardId", required=true) String cardId){
System.out.println("print the value of the cardId : "+cardId)
.......
}
where as #PathVariable used for accessing the values from the URI template.
URL : http://localhost:8081/Test/card/1012111
#RequestMapping("/card/{cardId}")
public String updateCard(#PathVariable(value="cardId") String cardId){
System.out.println("print the value of the cardId : "+cardId)
.......
}
So you can correct your code and use any one of the above mentioned approach rather then mixing both of them.

Related

JSP&Spring: How can I pass one parameter using JSP EL with submit button?

I'm trying to pass one parameter from a jsp page to Spring controller file.
However, I fail and fail again.
When I put just real data of database like a, b, c... instead of "${deleteList['user_id']}", my codes works well.
I have no idea.
I'd be appriciated if I can get your answer.
<table border="0">
<c:forEach items="${deleteList}" var="deleteList">
<tr><td align="right">ID:</td><td>${deleteList.user_id}</td></tr>
</c:forEach>
</table> <form action="${pageContext.request.contextPath}/user/delete" method="get"> <input type="hidden" name="user_id" value="${deleteList['user_id']}" />
<input type="submit" name="confirm" value="Delete" />
#RequestMapping(value = "/delete", params="confirm", method = RequestMethod.GET)
public String deleteConfirm(Model model, HttpServletRequest req) {
String user_id=req.getParameter("user_id");
UmsDAO dao=sqlSession.getMapper(UmsDAO.class);
ArrayList<UVO> uvo = dao.deleteList(user_id);
model.addAttribute("deleteList", uvo);
return "user/deleteConfirm";
}
<c:forEach items="${deleteList}" var="deleteList">
<tr><td align="right">ID:</td><td>${deleteList.user_id}</td></tr>
</c:forEach>
you are not sending any value in user_id..
<tr><td align="right">ID:</td><td>${deleteList.user_id}</td>
<td> from this try once.. you will get specific value what you want</td>
</tr>
Instead of using form every time use anchor tag and send value in partameter
Solution:
use HttpSession
For example:
#RequestMapping(value = "/delete", params = "confirm", method = RequestMethod.GET)
public String deleteConfirm(Model model, HttpServletRequest req) {
HttpSession session = req.getSession();
String user_id = (String) session.getAttribute("user_id");
UmsDAO dao = sqlSession.getMapper(UmsDAO.class);
ArrayList<UVO> uvo = dao.deleteList(user_id);
model.addAttribute("deleteList", uvo);
return "user/deleteConfirm";
}

How do I iterate over all my model attributes on my JSP page?

I'm using Spring 3.2.11.RELEASE with JBoss 7.1.3.Final and Java 6. I have this method in a controller
#RequestMapping(value = "/method", method = RequestMethod.GET)
public String myMethod(final Model model,
final HttpServletRequest request,
final HttpServletResponse response,
final Principal principal)
...
model.addAttribute("paramName", "paramValue");
Notice how I add attributes into my model. My question is, on the JSP page that this page serves, how do I iterate over all the attributes in my model and output them as HIDDEN input fields with the name of the INPUT being the attribute name and the value being what I inserted in the model using that attribute?
Edit: In response to the answer given, here was the output to the JSP solution. Note there are no model attributes in there.
<input type='hidden' name='javax.servlet.jsp.jspRequest' value='org.springframework.web.context.support.ContextExposingHttpServletRequest#7a0a4c3f'>
<input type='hidden' name='javax.servlet.jsp.jspPageContext' value='org.apache.jasper.runtime.PageContextImpl#3939794a'>
<input type='hidden' name='appVersion' value='???application.version???'>
<input type='hidden' name='javax.servlet.jsp.jspResponse' value='org.owasp.csrfguard.http.InterceptRedirectResponse#722033be'>
<input type='hidden' name='javax.servlet.jsp.jspApplication' value='io.undertow.servlet.spec.ServletContextImpl#14c1252c'>
<input type='hidden' name='org.apache.taglibs.standard.jsp.ImplicitObjects' value='javax.servlet.jsp.el.ImplicitObjectELResolver$ImplicitObjects#23c27a49'>
<input type='hidden' name='javax.servlet.jsp.jspOut' value='org.apache.jasper.runtime.JspWriterImpl#b01a1ba'>
<input type='hidden' name='javax.servlet.jsp.jspPage' value='org.apache.jsp.WEB_002dINF.views.lti.launch_jsp#1dcc48bf'>
<input type='hidden' name='javax.servlet.jsp.jspConfig' value='io.undertow.servlet.spec.ServletConfigImpl#3fd40806'>
Model attributes are "request scope" objects
you can do the following (I use JSTL):
<c:forEach items="${requestScope}" var="par">
<c:if test="${par.key.indexOf('attrName_') > -1}">
<li>${par.key} - ${par.value}</li>
</c:if>
</c:forEach>
Since with no filter you will have all the request scope objects, I filtered by the model attributes we wanted to check
I tested by using this code:
#RequestMapping(method = { RequestMethod.GET }, value = { "/*" })
public String renderPage(Model model) throws Exception
{
String requestedUrl = req.getRequestURI();
int indice = requestedUrl.lastIndexOf('/');
String pagina = requestedUrl.substring(indice + 1);
try
{
String usernameUtente = "default username utente";
if (StringUtils.hasText(getPrincipal()))
{
usernameUtente = getPrincipal();
}
model.addAttribute("usernameUtente", usernameUtente);
model.addAttribute("webDebug", webDebug);
for(int i = 0; i<10; i++)
{
model.addAttribute("attrName_"+i, "attrValue_"+i);
}
return pagina;
}
catch (Exception e)
{
String message = "Errore nell'erogazione della pagina " + pagina;
logger.error(message, e);
return "genericError";
}
}
And this is what I see as output (I omitted the not relevant prints but please note you'll print ALL the request scope objects:
attrName_0 - attrValue_0
attrName_1 - attrValue_1
attrName_2 - attrValue_2
attrName_3 - attrValue_3
attrName_4 - attrValue_4
attrName_5 - attrValue_5
attrName_6 - attrValue_6
attrName_7 - attrValue_7
attrName_8 - attrValue_8
attrName_9 - attrValue_9
I hope this can help
Angelo
For avoid headache with parameters added by Spring and Servlet container, it is better to use separate map for pass values into the model. Just use #ModelAttribute and Spring will create and add it to the model automatically:
#RequestMapping(value = "/method", method = RequestMethod.GET)
public String myMethod(final Model model, #ModelAttribute("map") HashMap<String, Object> map) {
map.put("paramName1", "value1");
map.put("paramName2", "value2");
//...and so on
}
Now you can iterate this map in JSP:
<c:forEach items="${map.keySet()}" var="key">
<input type="hidden" name="${key}" value="${map[key]}"/>
</c:forEach>
Also you can access to every item of map next way:
<c:out value="${map.paramName1}"/>
<c:out value="${map.paramName2}"/>
...
If you don't need some parameter to be iterable, add it into the original ModelMap istead of separate map.
In essence all you need is to itterate on all the page attributes. Depending on what you use on your jsp (scriptlets, jstl, or smthing like thymeleaf for html):
Scriptlet:
<form>
<% Session session = request.getSession();
Enumeration attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String name = attributeNames.nextElement();
String value = session.getAttribute(name);
%>
<input type='hidden' name="<% name %>" value="<% value %>">
<%
}
%>
</form>
JSTL:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<h3>Page attributes:</h3>
<form>
<c:forEach items="${pageScope}" var="p">
<input type='hidden' name='${p.key}' value='${p.value}'>
</c:forEach>
</form>
Thymeleaf:
<form>
<input th:each="var : ${#vars}" type='hidden' name="${var.key}" value="${var.value}">
</form>
Simply you can iterate using foreach tag of Jstl.
<c:forEach items="${requestScope}" var="var">
<c:if test="${ !var.key.startsWith('javax.') && !var.key.startsWith('org.springframework')}">
<input type="hidden" name="${var.key}" value="${var.value}" />
</c:if>
</c:forEach>
Request attributes from spring framework and from Servlet do have prefixes, you don't need to add prefix to your request attributes.
Rather you can ignore all those attributes which have prefix "org.springframework" or "javax.".
You can try this:
#RequestMapping(value = "/method", method = RequestMethod.GET)
public String myMethod(final Model model,
final HttpServletRequest request,
final HttpServletResponse response,
final Principal principal)
...
//Create list for param names and another list for param values
List<String> paramNames = new ArrayList();
List<String> paramValues = new ArrayList();
paramNames.add("paramName1");
paramValues.add("paramValue1");
paramNames.add("paramName2");
paramValues.add("paramValue2");
//paramValue1 is the value corresponding to paramName1 and so on...
//add as many param names and values as you need
...
//Then add both lists to the model
model.addAttribute("paramNames", paramNames);
model.addAttribute("paramValues", paramValues);
Then in the JSP, you can iterate over paramNames list, and use the varStatus.index to get the index of current round of iteration and use it to pull the value of corresponding param value from the paramValues list. Like this -
<form id='f' name='myform' method='POST' action='/path/to/servlet'>
<c:forEach items="${paramNames}" var="paramName" varStatus="status">
<input type='hidden' name='${paramName}' value='${paramValues[status.index]}'>
</c:forEach>
</form>
You can add other input elements to the form as needed but the above should generate all the hidden input elements for each of your parameter that you set in the Model.

How to pass checkbox values to the controller in Spring MVC

I have a jsp page with list of functions. Here in controller I get this list from database and pass it to jsp.
#RequestMapping(value = "/functionlist", method = RequestMethod.GET)
public ModelAndView functionList(Model model) throws Exception {
ModelAndView mv = new ModelAndView("functionList");
mv.addObject("functionList", getFunctionsFromDB());
return mv;
}
In my jsp page I create table using this list of functions
<table id="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<c:choose>
<c:when test="${not empty functionList}">
<c:forEach var="function" items="${functionList}">
<tr>
<td><input name="id" value="${function.id}" hidden></td>
<td>${function.name}</td>
<td>
<input type="checkbox" id="${function.id}" value="${function.action}"></td>
</tr>
</c:forEach>
</c:when>
</c:choose>
</tbody>
</table>
<button type="submit" name="save">Save</button>
I also give function id to checkbox id.
My Function entity is the following
public class Function {
private Integer id;
private String name;
private Boolean action;
...
}
I want to press button Save and get in controller "/functionlist/save" my list of checkbox values.
Try to add form like this to your jsp page
<form:form id="yourForm" action="/functionlist/save" method="POST" modelAttribute="functionList">
<c:forEach items="${functionList}" varStatus="status" var="function">
<tr>
<td>${function.name}</td>
<td>
<form:checkbox path="functionList[${status.index}].action"/>
</td>
</tr>
</c:forEach>
<input type="submit" value="submit" />
</form:form>
and in Controller you should have a method like this
#RequestMapping(value = { "/functionlist/save" }, method = RequestMethod.POST)
public String savePerson(#ModelAttribute("functionList")List<Function> functionList) {
// process your list
}
If this does not work, you can try to wrap you list.
public class FunctionListWrapper {
private List<Function> functionList;
public FunctionListWrapper() {
this.functionList = new ArrayList<Function>();
}
public List<Function> getFunctionList() {
return functionList;
}
public void setFunctionList(List<Function> functionList) {
this.functionList = functionList;
}
public void add(Function function) {
this.functionList.add(function);
}
}
in controller instead of passing list, pass wrapper
FunctionListWrapper functionListWrapper=new FunctionListWrapper();
functionListWrapper.setFunctionList(userService.getFunctionList());
mv.addObject("functionListWrapper", functionListWrapper);
For more details please take a look at this questions: question 1 and question 2
First you need to add name attribute to your checkbox inputs.You can get these in
an array on controller with same name as your name attribute.eg-
#RequestMapping(value = "/functionlist", method = RequestMethod.GET)
public ModelAndView functionList(Model model,#RequestParam("checkboxname")String[] checkboxvalues) throws Exception {
ModelAndView mv = new ModelAndView("functionList");
mv.addObject("functionList", getFunctionsFromDB());
return mv;
}
few things.
First you should think about a form object, which is the exchange entity between the view and the controller. The form entity will be something similar to the followng:
public class Form {
private List<Function> functions;
//getters & setters
}
secondly, since you are using Spring MVC, you should leverage the <%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %> library. Consequently, your form will be:
<form:form commandName="form" action="/your/url">
<c:forEach items="${form.functions }" var="function" varStatus="status">
<tr>
<td><form:hidden path="functions[${status.index }].id"></td>
<td>${function.name}</td>
<td>
<form:checkbox path="functions[${status.index }].action" id="${function.id}" value="${function.action}"/>
</td>
</tr>
</c:forEach>
</form:form>
and finally the controller will be something like
#RequestMapping(value="/your/url", method=RequestMethod.POST)
public String postForm(#ModelAttribute("form") FormForm form)
{
//cool stuff here
}
please note that the proper HTTP method is POST, not GET. Yup, I know things work also with GET it's definitely a deprecated strategy.
In addition, figure out how I referred the list of Function in the Form. I used the variable function in the foreach statement when I had to display data, I referred the list when I had to bind the Form object for transferring data to the controller. Last but not least, I haven't tried the code. I wrote it on the fly just to give you hints about how to do it properly.
One last thing. Since you pass the Form to the JSP, you don't need anymore to fill the Model with the attribute you used. Just fill the form with your data and use it to diaplay them in the view. Just like this ${form.stuff.you.want}

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

If you intend to handle the same path in multiple methods Spring

Im using spring MVC.
My Controller is :
#RequestMapping(value = "/approval/pendingescort", method = RequestMethod.GET)
public String getPendingEscort(Model model) {
log.debug("Received request to show Pending Escorts");
// Retrieve all pending escort details by delegating the call to Servicelayer
List<EscortRegistration> pendingEscortdetails = approvalService.getAllPendingEscort();
// Attach zones to the Model
model.addAttribute("pendingEscortdetails", pendingEscortdetails);
// This will resolve to /WEB-INF/jsp/pendingescort.jsp
return "pendingescort";
}
#RequestMapping(value = "/approval/pendingescort/success", method = RequestMethod.GET)
public String addEscort(#RequestParam(value="mobileno", required=true) String mobileno,Model model) {
log.debug("Received request to Accept Escort Request");
// Call ZonedetailsService to do the actual Updating
approvalService.approveEscortRequest(mobileno);
// Add mobile reference to Model
model.addAttribute("mobileno", mobileno);
// This will resolve to /WEB-INF/jsp/addedescortpage.jsp
return "pendingescort";
}
and my JSP Is :
<tbody>
<c:forEach items="${pendingEscortdetails}" var="escort">
<c:url var="editUrl" value="/efmfm/main/approval/pendingescort/success?mobileno=${escort.mobilenumber}" />
<c:url var="deleteUrl" value="/efmfm/main/approval/pendingescort/delete?mobileno=${escort.mobilenumber}" />
<tr>
<td><c:out value="${escort.mobilenumber}" /></td>
<td><c:out value="${escort.imei}" /></td>
<td> Approve
<!-- <td>Approve</td> -->
Reject
</td>
</tr>
</c:forEach>
</tbody
when i click to approve its sending to success page. i want to bring this to previous page with refresh.
Can any one solve my problem.
use
return "redirect:../../../approval/pendingescort";
Instead of
return "pendingescort";
First: I guess you need to use "../.."
return "redirect:../../../approval/pendingescort";
One more doubt. Are you using tiles??

Resources