Displaying Data Table And Submiting Form In One Page Struts - spring

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.

Related

Multiple View Rendering issue in Spring Boot

I am using Spring Boot application. In that i have used Spring MVC at front end. I have a requirement to download various reports like pdf, xls. As i understand, Spring Boot, internally uses ContentNegotiatingViewResolver, BeanNameViewResolver, ViewResolverComposite and InternalResourceViewResolver. I am not overriding any beans in code and using default configurations as provided
Currently to test, i am using below url
http://localhost:8080/SearchCustomers.xls
Properties in application.properties file are
spring.mvc.media-types.pdf=application/pdf
spring.mvc.media-types.xls=application/vnd.ms-excel
In my code, i have created a view class which extends from AbstractPdfView.It is a spring bean and it's id is "SearchCustomers".Controller code returns "SearchCustomers" as a view name.
Whenever i execute above code, ContentNegotiatingViewResolver doesn't returns any view.ContentNegotiatingViewResolver internally uses BeanNameViewResolver, ViewResolverComposite and InteralResourceViewRsolver to resolve view names.In our case, the bean name matches with view but its media type doesn't as it matches the path extension internally along with the bean content type.This is a correct Behavior?
However DispatcherServlet reiterates through all view resolvers and which is causing an issue.
In the second iteration, BeanNameViewResolver matches the bean id with returned view name from controller and it invokes the pdf view,which i believe is incorrect.
Is there any workaround for this?
I found out the solution
If you want just one controller method to handle all type of requests..then in that case your view should be given id in below format
id - viewname + path extension
Ex
My controller method returns view name as "SearchCustomers" for all type of request..
I have created different views for different requests like
#Component("SearchCustomers.pdf")
class MyPdfView extends from AbstractPdfView
#Component("SearchCustomer.xls")
class MyExcelView extends from AbstractExcelView
Interanally, CNVR searches for these beans. and then it matches the mediatype/contenttype which returns the correct view

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>

Best practice for using #SessionAttributes

I am trying to share data between two controllers in a Spring mvc application.
In Controller A I have annotated the class with #SessionAttributes({"mymodel1"}) and in the method which receives the first GET request I add it to the ModelMap:
model.addAttribute("mymodel1", MyModel1);
I now want to read myModel1 from Controller B.
In this Controller I have the following method which intercepts the POST requests and already has a different model in its parameters:
public String processSubmit(#ModelAttribute("mymodel2") MyModel2 mymodel2, BindingResult result, SessionStatus status, HttpServletRequest httpRequest)
Up to this point everything works fine and I am able to read mymodel2 from processSubmit however if I now want to add another #ModelAttribute("mymodel1") MyModel1 mymodel1 to this method signature I would have expected to be able to read the value I was setting in Controller A however I'm getting exceptions that the first model is no longer recognised.
So my question is: how can I read mymodel2 from Controller B?
You can't do that with #SessionAttributes :
Session attributes as indicated using this annotation correspond to a specific handlers model attributes, getting transparently stored in a conversational session. Those attributes will be removed once the handler indicates completion of its conversational session. Therefore, use this facility for such conversational attributes which are supposed to be stored in the session temporarily during the course of a specific handlers conversation.
For example I use this annotation when I want to validate elements with Hibernate validation, and after I submit the page and SOME elements are invalid I want the rest to be still on the page, but this is not your case. I think that the only way to do it would be with:
HttpSession.getAttribute()
The javadoc excerpt above is the most typical way #SessionAttributes is used. However, what Joly is describing should also work. Session attributes are stored via DefaultSessionAttributeStore, which by default does not prefix attribute names when it stores them in the session. That means if ControllerA and ControllerB both list an attribute called "mymodel1", they're actually referring to the same session attribute. You'll need to provide a little more information on the error you're getting and the actual controller code.

Read a form bean property to pass on to a forward

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.

Spring webflow validation

complete and utter newbie on spring webflow (and indeed, spring mvc).
30 minutes in... got the first page of my flow appearing, which happens to be a captcha, an input field and a submit button.
The actual captcha value is stored in session and i need to validate that the input field values matches the value in session.
In order to do validation, my model is passed a 'ValidationContext'.
Question: i can't seem to access session data from the ValidationContext. How do i do this?
Thanks!
try MessageContext in place of validationContext
In spring webflow we have a model class and a model validator class. Make sure you have created a validator method in the validator class and it must have same name as the method you are trying to validate (The method where you have those input fields). This should give you a guideline on getting started.

Resources