Read a form bean property to pass on to a forward - struts-1

I am using struts 1.3. I have a an action I am reusing in 3 different cases. The form bean backing this has a property that has the complete path(passed from the jsp) to which the action should forward in case of success/failure(the path is different for each case depending on what the user is doing). How do I specify this for the input attribute of the action in the struts config to read from that form bean property.

What you can do is return a dynamic ActionForward from your Action class. This lets you use an ActionForward that isn't defined in yourstruts-config.xml
return new ActionForward(path_to_forward, redirect_true_or_false);
This doesn't help you for the input, which expects a JSP and not an ActionForward, but you should be able to do that in the ActionForm's validate() method. The first parameter passed into that method is an ActionMapping. On that object, you should be able to call setInput(String) with the path of your JSP. I have not tried this, but it looks like it should work.

Related

How to change path parameters before passing to controllers in spring?

What is the best way to change path parameter (may be using interceptor) before passing it to controllers ? I am using spring mvc.
Right now, i am adding an extra parameter to get the job done, and checking for that in the controller, but i would rather change the parameter and not change anything in the controller

Java Spring #ModelAttribute method model name

I have been reading this forum for quite awhile and find it VERY useful, thank you to the contributors. I have a question that has plagded me for several weeks. And here it goes.
#RequestMapping(value="updateNote.htm",method=RequestMethod.POST)
public String updateNote(#ModelAttribute("note")NoteBean nb, BindingResult res,Model model){
daoobj.updateNote(nb.getName(),nb.getPath(), nb.getNote());
model.addAttribute("note",daoobj.getByName(nb.getName()));
return("success");
}
#RequestMapping(value="updateNote.htm",method=RequestMethod.GET)
public String updateNote(#ModelAttribute("note")NoteBean nb,Model model){
populateNoteBean();
model.addAttribute("note",daoobj.getByName(nb.getName()));
return("editNote");
}
#ModelAttribute("WHAT")
public NoteBean populateNoteBean() {
NoteBean nnb = new NoteBean();
return nnb;
}
With the method populateNoteBean() the model attribute is "WHAT". But, the name that I use is "note". So when I run the code, the NoteBean is correctly saved to the data base. My question is HOW?? It seems that the name "WHAT" should be "note" or that the model attribute is saving it as no name.
Thank for your time.
With your current code you will have two instances of your notebean in the model!
First spring invokes all modelattribute annotated methods in your controller and places the results in the model. Second it evaluates the ones from your requestmapping method.
The point of a modelattribute annotated method is that you can choose how to create your bean. Load it for example from a database.
We use this approach like that:
modelattr method (name="note")
Loads beans from db
requestmapping method with modelattr param (name="note")
Merges the note bean created by the first method with the request paramters from a submit for example and you habe directly access to the modifed one.
One nice effect:
We do not want to put hidden input fields for all attributes in a form just to be able to merge the entity with the entitymanager. This way you can have a form with only one attribute (plus one for the id to be able to fetch the entity)
Or another one:
If your note bean is an abstract class spring has no possibility to instanciate the bean because it does not know what to instanciate. You can for example add a requestparam parameter in the modelattr annotated method and decide what to do yourself.
This is very well described in the documentation. Either the reference or in the api of either controller, reqestmapping or modelattribute i believe.

Work flow of simpleFormcontroller in spring MVC 3.0

I have seen many examples on how simpleFormcontroller works.
But still I have some confusion.
I want to know when formBackingObject(), referenceData(), onSubmit() methods invoked?
I dont know exact working flow of these methods?
Can anyone explain me?
Workflow is as follows and it is controlled by AbstractFormController class-
The controller receives a request for a new form (typically a GET).
Call to formBackingObject() which by default, returns an instance of the commandClass that has been configured (see the properties the superclass exposes), but can also be overridden to e.g. retrieve an object from the database (that needs to be modified using the form).
Call to initBinder() which allows you to register custom editors for certain fields (often properties of non-primitive or non-String types) of the command class. This will render appropriate Strings for those property values, e.g. locale-specific date strings.
Only if bindOnNewForm is set to true, then ServletRequestDataBinder gets applied to populate the new form object with initial request parameters and the onBindOnNewForm(HttpServletRequest, Object, BindException) callback method is called. Note: any defined Validators are not applied at this point, to allow partial binding. However be aware that any Binder customizations applied via initBinder() (such as DataBinder.setRequiredFields(String[]) will still apply. As such, if using bindOnNewForm=true and initBinder() customizations are used to validate fields instead of using Validators, in the case that only some fields will be populated for the new form, there will potentially be some bind errors for missing fields in the errors object. Any view (JSP, etc.) that displays binder errors needs to be intelligent and for this case take into account whether it is displaying the initial form view or subsequent post results, skipping error display for the former.
Call to showForm() to return a View that should be rendered (typically the view that renders the form). This method has to be implemented in subclasses.
The showForm() implementation will call referenceData(), which you can implement to provide any relevant reference data you might need when editing a form (e.g. a List of Locale objects you're going to let the user select one from).
Model gets exposed and view gets rendered, to let the user fill in the form.
The controller receives a form submission (typically a POST). To use a different way of detecting a form submission, override the isFormSubmission method.
If sessionForm is not set, formBackingObject() is called to retrieve a form object. Otherwise, the controller tries to find the command object which is already bound in the session. If it cannot find the object, it does a call to handleInvalidSubmit which - by default - tries to create a new form object and resubmit the form.
The ServletRequestDataBinder gets applied to populate the form object with current request parameters.
Call to onBind(HttpServletRequest, Object, Errors) which allows you to do custom processing after binding but before validation (e.g. to manually bind request parameters to bean properties, to be seen by the Validator).
If validateOnBinding is set, a registered Validator will be invoked. The Validator will check the form object properties, and register corresponding errors via the given Errors object.
Call to onBindAndValidate() which allows you to do custom processing after binding and validation (e.g. to manually bind request parameters, and to validate them outside a Validator).
Call processFormSubmission() to process the submission, with or without binding errors. This method has to be implemented in subclasses.
Source
For more details and diagrammatic representation to understand the flow you can refer to below link -
SimpleFormController is deprecated since Spring 3.0
In Spring 3.0 use one controller with two methods for the creation process (and a third one for the show page). It typical looks like that:
/**
* Shows a form for car creation.
*/
#RequestMapping(params = "form", method = RequestMethod.GET)
public ModelAndView createForm() {
ModelMap uiModel = new ModelMap();
uiModel.addAttribute("carCreateFormBackingObject", new CarCreateFormBackingObject()); //formBackingObject - often called command object
uiModel.addAttribute("manufactureres", this.manufactureresDao.readAll()); //referenceData
return new ModelAndView("car/create", uiModel);
}
/**
* Creates the car and redirects to its detail page.
*
*/
#RequestMapping(method = RequestMethod.POST)
public ModelAndView create(final #Valid CarCreateFormBackingObject carCreateFormBackingObject,
final BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
ModelMap uiModel = new ModelMap();
uiModel.addAttribute("carCreateFormBackingObject", carCreateFormBackingObject);
uiModel.addAttribute("manufactureres", this.manufactureresDao.readAll()); //referenceData
return new ModelAndView("car/create", uiModel);
}
Car car = this.carService.create(carCreateFormBackingObject.name, ...);
return new ModelAndView(new RedirectView("/cars/" + car.getId(), true)); //redirect to show page
}
still i want to know formBackingObject(),refernceData() method get invoked automatically by whom and when?
Back to your question "still i want to know formBackingObject(),refernceData() method get invoked automatically by whom and when?"
All these methods get invoked by SimpleFormController (and its superclass AbstractFormController), the follow the Template-Method-Pattern. - SimpleFormController defines the process and your concrete subclass "plugsin" in some hooks of this process to gain the business value.
formBackingObject in invoked by AbstractFormController when the controller needs to handle a Submit (POST), or build the Command object for the initial "new" view.
referenceData is always invoked AbstractFormController when it need to build the model for the view.
formBackingObject() method, is used when you want to take some action before rendering page. i.e. like default value in HTML components.
refereceData() method, is used for add reference data in your form, i.e. populating dropdowns
OnSubmit() method, is called whe you submit form.
But, if you are using Spring 3.0
Follow following approach using annotation
#RequestMapping(value = "/index.htm", method = RequestMethod.GET)
public String showLogin() {
return "user/login";
}
This will same as formBackingObject. and in this method use modelMap() and add reference data.
Add methods same way with method = POST which will be same as OnSubmit()
rfe folling link
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/SimpleFormController.html
Read Workflow.. you can simply understand your doubts..
FormBackingObjectMethod()---> #RequestMapping(requestMethod.GET)
while first time form shown to the screen formBackingObject is the reason
initBinder()---> normally used for suppose you want date field should be for example (custom date example : dd**MM***yyyy) needed means use initBinder method
onSubmit() -->#RequestMapping(requestMethod.POST)
while submitting the form onSubmit() method get called
i hope this helps

Displaying Data Table And Submiting Form In One Page Struts

I'm new in Struts, currently I'm using struts 1.3 to build simple Contact application
I want to display data table contains contact list from the database, in the same page I want to create a form for creating new contact and then insert it to database.
I'm using Spring bean and hibernate to do database operation and logic. So here is my flow, my action class will call spring bean, and the spring bean will call dao classes for database operation do some logic, then my action class will put the list into request object named contactList, then in jsp file I'm iterate it using logicLiterate tag.
Displaying the table and submiting all works fine, but when I do validating in ActionForm, and I want to display the error message, I have an error 500. This is because the jsp cannot find attribute named contactList in the request object, because if there is an error in ActionForm classes, Struts not calling the method at my Action class that will read the database and put it into the request object. I can try calling the spring bean in my ActionForm, but I'm afraid it not appropriate, because if there is no error then I will call the spring bean twice for the same work. What do you suggest me to do?
My bad not to read the doc carefully, now i understand that action tag in struts-config.xml have "input" attribute, this attribute specifies the physical page to which the request has to be forwarded if there is an error.
In my case, i just have to specified the input attribute to current path (eg. /contacts.do, etc) so the Action class can do its Action method.
Please note that, this request is forward requuest, not redirect.

Polymorphic Form Binding in Spring MVC

Is it possible to give Spring MVC's form binding some kind of type hint to indicate what class to instantiate and populate with form data?
I've got some quite unusual requirements to try and build a dynamic form, that represents a collection of different objects. The user can add objects from a selection of types to this collection, and then set the properties for that object type using form elements. I can figure out how to create the form using jQuery, but I'm not sure how to get Spring to handle a load of POST data when it won't know what types to bind to in advance.
One way that I can think of doing this is to write your own custom HandlerMethodArgumentResolver , which is responsible for translating the request into the argument values of the controller methods. You should be able to create a custom annotation that will indicate to Spring MVC, that your custom handler method argument resolver will be resolving the specific annotated method arguments(say #CustomType Object argument).
Once the call comes into the handler resolver, you can probably determine the type that the json request should map to, and call the json mapper with the actual type.
You can register a custom argument resolver this way:
<annotation-driven>
<argument-resolvers>
<beans:bean class="..CustomArgumentResolver"/>
</argument-resolvers>
</annotation-driven>

Resources