Difference between Spring MVC formatters and converters - spring

I would need some clarification regarding the difference between Spring MVC formatters and converters.
My understanding of the main difference between them is that the formatter works on data that is going to be displayed to the end user such as a date, SSN or credit card number whereas the converter works on data hidden behind form controls such as the value attribute of an select's option.
Am I right or wrong? Can someone please provide advice and/or samples in order to better explain the difference between the two.

Converters are used to convert one Java type to another Java type. For example, from Long to java.util.Date or from Integer to Color or from String to Date. It can be used in the web tier or any other tier that needs conversion service.
Formatters are used to convert String to another Java type and back. So, one type must be String. You cannot, for example, write a formatter that converts a Long to a Date. Examples of formatters are DateFormatter, for parsing String to java.util.Date and formatting a Date. In addition, formatters' messages can be localized.
Conclusion: formatters are suitable in the web environment, such as a Spring MVC application.

Converter components are used for converting one type to another type and also to provide a cleaner separation by forcing to place all such conversion related code in one single place.
Spring already supports built-in converters for the commonly used types and the framework is extensible enough for writing custom converters as well.
Spring Formatters come into picture to format the data according to the display where it is rendered. Examples may include formatting date/timestamp values according to locales etc.

Related

Best way to represent object views (summary, detail, full etc) in Spring based REST service

I am working on a REST service which uses Spring 4.x. As per a requirement I have to produce several different views out of same object. Sample URIs:
To get full details of a location service: /services/locations/{id}/?q=view:full
To get summary of a location service: /services/locations/{id}/?q=view:summary
I have thought of two solutions for such problem:
1. Create different objects for different views.
2. Create same object, but filter out the fields based on some configuration (shown below)
location_summary_fields = field1, field2
location_detail_fields = field1, field2, field3
Could someone help me to understand what could be an ideal solution? I am not aware of any standard practice followed for this kind of problems.
Thanks,
NN
In my opinion the best option is to use separate POJOs for different views. It's a lot easier to document it (for example when you use some automated tools like Swagger). Also you've to remember that your application will change after some time, and then having one common POJO could make troubles - then you'll need to add one field to one service and don't expose it through another.
See this article on how google gson uses annotations to convert a Java Object representation to a json format : http://www.javacreed.com/gson-annotations-example/
Since you want two different representations for the same object you could roll your own
toJson method as follows :
a) Annotate each field of you model with either #Summary, #Detail or #All
b) Implement a toJson() method that returns a json representation by examining the annotations for the fields and appropriately using them
If you need an XML representation same thing, except you would have a toXML().

Where to format non-standardized data into a standard format (View, Service, or DAO layer)?

I am using Spring MVC for my presentation layer, and am also using Spring for my Service and DAO layers. Normally I would format data in the View layer of MVC (in my case JSPs), but what if the data that is retrieved from the database is not in a standardized format?
For instance, I am pulling phone numbers from one of my company's databases, but they could potentially be in any format (111)-555-1234 or 1115551234, etc. This seems like it would be too much functionality and processing to place in the JSP/View layer. I would prefer to put all of the numbers in the same format somewhere else and then re-format on the View. Where should I format in this situation - Service layer? DAO?
This would also allow me to take advantage of libraries that I could not potentially call from a JSP (or that would not make sense to call from a JSP).
Thanks!
I would have the DAO query methods remove the formatting characters from the phone numbers, and have the presentation layer give them a consistent format (probably in JSP tags). I am not a fan of putting business logic in DAOs, but this seems extremely data-related.
(Actually if the formatting code first removes any pre-existing formatting before doing its own formatting, you might be able to get by without removing formatting characters anywhere else. I just like having things in a canonical form.)
As an alternative to putting the formatting-char-removal in the DAO, if you are using Hibernate then you can create custom user types that remove or insert formatting characters from the phone number attributes.
I generally do formatting, when I map the Model to Value object (VO or whatever you want to call them), mostly in the presentation layer (or i put a layer in between the presentation and service layer, If I have too many things to do). This brings consistency in the format across the application, if that is what you want.
When i want the name to be in camelcase, I do this
BeanUtils.copyProperties(userAccount, userAccountVO, ignoreProperties);
userAccountVO.setName(StringUtilities.convertToCamelCase(userAccountVO.getName()));

When to use Spring WebMVC's Views and/or MessageConverters?

I am writing an inhouse app with Spring 3.1.3 with UI for humans utilizing the VelocityView and with a REST API which serializes response entities as JSON or XML.
Now, besides the view and messageconverter thing. When would one use one of theses? I presumed that views are for humans as a general rule and messageconverters for M2M communication. Why do Views like JsonView, XmlView, etc. exist? Those outputs aren't for humans anyway.
You are essentially right - View is to convert the internal model into a "viewable" format - be it html, json, xml etc, so MappingJackJsonView, newer Marshalling View etc, if used as a view take in all the elements set in the model and transform them to xml.
MessageConverters on the other hand do things a little differently, it doesn't work on the model attributes, it works instead on the response body - transforming the response body to the appropriate format based on the ACCEPT header of the request.

Spring Formatters inside data model, is this a violation of MVC? Is there a better alternative?

Spring provides formatters (and converters) with the use of annotations. This means that a request parameter can be annotated on a controller to format user input and also a property of a data model class can be annotated to format data for a view.
The latter seems to me as a clear violation of MVC's main purpose, that is the separation between model and view. Annotating a data model class with formatting specifics binds the model to the view. If the model hast to be used for some other view or for anything else, it can't, since its fields are formatted for a specific view.
If I am wrong let me know. If not, is there a way to format fields from and to view format without violating MVC?
Using annotations is a good declarative way to specify formatting - I would not give it up. An alternative would be a procedural way of defining conversions.
As I see it, the problem is that pure model objects and form-backing objects get mixed together. If you want to "purify" your architecture, introduce form-backing objects that will be between user's input and your model. If you think that it is too complex for the scale of your project, then you don't need it. In this case, just be aware that the model object has a double meaning.

N-tier question: Where do you do the variable casting?

Our UI exposes user input as strings. All of them, including dates and numbers, are coming as strings. The question is: is it better to convert these to the appropriate type (datetime, int, etc) in the UI (and then pass converted var to the BLL methods), or in the BLL itself?
Input validation and conversion should be done on the UI layer.
Not only is this so your business layer is dealing with typed data, but also so that you can easily throw UI error messages if they enter the wrong type or if the value is outside your range*.
*Some frameworks have their own validation logic for this sort of thing... ASP.NET being the first I can think of.
UI type conversion should be done in the UI layer, not the BL layer. This decouples the UI from the BL.
I prefer to do type casting in the UI and have the BLL expect the proper datatype.

Resources