Get hold of Spring model from everywhere - java

In a controller I can get model by declaring Model/ModelMap typed parameter. In handler interceptors and in view rendering I get the same. But how do I get the model from the arbitrary class, which can get hold of ApplicationContext or web request? I just don't want to use model.addAttribute() all the time and would like my service automatically put objects into model.

The idea is that you shouldn't. Your controllers are the entry point of your application, so you get them there, and pass them as arguments to the layers below.

Related

Difference b/w passing model and using request object at jsp/gsp

I have been working both on spring and grails (grails is built on spring).
We can pass our data from controller to view (jsp/gsp) via request object or via model.
Passing data via model is preferred because its easy.
Comparison of code :
Spring :
controller request.setAttribute("name","india");
view ${pageContext.request.getAttribute('name')}
controller ModelAndView("viewname",modelObject)
Grails
controller request.setAttribute("name","india")
view ${request.getAttribute("name")}
controller render(view:"viewName",model:[name:"india"])
I think request object does many functionalities other than this.
So my question is : If passing data from controller to view can be done with request object itself why java technology required to make a concept like model ?
necessity is mother of invention
I mean to say that there must be a task that can be implemented only via a model.
A few things come to mind, but they are speculation as to why.
Mainly, separation of concerns. Modifying the request, which is input, to hold output seems to be abusing this. The model is clearly ouput, and only output.
By clearly defining what constitutes output, using a model, frameworks such as Spring and Grails can then apply other processes to only the model. Grails filters come to mind, as an example.
That's my quick opinion.
That data which a controller gathers up and needs to make available to the view should be put in the model. That is kind of the definition of what the model is in this context. Never use request attributes for this.

Specific configurations for different items using same table

So we have an ITEM, TV, LCD and PROJECTOR.
We have DAO and Service object for TV, LCD and PROJECTOR that also are ITEM objects. Meaning that those tables all extends the ITEM table.
You can access these items through an UI and an API service.
Right now, I am in the need to put specific UI configurations that are not related at all with the API. Lets say that I need in the UI a configuration for each item to display or not display an image of the item on it, lets call it showImageFlag. This value can be modified from the Item's UI, this is a checkbox.
I've been thinking about a few options here:
Add a column SHOW_IMAGE_FLAG to the ITEM table and it's DAO and service object. On the service object put a #JSonIgnore flag so it is ignored on the API side, but we can use it normally in the UI. ------- My concern with this approach is that in the future we might need more configuration for these items or maybe others than tv, lcd and projector. So this will always will push us to add a new column to the table. Another concern is that we might be migrating all form post ui to use the REST API, so we are going to have to do something about that JsonIgnored property.
A ITEM_CONFIG (id, item_id, configuration, value) table FKed to the ITEM.id with a key/value approach to save N configuration related to specific items. So on every web controller I will be passing a ItemConfig object with all configurations related to the requested ITEM. -------- My concern with this one, is how should I map this to the form (using spring mvc) and how should I persist when the configuration changes on the UI.
Please free to comment and suggest any new option for this.
Second point is more feasible.
Also,you can have another service layer which will be responsible for saving mapping part and below service layer there will be UI controller layer which will actually map the changes to its undergoing presentation i.e. UI layer.
I would think about adding Item(id)--ItemUI(item_id) as 1:1.
Then you can add all your UI specific about an item to the ItemUI attributes.
Also you could request UI configuration with a second call to another service.
From the two options I'll go for number one. The only problem that comes up is when the UI is migrated to use the API. In that case you won't be using #JsonIgnore, instead you will be using Json Views.
You can create classes representing specific views on your data and use them to tag your attributes with #JsonView(MyView.class). Finally, you can serialize your beans using objectMapper.writeValueUsingView(out, beanInstance, MyView.class);
In your case you could create an view class MyAPIView and annotate all fields but SHOW_IMAGE_FLAG with #JsonView(MyAPIView.class) (Note MyAPIView is an empty class used for tagging purposes, with no logic nor attributes).
If you call objectMapper.writeValueUsingView(out, beanInstance, MyAPIView.class); you wont serialize the SHOW_IMAGE_FLAG attribute. If you call objectMapper.writeValue(out, beanInstance) you will serialize the attribute.
You must determine at runtime the view to be used. If you are using OAuth you could select view depending on the connected client.
Eventually, you can create several views and apply inheritance. Take a look at jacksons doc.
I ended up with a config table for items called ITEM_CONFIG (ITEM_ID, UI_PROPERTIES)
On the UI_Properties I save a JSON string, which is mapped to a String propertie on the DAO model, but as a HashMap<String, Object> on the service model.
I have a converter that maps the value from the dao model to the hasmap on the service object, "automatically".
On the controller (in the BaseController, parent of every WebController [not rest]), I added a method to get the config from the ItemConfigService and then set the value on the response (Model in SpringMVC) using the hasmap key as the parameter and the value as the parameter value.
This is working very clean and we haven't had any issues since last week.

Need information about spring Controllers

I am very confused about spring controllers,
pls help me.
i want to know that how spring controller initate and how its constructor get into action,
as when i call a controller from one page, and then ask the same controller from another page it dosn't seems to create a new object of that controller rather than provide same reference of the controller object
Controllers are "application-scoped"; they are instantiated just once and then reused for all requests you associate them with. As such, it is important that they do not carry session-specific state.
You should refer to the documentation for more details on how controllers work and how to instantiate them.

Load objects before action, and share those objects in action and freemaker modules, possible?

Say a logged in user hits the url:
www.example.com/forum/234
Before the spring mvc action fires, I want to load the User Object, the user's permission, the Forum object.
Now I want to share these objects accross this request. So other classes can look to see, in the current request, for a User, Permission and Forum object.
Potentially it would be cool if a custom freemarker module could also reference these objects if they are available.
is this possible?
First, consider using spring-security, whose filters do everything you need.
If you want to do all by hand, then you have at least two options:
- use servlet filters
- use spring handler interceptor (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor).
In both cases store this data in request attributes.
Another option is to create bean with request scope which will store your data.
As for Freemarker, you must provide own subclass of FreemarkerViewResolver, which will return subclass of FreeMarkerView in requiredViewClass() method. Add your objects in exposeHelpers() method in this FreeMarkerView subclass.

How to display the same data on all pages in Spring Framework 3.0?

I have some text data from database that I want to display it on all pages on my site. (for example news block etc.) How can I load and pass it to View in Spring Framework 3.0?
I don't want to create some method, which will retrieve data, and call it from each controller...
Use a HandlerInterceptor, which is built for this purpose - you can specify a piece of logic to execute before or after the execution of your controllers (or a list of controllers - it is up to you to map an interceptor to the controllers it should apply to) by implementing a preHandle() and/or postHandle() method. The latter receives the ModelAndView as an input, allowing you to add model attributes to it.
This way the logic to add some data to the model exists in just one place, can be selectively configured to apply to all or some pages, etc.

Categories