I am working on struts2. In my action class I have written some accessors (setter-getter). Now, suppose this action class is returning SUCCESS and in struts.xml I am open a jsp page (say abc.jsp) against the result "SUCCESS". I need the values of all getter methods written in action class without creating object of action class in my jsp (i.e abc.jsp).
If your controller has a getPostalCode property you can do:
<s:textfield name="postalCode"/>
Which will bind the value to the controller field. Outside s: tags you can also use jsp-el; the expression ${postalCode} will do the same. Read this documentation
Related
I have an action that has this signature:
public ActionResult Update(ContactForm contactForm)
ContactForm is a class from an edmx file. No code first. Its EF 5.0.0.
The edmx file is auto generated.
I have a relation from ContactForm to ContactFormField, which causes a navigation property.
I named it "Fields". It is of type
EntityCollection<ContactFormField>
When I have fields (and only then) included in the posting caused by post variables that looks like this:
ContactForm.Fields[0].Name=foo&ContactForm.Fields[1].Name=bar
etc...
I get an InvalidOperationException before the action is even called.
It occurs in the setter of Fields.
The message is:
The EntityCollection has already been initialized. The
InitializeRelatedCollection method should only be called to initialize
a new EntityCollection during deserialization of an object graph.
If I try to have an action that takes Fields separately, adding an argument like
public ActionResult Update(ContactForm contactForm,
IEnumerable<ContactFormField> fields)
...those will be retrieved correctly, but for each field I have yet another list of ContactFieldAlternative. In other words, I need to be able to post sub objects.
How do I get rid of the exception?
The problem here is how the model binder is interpreting your URL string. The model binder doesn't have any logic which allows it to assume that multiple parameters in the URL string represent the same object. Therefore, instead of creating one instance of ContactForm and binding your fields, it's trying to create an instance of ContactForm and bind Fields[0] to that, then trying to create another instance of ContactForm to bind Fields[1] to, which obviously your method signature doesn't accept. Without creating a custom overload to the model binder, you really can't submit your form values with this URL pattern (and shouldn't anyway, imo). The intended method for accepting a complex object through a post is either through form elements or JSON. One of the prime objectives of the ASP.Net MVC framework is the use of restful URLs, which your parameter list in the URL isn't.
I have a class A :
class A extends ActionSupport{
int someId;
// getters/setters
public String execute(){
setSomeId(2);
return SUCCESS;
}
public String save(){
// something
}
}
In struts.xml, I have configured an action "ViewId" that takes us to the default method execute, where someId is set. Then, we are taken to a jsp page show.jsp where I can access the someId value. In show.jsp, I have to enter an email id and then submit the page. The action that's now called in "Save" that takes us to the save method of the action class. But, I have given some checks in the corresponding validation.xml file A-Save-validation.xml, which will check the email entered for a format. The problem is that if the xml validation fails, we are taken back to show.jsp, but the viewId parameter is now not available. Why is this so ?
The input page should appear similar to the user as before. Only the fields that are now validated should have an error page associated with them. Any workaround for this ?
Like #Umesh said, validation happens on the corresponding interecptor, before the action's method is called.
When validation fails, the action's method is never called and you will be taken to the INPUT result.
In order to achieve what you want you have some options:
Implement the preparable interface in your action
Peform the validation inside your method.
Use s:action in your jsp before the items you want populated to call an action that populates the relevant section
1 is probably the easiest. I like option 3 as well.
If there is a request parameter 'name' passed to an action, we can receive it in our Action class if we have a field named 'name'. Which interceptor is responsible for doing this ? I looked at the code for ParametersInterceptor, but it only sets the parameters onto the value stack, not in corresponding fields of the action class
but it only sets the parameters onto the value stack, not in
corresponding fields of the action class
There is just a little glitch in your reasoning: The action class is is at the top of the value stack! So com.opensymphony.xwork2.interceptor.ParametersInterceptor is responsible.
As a piece of advice, though, I would suggest that you don't actually have a parameter named "name" on the action class, but rather move such fields from your action class into another class that will serve as your "model". Then, have your action class implement the ModelDriven interface. This will place the model class on the top of the ValueStack instead of the action class instance, and then the "name" parameter will map onto your model instance.
The separation of the model/data concerns into another class from the action/control concerns will make your code more readable and maintainable. Of course, if there is only, say, a single param, then separating it into a separate class would be silly. More than 2 or 3 params, though, and you will benefit from the separation.
I am struts2 for developing my application.
Sample code of action class would be
class sampleAction extends Action {
private List<Employee> employee;
public validate(){
--logic for validation
}
public String prepopulate(){
--logic for populating value of employee list
}
--getters and setters
}
Now my problem is on page load i call prepopulate function and populate the value of employee list. After page submit validate method is called and during that if some error happens control redirects to jsp. but this time the value of employee list is empty. I am using this list for autocompleter tag in struts2.
I have never used Struts 2 built-in validation mechanism, as I prefer client-side validation to avoid an extra round trip. This is purely a personal choice and not a standard.
First I will suggest you not to use Action and use ActionSupport: ActionSupport provides a lot of functionality out of the box and you need not to do everything yourself.
I am assuming that you are using defaultStack and if this is the case than it provides out of the box Prepare Interceptor which takes care of preparing any values before the action itself is called.
In your case, validate is called before the execute method, so you never will get a chance to re-fill the values you need in your JSP.
All you need to make sure that you have prepare() method in your action class. Here are more details for this interceptor:
Prepare Interceptor
FAQ: How do we repopulate controls when validation fails
In action class i am reading value from the database.
Let's say "abc".Now the "abc" value should be populated to jsp page.i.e "abc" value should set to s:hidden field in the jsp page.
Since it is single value , i don't want to use List in the action class.
Is there any other way to do that ?
Why would you want to use a list? Just provide the appropriate getter like:
public Object getAbc(){
return abc;
}
and in your page access it with simple OGNL expression like:
<s:hidden name="filedYouWantToSetThisValueTo" value="%{abc}"/>
Hope I got it right.