Pass parameter in request while using spring vmc form - spring-mvc

I am using spring mvc form to submit request. I have a hidden variable which i want to pass to the controller. The hidden variable path is using a property which present in the model attribute object. Now I want to pass this hidden variable to the controller. For this one approach is to have the this variable in the model which curremtly is present. But I dont want to put this hidden variable in the model vo object. I just want to pass this hidden field as a request parameter to the controller. Is there any way to do that? If I use html input field type=hidden, will work ?
Please let me know. Below is the code for this. The value of the hi9dden field i am setting from javascript and doing the form submit.
JSP file
<form:form id="form" modelAttribute="customerRelationshipBean">
<form:hidden path="customerSearchBean.action" /> </form>
JS file
document.getElementById("customerSearchBean.action").value='addCustomer';
document.getElementById("form").action = '/gcldw-web/customerSearch' ;
document.getElementById("form").method='POST';
document.getElementById("form").submit();

As soon as you use's spring tags hidden element with a path attribute you establish an associatation with a model bean, and the value ends up in the model
Instead, you can simply add a plain input hidden element, e.g.
<input type="hidden" id="secretValue" name="secretValue" value="" />
place the value to that element (via your js code) and add a suitable #RequestParam argument to your handle method e.g.
public String processSubmit(#ModelAttribute("customerSearchBean") CustomerSearchBean customerSearchBean, BindingResult result,
#RequestParam String secretValue) {

Related

Can I separate a spring form?

I am using tiles, Spring MVC, Spring form tag. I want to make a form that step by step. When click a button, show more inputs from another tiles definition. But throw a exception can not find "Neither BindingResult nor plain target object for bean name " , It looks the "more inputs" can not get bindle object from previous request, is it right?
Source code:
<form:form action="/saveTicker.do" commandName="ticker" modelAttribute="ticker" method="post">
...
<form:input path="name" id="name"/>
Confirm
<div class="row" id="filelist">
</div>
</form>
js
var confirmTicker=function(){
var ticker=$('input:text').val();
$.get("/confirmTicker.do",{ticker:ticker}).success(function(data){
$('#filelist').html(data);
});
}
want to import another file
<table class="table ">
<c:forEach var="f" items="${fileList}">
<tr>
<td>
<form:checkbox path="files" value="${f}"></form:checkbox>
</td>
</tr>
</c:forEach>
</table>
The error is
Neither BindingResult nor plain target object for bean name 'files' available as request attribute
If I am reading this correct, what you want is a "wizard" form where the user is passed from one form to the next as a series of steps. First, I believe Spring Web Flow does this out of the box, but, if like me, you cannot use Spring Web Flow you can do this manually.
First, you need a Form Bean (read Command object) that has all the possible inputs from all the forms.
Next, you will either have one Controller method that accepts your Form Bean and returns the proper step (this is what I did), or you can have multiple methods...it doesn't matter. You will use the #ModelAttribute annotation on the handler method to bind the Form Bean to the view form. Also, #SessionAttributes annotation at the top of the controller to set the Form Bean as a session attribute. Make sure the name of the #ModelAttribute, #SessionAttribute, and the view all correspond to the same attribute name.
Last, create multiple views, each with the same , but each with only the pieces you want to set on the FormBean at that point. You cannot use JSR 303, or at least I don't know how you can, since you can't have validation done between steps. You will have to handle validation at the end on your own.

getParameternames() of servlet

In servlets - getParameterNames() returns the name passed in the request.
I want to ask that if we have 3 form tags into one html file and we want to get the names from form1 and form3 then how we can pass the reference of the form with getParameterNames.
Enumeration enum = req.getParameterNames();
Thanks..
You will only get the parameters for the form that is submitted. I'm not sure what you are trying to do, but you could have hidden form inputs that contain the values of the non-submitted forms. You can set those hidden values using javascript.

Default constructor parameter values in ASP.Net MVC?

I’m using MVC3, with the Razor syntax, and am going over an example in the Apress book “Pro ASP.Net MVC 3 Framework” (which is very good). In it the author has this bit in a _Layout.cshtml file:
<body>
<div id="header">
#{Html.RenderAction("Summary", "Cart");}
<div class="title">SPORTS STORE</div>
</div>
<div id="categories">
#{ Html.RenderAction("Menu", "Nav"); }
</div>
<div id="content">
#RenderBody()
</div>
</body>
My question has to do with the CartController class. I see that it’s passed a Cart object in its constructor, but the code in the _Layout.cshtml snippet above doesn’t appear to pass one in when RenderAction() is called?
CartController snippet:
public ViewResult Summary(Cart cart) {
return View(cart);
}
When I debug that method a Cart object is in fact passed in, but I don’t see where it’s coming from. This sample code uses Ninject as a dependency injection container but I can’t find any evidence in the configuration that it knows anything about the Cart class. Is there a ‘default value’ mechanism in MVC?
Summary is an action method. It is not a constructor. Therefore, DI doesn't have anything to do with this. Instead, what we are seeing is the behavior of the default model binder. That is to say, the model binder will analyze whatever parameters you declare for your action method and will attempt to populate these arguments with data derived from form or query string parameters and route values.
In your particular scenario, since you are not passing in any route values to your Html.Action call, all it's doing is instantiating the Cart class -- if you inspect it you will presumably see that it's empty (no properties have been set).
However, if you were to pass route values into your Action call, it would populate that object. For example, if Cart contained a property called "Size" of type int, and your action call looked like:
#Html.Action("Summary", "Cart", new { Size = 5 })
Your Cart class would now have its Size property set to 5.
(Note also that it's far cleaner to use the Action method and not the RenderAction method in this case. As you've seen, RenderAction assumes a statement-level call, which requires those ugly enclosing curly braces. Action on the other hand is an expression and returns the actual HTML content inline, and thus can be expressed in a more concise fashion.)
Summary is actually an action method, not a constructor. The data can come from a number of different places:
Route parameters
Query String
Form Variables
Etc.

Spring MVC checkbox tag bound to collection expects object but validation expects object.id

In my Spring MVC project I have an update page for Class1 that must display a list of form:checkbox tags that is bound to a collection of entities on Class1.
Class1.java:
class Class1 {
private Set<Class2> set;
//... other fields
}
In updateclass1.jspx:
<c:forEach items="${allClass2Instances}" var="class2">
<form:checkbox label="${class2.name}" path="set" value="${class2}"/><br/>
</c:forEach>
With the checkbox tag as above, when I display the page, the checkbox is ticked if the Class2 instance is part of the Set on class1, and unticked if it isn't. But when I hit submit, I get the following error:
Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Set' for property 'set'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "Name 1" from type 'java.lang.String' to type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "Name1"
As far as I can tell when the page is populated, the form:checkbox tag needs an instance to set the correct checked/unchecked value, but on submit the JSP is sending an array of class2.toString() values to a converter that expects the IDs. Conversely when I change the tag to the following:
<form:checkbox label="${class2.name}" path="set" value="${class2.id}"/><br/>
The binding works fine, but when I view the update page the checkboxes are not ticked / unticked correctly because the tag does not know that value being passed in is the object id.
How do I make the binding after submit consistent with what the checkbox tag expects?
In case it matters - this is all inside a scaffolding page generated by Roo.
Figured out how to make this work for now. If anyone comes up with a neater solution please add it and I'll mark it correct instead.
The problem above was being caused by needing ${InstanceOfClass2} to evaluate to different things in different places:
At the time of evaluation of the tag, <form:checkbox> needed an expression that evaluated to an actual instance of Class2
After the tag completed, the value attribute of the generated <input type="checkbox"> tag needs to be equal to a numerical ID field of an instance of Class2
The solution was to add a converter to my Class1Controller, eg:
Converter<Class2, String> getClass2Converter() {
return new Converter<Class2, String>() {
public String convert(Class2 instance) {
return "" + instance.getId();
}
};
}
Thus the expression ${InstanceOfClass2} evaluates to a Class2 instance for the checkbox tag, but when it comes to writing the actual HTML is converted to a numerical ID.
This approach is very messy when working with Roo. All of the other scaffolding relating to Class1 then wants to use this same Converter, so I started seeing a whole bunch of IDs everywhere that you would want to see Class2.name or other such fields. I solved this by modifying the Spring Roo <field:display> custom tag - added an attribute fmtCollectionToString that if present forces the tag to evaluate collections by iterating them and calling toString on each element, instead of calling spring:eval on the whole collection, which also seems to end up with the Converter being invoked.
Like I say, neater solutions greatly appreciated! If there's a way of making converters behave differently in different circumstances, for instance - still want to hear it.

ASP.NET MVC model binding and action parameters

Let's say I have a controller action defined as:
public ActionResult(MyModel model, string someParameter)
{
// do stuff
}
I have a custom model binder for the MyModel type, and there is a form field called "SomeParameter" in the view that is not bound to the model. How does ASP.NET MVC know to pass the value of Request.Form["SomeParameter"] as the value for the "someParameter" argument to the action?
ASP.NET uses reflection to determine the correct method to invoke and to built up the parameters to pass. It does so based on the FormCollection array. Basically it will see model.* Keysin there and a FormCollection["someParameter"] it will first try Action(model,someParameter) then Action(model) and then Action(). Since it finds an Action with a model and someParameter arguments it will then try to convert them into the arguments types.
However by default it does so blindly which introduces some security risks, this blog post goes into greater detail on this.
If anyone can post up a link which in greater detail describes how ModelBinding is done under the hood that would be great.
Because the default model binder will be used for someParameter unless you specify otherwise. And the default model binder does exactly what you describe.
Phil Haack has a post on How a Method becomes an Action which explains just how this resolution happens.
Sounds like you need a model binder. These allow you to define how form data is bound to a model parameter. You can read more about them at the following:
ASP.NET MVC Preview 5 and Form Posting Scenarios
How to use the ASP.NET MVC Modelbinder
One of the easiest way is having Html items on the page with same name as the input parameters in the action method.
EX) In the View we have:
<input name="refNo" type="text">
Then in the Action method:
public ActionResult getOrders(string refNo)
So, it simply bind the value of "refNo" to the input parameter of the "getOrders" action.

Resources