Having multiple forms on Spring MVC - spring

I am working with Spring MVC 2.5.
Oftentimes, I am only using one form in all my JSP. Now I need to add another form into the same JSP.
My question is, will Spring MVC still support the same lifecycle method whichever form I submit?
I mean, the same databinding, validation, errorhandling, form controller etc?
<div>
<form:form method="post" commandName="station">
</form>
</div>
<div>
<form:form method="post" commandName="fields">
</form>
</div>

The old-style controllers you're using can only support one command object, and therefore only one form, at a time. #Arthur's answer shows that you can't really put both forms on one page, because any given controller will only supply one form object, you'll never get both active at once.
If you want to do this, you're going to have to stop using the old-style controllers (which are obsolescent in Spring 2.5, and deprecated in Spring 3), and use annotated controllers, which are much more flexible. You can mix up your forms pretty much as complex you want.

Spring SimpleFormController just support one kind of Command object. So if you want to use two distinct Spring form into The same JSP, you have to create two SimpleFormController. And inside your JSP, do as follows to avoid some exception
<c:if test="${not empty station}">
<div>
<form:form method="post" commandName="station">
</form>
</div>
</c:if>
<c:if test="${not empty fields}">
<div>
<form:form method="post" commandName="fields">
</form>
</div>
</c:if>

Related

thymeleaf defference action and th:Action?

when attributes are used together with attribute of existing normal attribute and when used alone.
What's the difference..?
For example
<form action="#" th:action="#{/seedstartertermng}" th:object="${seedStarter}" method="post">
<form th:action="#{/seedstartertermng}" th:object="${seedStarter}" method="post">
above, when using action attribute with th:action,
Why do i have to write it twice similar attribute?
can't i use th:action alone?
Does second case using only th:action perform the same function as first case?
ps. Additionally, what is the role of the "#" character in the first sentence..?

Migrate spring Form htmlEscape attribute behavior to Thymeleaf

I'm currently working on a Spring MVC project where we are migrating all our jsp files to thymeleaf. I'm aware that the spring form tag has an htmlEscape attribute that will escape user input when rendering, such as when the user submits an invalid form and the user input is rendered bound to the form. An example of this:
<form:form method="post" id="someForm" modelAttribute="${commandName}" htmlEscape="true" autocomplete="off">
<div class="form-group">
<input type="text" id="username" value="<c:out value='${inputValue}'/>"/>
<input type="password" id="password" />
<input type="submit" class="btn btn-lg btn-block-sm" value="<spring:message code="header.content.close"/>" tabindex="0" />
<input type="hidden" name="_eventId" value="continue"/>
</div>
</form:form>
This fits under the umbrella of output-escaping, which is something that happens on the server side when processing a template to render.
An example of an xss attack this prevents is if the user entered
<script>alert("gotcha");</script> for the username, and some arbitrary value for the password. The form will rerender with the entered username bound to the form. The htmlEscape="true" attribute in the form tag will cause this output to be escaped to mitigate xss. So the username field will contain <script>alert("gotcha");</script> when the bound form rerenders with the error, instead of the actually entered valid html
Is there a standard way to achieve this same functionality in thymeleaf?
A few possibilities I see:
This is already built into thymeleaf.
I'm aware that the spring thymeleaf package uses unbescape to perform output escaping on some attributes, for example SpringValueTagProcessor which I believe escapes output on th:value attributes. However, I'm not sure this is equivalent, and fear there may be security holes left unfilled if this was done in a way that only partially mitigates what the spring form htmlEscape fully mitigates.
If so, please explain how this covers the same cases that htmlEscape does.
There is an existing Spring / Spring MVC solution that is flexible enough to not rely on jsp.
If so, what?
There is a common solution to this for thymeleaf which involves some modification of the template parsing engine.
If so, please explain.
Here is a brief article to give you an idea of what I mean regarding the spring form behavior. Regarding this article, it appears that setting the defaultHtmlEscape to false globally in the web.xml only overrides the default value of HtmlEscapeTag, which appears to only work for spring tags. Thus I don't think the solution can be applied to thymeleaf.
I would appreciate any direction here.
Escaping of output text is done automatically if you use th:text. In rare cases, you can use th:utext if you want to use unescaped text, but you have to be aware of the security implications. See Process thymeleaf variable as html code and not text for some more info.
I ended up getting an answer on the GitHub discussions for the Thymeleaf project here, which I will summarize and clarify:
HTML escaping is built into Thymeleaf form elements by default.
This is evidenced by th:input processor source code. Note the use of getDisplayString which performs html output escaping via org.springframework.web.util.HtmlUtils
I went through and manually checked all the uses of getDisplayString where htmlEscape is false and can verify that in these cases, the output is HTML escaped before displaying (in the case of SpringErrorTagProcessor and SpringUErrorsTagProcessor), they don't output any content to escape (SpringSelectedValueComparator returns a boolean), or the expression is a bound object (SPELVariableExpressionEvaluator).
See GitHub issue thymeleaf/thymeleaf-docs#84 for information regarding the docs being updated accordingly.

<Spring MVC> Second form on same page causing a lot of errors

A short while ago it was decided that our 'support' tool needed some reforming. This included design and technically. One of these things was making several selections, which were present on any form in the tool, session-scoped.
For this purpose it was decided that we extend our menu-bar with a second form. The form right now is causing a lot of trouble. Namely:
Some pages don't load at all, and instead give a net::ERR_INCOMPLETE_CHUNKED_ENCODING error.
If a page works and I submit the form, the following error occurs: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
Whenever I debug the controller-class, it steps through the code and recognises the bound fields, and assigns them to the linked command-class. Whenever I submit the original form (Not the one from the menu-bar) no errors occur.
This is my form (As it stands now, with testing and all that):
<form:form method="post" action="userbar">
<form:errors path="*" cssClass="error"/>
<span id="headerImageLeft"><img src="<c:url value="/static/images/temp_tc_logo.png"/>" alt="Ticketcounter"/></span>
<li id="menuItemProfile"><spring:message code="button.profile" /></li>
<li id="menuItemChangeList"><spring:message code="button.change-list" /></li></a>
<li id="menuItemLogOff"><spring:message code="button.logout" /></li></a>
<li id="menuItemUsername">
<spring:message code="label.user"/>:
<c:out value="${user.username}"/>
</li>
<c:if test="${not empty clientsList || not empty casesList}">
<li id="menuItemClientBrowser">
Show Archive <form:checkbox path="showArchive" id="showArchive" value="showArchive" onchange="submit();"/>
</li>
</c:if>
</form:form>
The net::ERR_INCOMPLETE_CHUNKED_ENCODING is caused by the part. Whenever I remove that, every page loads normally. Even trying:
<spring:bind path="showArchive">
<input type="checkbox".../>
</spring:bind>
gives the error. Whereas on other .jsp files these tags work a-OK.
The pages are built using a template that picks the menubar.jsp and corresponding page-.jsp files and stitches them together. This way the menu is exactly the same throughout the tool.
I hope someone can help me with this issue, and if I've been vague about some things, or maybe if you possibly want to know more, please ask and I shall answer.
Managed to fix it. The errors seemed to have been an issue regarding the ModelAndView my Controller was returning in the onSubmit() function.
I changed it so that, instead of returning a ModelAndView with a URL ánd a Model, it simply returns a RedirectView. No more errors, except for when I change HTML form-elements to Spring form-elements.

Requests with AJAX in a portlet (Liferay)

I have an issue with my portlet and I don't know exactly how to solve it.
My portlet adds or retrieves info from liferay's DB by inserting a name in 2 text fields.
After pressing the submit button, I see the response from the server, a JSON response like this:
{"id":301,"name":"Pepo"}
If a user correctly inserted or if the search throws a good result. I have to go back in the browser to see the portal again.
How can I use AJAX to pass the following URL dynamically from the portlet to the server without refreshing the page afterwards?
http://localhost:8080/c/portal/json_service?serviceClassName=com.liferay.test.service.TrabajadorServiceUtil&serviceMethodName=findByName&servletContextName=TrabajadorPlugin-portlet&serviceParameters=[param1]&param1=NameInsertedByUser
Now I'm using the <form> tag like this:
<%
//Shows "New Employee" in the text field when portlet is rendered, or gets the user input and pass it as a param to the URL
PortletPreferences prefs = renderRequest.getPreferences();
String employee = (String)prefs.getValue("name", "New Employee");
%>
<form id="postForm" method="post" action="http://localhost:8080/c/portal/json_service">
<input name="serviceClassName" type="hidden" value="com.liferay.test.service.TrabajadorServiceUtil" />
<input name="serviceMethodName" type="hidden" value="create" />
<input name="servletContextName" type="hidden" value="TrabajadorPlugin-portlet" />
<input name="serviceParameters" type="hidden" value="[param]" />
<input name="param" type="text" value="<%=employee%>" />
<input type="submit" value="Submit"/>
</form>
I understand how AJAX works, but I need some help to create my function in order to achieve the URL to be correctly sent to the server for both GET and POST requests. This is my first try with AJAX.
Thank you very much, hope somebody understands my problem and could help me.
First of all, I see no point at all to use JSON services here. Just write ordinary portlet with MVC Controller, and in controller write action handling for corresponding actions (storing data, searching etc).
In controller you can directly call static methods like create or findByName from java class com.liferay.test.service.TrabajadorServiceUtil (or TrabajadorLocalServiceUtil) - that's how people usually do it.
If for some reason you really must use JSON, you should of course do these actions with AJAX calls - and render results using JavaScript.
Updating after question update:
The easiest and most correct way to send AJAX requests in Liferay would be to use AlloyUI JS framework that's a part of Liferay. You can read more on how to send AJAX requests with it here: http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/4733559
In order to accomplish your goal I'd suggest implementing processAction(ActionRequest actRequest, ActionResponse actResponse) method in your controller/portlet.
In order to actually send data to it you'll have to have actionURL, which you can create using for example portlet:actionURL tag:
<portlet:actionURL /> or with Java code PortletURL actionUrl = portletResponse.createActionURL();
Then just submit your form using POST to this URL, and in actionRequest you'll have your parameters.

Can you mix and match Spring form tags and regular HTML form tags in a single HTML form?

I have a legacy HTML form that I want to make into a Spring form. Do I need to switch all of the form tags to Spring form tags or could I mix and match them as I please?
In other words, something like this:
<form:form modelAttribute="mymodel" action="/somecontroller/someaction" method="post">
<input type="text" name="something" value="">
</form:form>
instead of this (using only Spring form tags):
<form:form modelAttribute="mymodel" action="/somecontroller/someaction" method="post">
<form:input path="something" />
</form:form>
You can use regular <input /> elements within a <form:form /> without any problems. This is the conventional way to add submit buttons to a Spring form.
See here for more information.

Resources