spring mvc form handling without using spring tag - spring

Recently, I have been researching a new framework for the purpose of building a web-application. To this end, I wanted to try out Spring MVC. Of the many parameters for evaluating a framework, one is that I don't want to be bound to the tag libs associated with the framework to make use of the HTTP request parameter -> Java bean translation. The Spring MVC documentation repeatedly mentions that it is possible to do view related things with only JSTL and no Spring tags, however, I haven't found a way to get the Request-to-Bean translation feature [SimpleFormController] to work without Spring tags.
As of now, the only way seems to extract the request parameters one by one and set to my bean. Is there any way to perform this translation w/o using framework dependent tags?
I appreciate your inputs!

I use Spring Web MVC without Velocity templates (non-JSP templating). To answer your question, you need to understand how Spring performs data binding. Basically, it's all in the name you give your input elements. E.g
<input name="properytOne" value="1" type="hidden">
<input name="properytTwo" value="2" type="hidden">
<input name="rich.property3" value="3" type="hidden">
will bind values to an object like this
class CommandOne {
private String propertyOne;
private String popertyTwo;
private CommandTwo rich;
// Getters and setters
}
class CommandTwo {
private String propertyThree;
// Getters and setters
}
You also have to be sure to instantiate your command object, but that will be handled in your SimpleFormController.

Spring tags are completely optional.
Read chapter 15, 16, and 17 of the Spring Reference Document You can use annotations to retrieve request parameters with your controller (see section 15.3).

As per my understanding, what you are trying to achieve is Binding your form to your Bean Class, which is very nicely implemented in JSF. JSF works on component architecture and very easy to start with, plus it has many component builers available such as primefaces, omnifaces, icefaces, openfaces, etc. Reusability of self-designed components can help you a lot in specific projects. Try giving a chance to JSF. Thanks, hope this was helpful.

Related

Check if Thymeleaf template url contains string

How can I check if this URL 'http://localhost:8080/employees/subordinates/1' contains the string 'subordinates'? I'm trying to make the presence of an anchor conditional upon the URL containing the phrase. This is what I've been hoping to achieve.
<div th:if="${#strings.contains(#httpServletRequest.requestURI, 'subordinates')}">
employee directory
</div>
Yes, the workaround you mention in the comments is the way to do it.
The #request, #response, #session, and #servletContext expression utility objects are no longer available in Thymeleaf 3.1. According to this issue:
The #request, #response, #session and #servletContext expression utility objects should be removed from the Standard Dialect, both for security reasons (in order to avoid direct access to potentially unsafe properties such as request parameters) and also due to the fact that these are currently bound to the javax.* Servlet API, and generalizing the web interfaces in the Thymeleaf core in order to support jakarta.* and other web technologies would not be compatible with these specific objects still being available.
The article Thymeleaf 3.1: What’s new and how to migrate recommends adding to your model, at the controller level, the specific pieces of information your templates need from these objects. For example, you can add the following to your controller:
#ModelAttribute("requestURI")
public String requestURI(final HttpServletRequest request) {
return request.getRequestURI();
}
And use the attribute in your template this way:
<div th:if="${#strings.contains(${requestURI}, 'subordinates')}">
employee directory
</div>

How to add a custom ContentHander for JAXB2 support in Spring 3 (MVC)?

Scenario: I have a web application that uses Spring 3 MVC. Using the powerful new annotations in Spring 3 (#Controller, #ResponseBody etc), I have written some domain objects with #XML annotations for marhalling ajax calls to web clients. Everything works great. I declared my Controller class to have a return type #ResponseBody with root XML object - the payload gets marshalled correctly and sent to Client.
The problem is that some data in the content is breaking the XML compliance. I need to wrap this with CDATA when necessary. I saw a POST here How to generate CDATA block using JAXB? that recommends using a custom Content Handler. Ok, fantastic!
public class CDataContentHandler extends (SAXHandler|XMLSerializer|Other...) {
// see http://www.w3.org/TR/xml/#syntax
private static final Pattern XML_CHARS = Pattern.compile("[<>&]");
public void characters(char[] ch, int start, int length) throws SAXException {
boolean useCData = XML_CHARS.matcher(new String(c,start,length)).find();
if (useCData) super.startCDATA();
super.characters(ch, start, length);
if (useCData) super.endCDATA();
}
}
Using Spring MVC 3, how do I achieve this? Everything was "auto-magically" done for me with regards to the JAXB aspects of setup, Spring read the return type of the method, saw the annotations of the return type and picked up JAXB2 off the classpath to do the marshalling (Object to XML conversion). So where on earth is the "hook" that permits a user to register a custom Content Handler to the config?
Using EclipseLink JAXB implementation it is as easy as adding #XmlCDATA to the Object attribute concerned. Is there some smart way Spring can help out here / abstract this problem away into a minor configuration detail?
I know Spring isn't tied to any particular implementation but for the sake of this question, please can we assume I am using whatever the default implementation is. I tried the Docs here http://static.springsource.org/spring-ws/site/reference/html/oxm.html but it barely helped at all with this question from what I could understand.
Thanks all for any replies, be really appreciated.
Update:
Thanks for the suggested answer below Akshay. It was sufficient to put me on right tracks. Investigating further, I see there is a bit of history with this one between Spring version 3.05 and 3.2. In Spring 3.05 it used to be quite difficult to register a custom MessageConverter (this is really the goal here).
This conversation pretty much explains the thinking behind the development changes requested:
https://jira.springsource.org/browse/SPR-7504
Here is a link to the typically required class override to build a cusom solution:
http://static.springsource.org/spring/docs/3.1.0.M1/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter.html
And the following Question on stack overflow is very similar to what I was asking for (except the #ResponseBody discussion relates to JSON and jackson) - the goal is basically the same.
Spring 3.2 and Jackson 2: add custom object mapper
So it looks like usage of , and overriding MarshallingHttpMessageConverter is needed, registering to AnnotationMethodHandlerAdapter. There is a recommended solution in link above to also get clever with this stuff and wrap the whole thing behind a custom defined Annotation.
I haven't yet developed a working solution but since I asked the questions, wanted to at least post something that may help others with the same sort of question, to get started. With all due respect, although this has all improved in Spring 3.2, it's still bit of a dogs dinner to get a little customization working... I really was expecting a one liner config change etc.
Rather than twist and bend Spring, perhaps the easiest answer for my particular issue is just to change JAXB2 implementation and use something like Eclipse Link JAXB that can do this out of the box.
Basically you need to create a custom HttpMessageConverter. Instead of relying on the Jaxb2RootElementHttpMessageConverter that spring uses by default.
Unfortunately, customizing one converter means you are telling spring that you will take care of loading all the converters you need! Which is fairly involved and can get complicated, based on whether you use annotations, component scanning, Spring 3.1 or earlier, etc.. The issue of how to add a custom converter is addressed here: Custom HttpMessageConverter with #ResponseBody to do Json things
In your custom message converter you are free to use any custom JAXB2 content handlers.
Another, simpler approach to solve your original problem would be to use a custom XmlJavaTypeAdapter. Create a custom implementation of javax.xml.bind.annotation.adapters.XmlAdapter to handle CDATA, in the marshal method wrap the return value with the cdata braces. Then in your mapped pojo, use the XmlAdapter annotation, pass it the class of your custom adapter and you should be done.
I have not myself implemented the adapter approach, so couldn't provide sample code. But it should work, and won't be a lot of work.
Hope this helps.

Apply Spring formatter to non-form text in JSP

In Spring MVC 3, I have a customer Formatter that converts my entity objects to text and parses the text for my entity objects. It's registered with the conversionService bean. This link shows how it works: http://springinpractice.com/2012/01/07/making-formselect-work-nicely-using-spring-3-formatters/
I'm wondering if there's any way to apply the formatter to text not inside of forms. Specifically, I'd like my object displays to have a web link to their foreign key entities with the same text that's used in the forms. I've gotten the forms to display successfully, but I haven't been able to apply it to the text on the JSP page. Instead, it uses toString.
I've played around with <spring:bind>, <spring:message>, and <spring:eval>, but they don't seem to apply to the formatter. <spring:eval> attempts to use the DateTimeFormatter.
Hopefully, this helps someone else looking for this. It turns out it was <spring:eval>, which makes sense, since somehow it has to be linked to Spring. The issue was syntactical. The statement below causes the entity to be processed by a Spring converter.
<spring:eval expression="myEntityObject" htmlEscape="false"/>
No JSP tags are needed, like: ${ok}
This uses the Spring expression language.

Spring MVC Front End Validations

I wanted to validate user inputs in my jsp which were binded to Springformdata objects using <spring:bind> without hitting the controller.
Is there any other way I can achive this in spring MVC without using javascrpit.
See below code
<tr><td>
<spring:bind path="applyDmlFormData.file">
Select DML File : <input type="file" name="file"/>
</spring:bind>
</td></tr>
Here I am asking user to browse/select the input file and then attaching that to applyDmlFormData objects' file property.
If user don't selects any file and submits the form I wanted to validate that in the forntend itself without hitting the controller and display a error message saying file must me choosen. Basically I wanted to achieve the same functionality which is available in struts validation framework.
One more thing to add is I dont want to use validator which will be invoked by controller
#RequestMapping(value="/applyDml.htm", method = RequestMethod.POST)
public String process(#ModelAttribute("applyDmlFormData") ApplyDmlFormData applyDmlFormData, BindingResult result, SessionStatus status, HttpServletRequest request)
{
String mav = applyDmls;
validator.validate(applyDmlFormData, result);
if(!result.hasErrors())
{ //Business logic goes here
}
}
In the above code I am validating user inputs using validator.validate I dont want to do that.
The Struts Validator framework generates client-side JavaScript; AFAIK, Spring MVC doesn't offer a similar functionality. You need to roll your own client-side validation code. Even if you include Spring JS in your application, you still need to write your own validation code; here's an example.
Note that you don't need to use use a Validator object in your handler methods. You can also annotate your #ModelAttribute with #Valid and use JSR-303 annotations. See http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#validation-beanvalidation-overview for details.
You can explore the Rhino library..find the spring integration api here

Is it possible to set a domain object as a hidden field in spring forum bean?

greetings all
i have a domain class named car
and i have an object from car retrieved from the DB
and i want to save this object in the form as a hidden field
in order when submitting to get this object
but when i tried
<form:hidden path=carObj />
it didn't work, any ideas why, and how to do such behaviour ?
Well carObj is a java object, and an HTML hidden field can only hold text, so how would Spring store one inside the other? If you want to use hidden fields, you're going to have to break down the object into individual fields.
It sounds like what you need is to tell Spring to store carObj in the session, so that's visible when the form is posted. You can use the #SessionAttributes annotation for this (see docs).
Spring's form tag library does indeed support hidden fields as you described.
See the Spring Reference for more information.

Resources