what really get cached in dispatcher in cq5? - caching

We Developed Header & Footer for our site. we created a content hierarchy and from a java service class we accessed content hierarchy and for each level there is a java bean to hold the values
For ex
LevelOneBean.java
{
string linkName; String linkUrl, List<LevelTwoBean> LeveltwoBeanList;
}
LevelTwoBean.java
{
string linkName; String linkUrl, List<LevelTwoBean> LevelthreeBeanList;
}
LevelThreeBean.java
{
string linkName; String linkUrl,
}
After that i am rendering bean in my component jsp.
when we deployed on web server, found that these two component using 70% of cpu and hence it is slow. we do have dispatcher and page should get cached in dispatcher.
My senior said since you have created java bean and java bean not get cached. and he asked to create JSON for header and footer. Json will get chached at dispatcher level.Java bean not.
My Q - I want to validate my above statement statement. Ideally page get should cached regardless of rendering design.
Please help to understand this.

Calling a bean is irrelevant here. Beans are generally called during transformation of the JCR section to HTML/CSS/JS.
If you are calling the bean during the JSP transformation phase, and then serving HTML based upon the bean results, the response should be cached.
If the browser has been served with the page, and you are making an AJAX call, a JSON or XML request is made, which can be set to cache. By default, JSON and XML are not configured to cache in a dispatcher.
The JSON call back from the dispatcher would hit the publisher, and then the JSP would call your bean to render the response. Again, it should not have anything to do with your bean.
The only thing to be careful of when you're caching, is what actions trigger to flush or clear your cache. If you are updating content, the stats file flush approach of the dispatcher works well. The danger with JSON and XML, is that you are likely to be synthesizing the response from several different source points in the tree, which if they do not match between the content and the json path, the cache is likely to not be flushed unless if you are using Dispatcher Flush for ACS commons.
https://adobe-consulting-services.github.io/acs-aem-commons/features/dispatcher-flush-rules.html
From what you have described, your bolded statement does not make sense. I would check to see what you are producing as a rendered artefact, and whether those artefacts are being cached/flushed.

Related

Does ModelAndView serialize model before sending response to client

In spring mvc, when we return ModelAndView / Model object, does this get serialized to be sent on HTTP?
Just like it happens in REST API that the #ResponseBody annotated method returned value is serialized.
If not, how is Model object transferred over HTTP in Spring MVC as I have read that objects can't be transferred over HTTP without serialization?
It depends. It depends on the view technology in use. But for most they will be exposed as request attributes and that is done in the View. The AbstractView has code for this which is used by most View implementations.
For something like Freemarker the model is exposed both as request attributes but also added to the Freemarker internal model object. This is so that Freemarker can render the page and you could also use tags in the template to retrieve the request attributes.
Depending on the actual view technology used if something gets serialized depends. For things generating HTML, PDF, Excel etc. nothing will be serialized. All the rendering and processing is done on the server and the end result (the complete view) is being sent to the client.
However, for view technologies like the MappingJackson2JsonView (there are others as well) that will actually serialize the model using Jackson. But in the end, this will be JSON that is sent over HTTP.
So what is sent over HTTP is at least never the actual model but depends on the view technology in use.

Set JSP list box contents from DB on every request

I have a single JSP that serves multiple methods in a Controller -- it is the result of Add, Edit, Delete, etc. It may even serve multiple Controllers, so it's used in a lot of places.
This JSP always has a List Box displaying a set of records. So I need to re-fetch the list on every request every time this JSP is displayed.
On the one hand, I can do request.setAttribute("contents",
service.getForms()) and then retrieve this Req. Attr., but this has
to be done on every method that uses the JSP. There may be dozens,
and it's redundant.
Can't use a Session object, the list may change depending some
Add/Delete operations, so it needs to be re-fetched.
I was thinking of scriptlets: in this case, although generally
ill-advised, there's a single JSP, so the List Box can be populated
on the JSP level, without worrying about controllers. But
unfortunately I can't do this:
<% service.getForms(); %>
My service is auto-wired. According to this thread, I can't expose autowired objects to JSPs:
What is the cleanest way to autowire Spring Beans in a JSP?
#Autowired
#Qualifier("Myervice")
private MyService service;
What's the best way to go about it?

Deleting from JSF Datatable on a Request Scope Bean

I have a page with a dataTable, which is populated based on the query parameters (e.g., username and pagenum). Each entry in the table has a delete commandButton
When the pagenum != 0 and we click delete, the list of records to display is generated during the "apply" phase. During this phase the view parameters have not been set, so the list of records is empty so nothing get's deleted (our delete method doesn't get called)
To work around this I've added a #PostConstruct method that retrieves the query parameters from the Servlet request and sets the values in the bean, so they are available when we get the list of away records, which allows my delete method to be called.
I'm certain that JSF has a better way of handling this scenario and the #PostConstruct work around is a hack.
What is the correct way to implement this scenario, without resorting to a View or Session scoped bean?
Surely there must be a way to just POST the form and delete the appropriate record without having to waste time regenerating the list of records.
What is the correct way to implement this scenario, without resorting to a View or Session scoped bean? Surely there must be a way to just POST the form and delete the appropriate record without having to waste time regenerating the list of records
Sorry, there's no way. At least not when using a standard <h:commandButton> inside a standard <h:dataTable>. This is the consequence of the stateful nature of JSF. JSF just wants to ensure that the view is exactly the same during processing the postback as it was during generating the HTML output.
This is part of JSF's safeguard against tampered requests wherein the enduser/hacker can manipulate the request parameters in such way that it could do hazardful things, e.g. changing the ID of entry to delete, or bypassing the check on rendered attribute, etc. All those things on which you would/should do additional pre-validation anyway if JSF didn't do that for you and are easily overlooked by starters (they would then blame JSF for being insecure instead of themselves). See also Why JSF saves the state of UI components on server? and commandButton/commandLink/ajax action/listener method not invoked or input value not updated.
In case of <h:commandButton> inside <h:dataTable>, JSF simply needs to have the data model available during the apply request values phase, so that it can iterate over the <h:dataTable> in the component tree in order to find the pressed button and queue the action event. If there's no datamodel, then it can't find the pressed button and the action event won't be queued. Normally, this is to be solved by placing the managed bean in the JSF view scope. See also How to choose the right bean scope?
In case of request scoped beans, the <f:viewParam> is indeed not the right tool for the job of preserving the data model before apply request values phase takes place. You need to do the job in a #PostConstruct annotated method instead. The request parameters can in case of JSF managed beans be injected via #ManagedProperty. See also ViewParam vs #ManagedProperty(value = "#{param.id}"). In case of CDI or Spring managed beans, there's no standard annotation available to inject a HTTP request parameter as a bean property. For CDI, the JSF utility library OmniFaces has a #Param for the very purpose. See also OmniFaces #Param showcase. For Spring, you'd need to homegrow it yourself. I, as non-Spring-user have however no idea how to do that. Google also doesn't seem to reveal much.
Alternatively, you can also just put the bean in the view scope by #ViewScoped. It'll then live as long as you postback to the same view. JSF 2.2 has a CDI compatible annotation for that in javax.faces.view package. The one in javax.faces.bean package is the old JSF 2.0/2.1 annotation for #ManagedBean. Spring has no annotation out the box for this as that would otherwise put a dependency on JSF API. You'd need to homegrow it yourself. Google shows several examples.
What is the correct way to implement this scenario
Before executing the any logic on the backing bean, JSF always have to rebuild the view in order to get information about what to execute. For displaying and updating purpose, the best (and correct) solution is certainly the #ViewScoped.
without resorting to a View or Session scoped bean?
If you insist on using #RequestScoped, I'd say there're no correct ways but work-arounds or hacks. One way is to initialise the list in a #PostConstruct method like you've mentioned. Another way may be to use a JavaScript function for the onclick attribute of your delete button. The JS function, for example, will make a call to the server using a URL to request a delete. Or else, you can also use PrimeFace's RemoteCommand for the JS function.

Application-wide process in SpringMVC

Suppose I have a certain operation that should be available to every process running in Spring MVC.
Say string normalization--
i need to run a method that normalizes the string fields before doing anything else on that form/data.
One thing specific to do is, to normalize the String fields on every input form before
they are dispatched to the back-end services. Likewise, that operation (normalization)
should be run on data from the back-end before it is dispatched to the view component.
One way of doing this that I can think of is:
Code a bean doing it-- the normalization. Then, define this bean somewhere at the top in
the context hierarchy of Spring-- ApplicationContext.xml or WebApplicationContext.xml(?),
so that it will be visible and can be used
accross all the processes/servlets in the application.
Then, Whenever and from wherever needed, invoke that method on the bean defined up there.
Or, inject it to the relevant fields in the bean definitions(?)
In this case, is there a way to call it before or during a HandlerMapping is running? if so, how?
Another i can come up with is:
Code a validator (implement Validator) to run that process and "validate" the String fields for you.
But i dont see how this would be of good help.
From what i know, a validator runs on specific object types. I can define that type generically(?)
but then I'm operating on the fields-- not objects as a whole each.
Coding validator(s) seems too costly to me for this use-- even if it is an option here.
I'm new to Spring. pls bear with me on this.

Displaying Data Table And Submiting Form In One Page Struts

I'm new in Struts, currently I'm using struts 1.3 to build simple Contact application
I want to display data table contains contact list from the database, in the same page I want to create a form for creating new contact and then insert it to database.
I'm using Spring bean and hibernate to do database operation and logic. So here is my flow, my action class will call spring bean, and the spring bean will call dao classes for database operation do some logic, then my action class will put the list into request object named contactList, then in jsp file I'm iterate it using logicLiterate tag.
Displaying the table and submiting all works fine, but when I do validating in ActionForm, and I want to display the error message, I have an error 500. This is because the jsp cannot find attribute named contactList in the request object, because if there is an error in ActionForm classes, Struts not calling the method at my Action class that will read the database and put it into the request object. I can try calling the spring bean in my ActionForm, but I'm afraid it not appropriate, because if there is no error then I will call the spring bean twice for the same work. What do you suggest me to do?
My bad not to read the doc carefully, now i understand that action tag in struts-config.xml have "input" attribute, this attribute specifies the physical page to which the request has to be forwarded if there is an error.
In my case, i just have to specified the input attribute to current path (eg. /contacts.do, etc) so the Action class can do its Action method.
Please note that, this request is forward requuest, not redirect.

Resources