Spring MVC annotation preload form - model-view-controller

I am a newbie to spring mvc annotations. Which is the best way to load data into a page that has say a string, list (list of country for a drop down) and some form elements like name and address
I see two possible ways
#ModelAttribute on a method - can be used for string, list, initialize the form elements
Put the string, list into ModelAndView in the RequestMethod.GET method
Can anyone shed light on the pros and cons.
Also can some one give a brief example on how to load reference data and form data. What goes inside a form backing object (just the form elements like an address object or the reference data also)

I prefer to create a method which returns, for example, a collection of Strings. I annotate this method with #ModelAttribute, and then the data is always available to all of my vies.
You can manually inject into the model as you described, which is sometimes more appropriate (when you only need model attributes in very specific cases). Often you'll want certain model attributes for multiple views, so it's easier to use a #ModelAttribute-annotated method.
Here is a simple example I wrote on barebones Spring MVC which might help you get started.

Related

Spring best practice to separate model from view in controller and jsp?

Is it a good practice to use Spring Controller class(with #ModelAttribute) and the jsp to prepare model at the same time or the model has to be prepared only by Spring and the view from the jsp?
The idea comes from this topic . I have a Controller class:
#RequestMapping(value = {"", "/"}, method = RequestMethod.GET, params = "mode=create")
public ModelAndView showCreatePage(#ModelAttribute("createForm") ApplicationCreateForm form)
{
return customMethod("some string");
}
and in my jsp I have:
<jsp:useBean id="createForm" scope="request" class="com.example.ApplicationCreateForm"/>
I do not need to populate the form with the information to be present to the user all fields are empty.
So from what I uderstand I have been declared ApplicationCreateForm bean twice, with the same scope - request.
Is it a good design practice to use both at the same time? Is there a reason for that? Does the second declaration(in jsp) give me more power, for example to override the model or it is complete unnecessary? Does the second declaration overrides the first one when both are present?
There are many things wrong with this implementation.
Is it MVC?
If JSP know about Model, why do we need controller. Lets remove the routing engine and use JSP directly to consume Model. But then the application will be monolithic. I believe you do not want that. We have two major flavours of MVC. In both, controller is the front facing object. It receives the command, interprets it, works with data layer and gets Model. If required the Model gets converted into a viewModel and then this object is passed to the view.
Why viewModel?
Say we are implementing paging on screen. We are showing list of persons. Person is your model here but your view also need to know page number, page size etc. Your model thus may not fit directly in this case.
Say we need data from multiple tables to shown on screen. This data is related in some way. Now will you pass separate model objects to view and let it do all the business logic? Ideally no.
Should not the design support DTO or ViewModel or Commands and Queries?
We want our application to be designed properly. As stated above we need to send data to view or clients (REST) after processing. Processed data may not map to you domain until unless we are just creating a CRUD stuff. What if you want to implement CQS or CQRS?
Where is separation, where is SOLID?
If my view is performing business logic then where is 'S'? If view knows about model and need to be changed in slightest of changes in model then where is 'O'?What if I want to separate queries from command (CQS) and scale the two things separately?
To conclude I would say, yes you can do this but it is not good if you are developing a decent size application or you think it will eventually be one. I have seen people using model entities starting from ORM, to controller to view. It will work but the question is do you want a monolithic and tightly coupled application. As per my experience the presentation logic (view) has very different logic and need of data in comparison of controller and same goes for your data access layer.
I think you should prepare your model fully in spring controller. Then view should be as passive as possible, ie. only showing model attributes received from controller while having no further knowledge about application logic. This approach gives you clean separation of concerns and you view is as independent as possible and can be easily switched for different view technology - eg. thymeleaf or freemarker templates. The whole idea of MVC is to separate presentation layer and by leaking business logic to view you create unnecessary dependencies.
Your view should be as simple as possible, as the logic leaked to view makes it very hard to test and reuse. On the other hand, if your logic is nicely separated, you can test it easily and reuse it easily. Ideally, business logic should be completly independent on web environment.
By defining you are creating tight coupling between your view and class com.example.ApplicationCreateForm, using spring mvc you achive loose coupling between your controllers, view and model it might happen that you change you model name but you still have same properties in it which might be enough for view, in above case you will need to update your view but it won't be required in case you are using Spring MVC.
Since spring comes with the concept of making things loosely coupled to make your code more testable, you should always keep in mind that separation of concern is your priority. So it is always the best practice to prepare your model fully in Controller, not in views.
Keep thing simple , make your controller responsible for preparing your model, and keep your views to display the model only.
So, a big NO to your question. The second declaration isn't going to make you powerful, rather help you to be tied up.

Problems with Spring Forms and Validation

I am newer to Spring, previously I've worked in PHP and Python. I am having some issues understanding how Spring forms work and are validated. My understanding thus far is that when you are using the your form is backed by a bean, meaning you must provide a bean to the JSP. You can also use the stand HTML forms but then you have to manually retrieve the request parameters in the controller.
Here is the issue I am having. I have a User bean that is using Hibernate Validator, and I have add, edit pages for users. The issue is I don't want the password field to appear on the Edit page, the password is going to be garbage anyway because its using BCrypt. However when the form is submitted validation fails because it expects the password to be present. There doesn't seem to be anyway to do partial bean implementation using Spring Form.
I would like to use Spring Form if possible because it reduces repetitive validation code, and its always nice to work with objects. My thoughts now are do I create an intermediate object and then translate the data from that to my bean. Seems tedious and can lead to the creation of way to many objects. My other thought is to just using plain old HTML forms and pull the params myself and set the values in the object.
I'm not sure what is the best approach or if I'm even thinking on the right track. Spring Forms and the validation is offers seems great, but seems like it isn't particularly flexible. Like I said I'm new to Spring so I may just be missing something or not understanding.
Another issue I have been wrestling with is having multiple objects needed on a form. Lets say I have a User bean, which has the following Properties.
private Role role;
private Country country;
So I need to pass User, List, and List to my JSP. I can get them to display fine, however if the form validation fails when it returns to that page, I lose my role and country objects, unless I re-add them to the model before returning the view name. Am I missing something here or is that the norm. It's a request object so I guess that makes sense but seems tedious to have to re-add them every time.
My understanding thus far is that when you are using the your form is
backed by a bean, meaning you must provide a bean to the JSP.
I'd say mostly true. The form is backed by a bean, but the Spring JSTL tags know how to get to the bean based on the set modelAttribute. The bean is living in what you would consider "page" scope, unless you add set your model attribute to be in session. Either way, if you are using the Spring JSTL tags, they are going to one or the other place to get it.
You can also use the stand HTML forms but then you have to manually
retrieve the request parameters in the controller.
Not true. You can "simulate" the same thing that the Spring JSTL tags are doing. Understand that JSTL tags are very much like macros. They are simply copying in some pre-determined block of code into the output with some very rudimentary conditional statements. The key bit that Spring MVC needs to wire the Model Attribute on the Controller side is the name and value, which are easy to decipher how those get generated/wired together.
However when the form is submitted validation fails because it expects
the password to be present.
You could create a "DTO" or "Data Transmission Object", which is basically a go-between to take the values from the UI and are converted in the Controller/Service layer to the real Model objects on the backend. Or, if you are lazy like me, put the User in session scope, in which case you don't have to post the value as Spring will take the one out of session and just updated the one or two fields you did post. Don't post the password, Spring wont set the password.
My thoughts now are do I create an intermediate object and then
translate the data from that to my bean.
Yes, this is the DTO I referred to. You only need to do it where you need to.
I'm not sure what is the best approach or if I'm even thinking on the
right track.
There are probably thousands of ways to do anything in coding, some more right or wrong than others. I know some developers who are design-Nazi's and would say you should always do it one way or another, but I am not one of those people. I think as long as you are consistent, and you are not doing something completely boneheaded you are on the right track. My #1 concern with all the code I write is maintainability. I
Don't want to spend 20hrs trying to re-learn what I did 6mo ago, so I tend to choose the simpler option
Hate repeating code, so I tend to choose more module designs
Hate having to spend 20hrs trying to re-learn what I did 6mo ago, so tend to make heavy use of JavaDoc and comments where I find the code is tricky (lots of loops, doing something weird, etc)
Another issue I have been wrestling with is having multiple objects
needed on a form.
There are several ways to deal with this too. I have never used it, but you CAN actually have more than one Model Attribute associated with the same form and Controller handler. I think you use a <spring:bind> tag or something. I have seen samples around, so Google it if you think you need that.
My approach is usually to either put something in session or build a DTO to hold all the things I need. The first I use more for things like lists to drive building the view, for instance if I have a drop down of States coming from a table. I would have a List of the States put into session and just use them from there, that way I only go after them once and done.
I use the DTO approach (some might call it a Form Bean) when I have a complex gaggle of things I need to change all at once, but the things are not necessarily connected directly. Just to point out: You can have nested objects in your model attributes and use them in your Spring JSTL tags. You can also have Collections (List, Set, Map) in your Model Attribute and get to those as well, although Spring doesn't handle nested Collections very well.
Hope that helps.

How to architect bean retrieval from DAO vs. User Entered Data bean

I am a total newb to Spring. Even though I understand the concepts of individual annotations (and dependency injection), I am having difficulty "seeing the forest for the trees." Here, in this example, I have a page that has a dropdown box. It also stores the user's selected option from that box. So there are three beans, only one of which is properly called a domain bean:
DropDownEntry *domain
SelectedOption (which could be String or a whole DropDownEntry type stored at Session Scope)
PageModel (containing a List of #1 above, and a single instance of #2)
Below is an image of my best guess as how to use Spring to:
1. Retrieve a List from the persistence layer via DAO
2. Retrieve/Store the user's selection
Is this design remotely near correct? Is there an alternate "best practices" way to architect this scenario?
I think Spring MVC Forms might be what you are looking for.
http://www.javacodegeeks.com/2013/07/spring-mvc-form-handling-vol-5-select-option-options-tags.html
Model
The model is a map of entries for the drop down box.
Controller
You can fetch these entries from a database using the DAO Pattern and turn it into a map in a controller class.
View
The drop down box is generated using a mix of HTML, a JSP tags and map of 'drop-down' entries.
Hard to tell. But from the looks of it, you've made things awfully complicated.
My advice: stop drawing UML, re-read the specification, and start coding. Start with a simple model class that represents the selectable entity. Don't name it DropDownEntry (unless you're creating software to model dropdowns), but something that actually describes the selectable entity. Don't worry about data access (DAOs) at this point.
Then create a controller class that allows you to render a view that contains the said dropdown UI element. Then pass the selectable entities (as reference data) to the view in the model. Then make the view render the selectable entities appropriately. Then allow the user to post the selection back to your controller.
Once you have this, you can think about saving the selected entity to persistent storage. At that point you will probably find out that you need to link the selected entity to a user etc.
Good luck.

spring - difference between request.setAttribute and model.addAttribute?

can any one tell me the difference between request.setAttribute and model.addAttribute in spring web app?
The difference is, that Model is an abstraction. You could use Spring with servlets, portlets or other frontend technologies and Model attributes will always be available in your respective views.
HttpServletRequest on the other hand is an object specific for Servlets. Spring will also make request attributes available in your views, just like model attributes, so from a user perspective there is not much difference.
Another aspect is that models are more lightweight and more convenient to work with (e.g iterating over all attributes in a model map is easier than in a request).
Request V/s Model
where request could get attributes through getAttribute("") method. normally it is used for getting information from defined attributes and used inside the method for performing the different operations. So Basically Request used for input.
Just like Request, the model provides addAttribute("","") method, Through this model, we could make the object and storing data inside model object and deploying it on result Server Page.Basically it used in storing input data which is provide by us and storing for some time.

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.

Resources