Overriding Sling DefaultGetServlet.java - java

I'm working on a servlet to perform some logic specific to a resourceType in sling and set information to the request to be accessible via the jsp then handing off the request to the jsp similarly to the first solution provided in this answer.
Here's some example code to represent my situation:
#SlingServlet(
resourceTypes="myapp/components/mycomponent",
methods="GET",
extensions={"html"}
)
...
#Reference
private ServletResolver serlvetResolver;
protected void doGet(....) {
setPropertiesToRequest();
Servlet servlet = servletResolver.resolveServlet(resource, "....jsp");
servlet.service(slingRequest, slingResponse);
clearPropertiesFromRequest();
}
Because of this, I've noticed that I've lost sling's selector handling (I've had to roll my own simpler version to determine which jsp to render. Full featured sling selector handling is described in more detail here). I wanted to reach out to the stack overflow community and ask what else I may be missing out on by depriving the default get handler of the request. I've scanned through the source code but I think there may be more going on.
Secondly, I'd be interested in thoughts on how and where this approach may impact performance of the request resolution.
Thanks, Thomas

Processing the business logic in Java and delegating to scripts for rendering sounds like a job for the recently released Sling Models. Using that should remove the need to implement your own handling of selectors, as those won't affect the model selection, only the rendering scripts.

Not sure what you are trying to achieve here, but the main problem seems to me that your SlingServlet handles the html extension and by itself does not have selectors to filter a bit more. Thus it of course intercepts all the requests to your component. Then you have to take care of the selectors again to be able to choose the correct JSP.
The question is, why do you use a SlingServlet for it when you anyway do the rendering by JSP?
Can't you implement your logic in the JSP or better in a bean referenced in the JSP?
In our company we use our custom tag that takes care of this, but there are public frameworks available from other Adobe Partner:
https://github.com/Cognifide/Slice
http://neba.io/index.html

Related

Details on how front end interacts with back end?

Consider this line of jsp code:
function clearCart(){
cartForm.action="cart_clear?method=clear";
cartForm.submit();
}
Clearly it's trying to call a method on the back end to clear the cart. My question is how does the service (Tomcat most likely, correct me if I'm wrong) which hosts this site that contains this snippet of code know how and where to find this method, how it "indexes" it with string values etc. In my java file, the clear method is defined as:
public String clear( )
{
this.request = ServletActionContext.getRequest();
this.session = this.request.getSession();
logger.info("Cart is clearing...");
Cart cart = ( Cart ) this.session.getAttribute(Constants.SESSION_CART );
cart.clear();
for( Long id : cart.getCartItems().keySet() )
{
Item it = cart.getCartItems().get(id);
System.out.println( it.getProduct().getName() + " " + it.getNumber()
);
}
return "cart";
}
By which module/what mechanism does Tomcat know how to locate precisely that method? By copycatting online tutorials and textbooks I know how to write these codes, but I want to get a bit closer to the bottom of it all, or at least something very basic.
Here's my educated (or not so much) guess: Since I'm basing my entire project on struts, hibernate and spring, I've inadvertently/invariably configured the build path and dependencies in such ways that when I hit the "compile" button, all the "associating" and "navigating" are done by these framework, in other words, as long as I correctly configured the project and got spring etc. "involved" (sorry I can't think of that technical jargon that's on the tip of my tongue), and as long as I inherit a class or implement an interface, when compiling, the compiler will expose these java methods to the jsp script - it's part the work done by compiler, part the work done by the people who composed spring framework. Or, using a really bad analogy, consider a C++ project whereby you use a 3rd party library which came in compiled binary form, all you have to do is to do the right inclusion (.h/.hpp file) and call the right function and you'll get the function during run time when calling those functions - note that this really is a really bad analogy.
Is that how it is done or am I overthinking it? For example it's all handled by Tomcat?
Sorry for all the verbosity. Things get lengthy when you need to express slightly more complicated and nuanced ideas. Also - please go deep and go low-level don't go too deep, by that I mean you are free to lecture on how hibernate and spring etc. work, how its code is being run on a server, but try not to touch the java virtue machine, byte code and C++ pointers etc. unless of course, it is helpful.
Thanks in advance!
Tomcat doesn't do much except obey the Servlet specification. Spring tells Tomcat that all requests to http://myserver.com/ should be directed to Spring's DispatcherServlet, which is the main entry point.
Then it's up to Spring to further direct those requests to the code that handles them. There are different strategies for mapping a specific URL to the code that handles the request, but it's not set in stone and you could easily create your own strategy that would allow you to use whatever kind of URLs you want. For a simple (and stupid) example you could have http://myserver.com/1 that would execute the first method in a single massive handler class, http://myserver.com/2 would execute the second, etc.
The example is with Spring, but it's the same general idea with other frameworks. You have a mapper that maps an URL to the handler code.
These days it's all hidden under layers of abstraction so you don't have to care about the specifics of the mapping and can develop quickly and concentrate on the business code.

Best practice for URLs in Java template engines

I used a couple of Java template engine (Mustache, Freemarker) and I always struggle on how to deal with the same problem.
Assume you have a template with a piece of code like:
<a href="/{{article.name}}/{{article.color}}/home.html">
where article is an object passed from a controller to the template engine, for instance.
Then, I always see the same problems. I have to hardcode the url in several pages, if I change it then I have to look at it manually everywhere. E.g., if I want to change the URI like this:
<a href="article/{{article.name}}/{{article.color}}">
Then I have to change it everywhere.
Yeah, maybe I can define each url in something that is enabled by specific template engines (e.g. includes), but I'm wondering if there is a best practice.
One possible solution I was thinking about is to create the urls on the server side (e.g. in the controller) and sending them to the view.
Which are the best approaches from the point of view of re-usability, correctness and flexibility?
You said it: The best (most flexible and maintenable) practice is to produce the URLs in the controller and send them to the view: That is called HATEOAS.

Returning list using #Responsebody or return ModelAndView from spring controller which one better

First of all my language is not good and sorry for that and i am working with small organization and i am not getting coding standards or suggestions in the office .so let me know to which process uses in the well defined java projects among return List,Map and model object OR return ModelAndView from Controller in spring.Because for complex tables in the jsp's i think myself its not the better way to return json formatted List and handle them using jquery instead of that just throw a model and view and use static html components in the jsp's and populate the tables using model object.If you suggest return Collection List i need to add jackson processor jar files and having nearly 1mb size otherwise an jsp just 2kb size. Please help me to follow the correct way in what cases we generally use among one.Thanks in advance
Viswam,
The answer depends mostly on your application and the functionality you want to achieve, there is no standard solution here.
If your application is a single page application (read this wikipedia article) or you want RESTful application, I would suggest to stick with #ResponseBody, reason is simple, it supports AJAX and basically doesnt change the page from Server side.
You can easily populate any complex table using plain JavaScript or jQuery from the JSON response you receive.
Also if I were to think, I wouldn't want to waste my resources at server side for populating data in JSP and then send it over to client(browser) when it can do this by itself. But this is strictly a personal choice/preference.
And, If you need to redirect to or reload a page, I believe ModelAndView is the way to go.
Suggestion : You can check the Spring Code from various tutorials and projects on GitHub or similar platforms/blogs to learn how to keep your code clean and readable.
The best way to learn Best Practices is first code-reading and second actually Practicing them.
Also I dont think a dependency of 1 MB size should be a headache in today's world.

Creating objects from request

I'm working on some user related tasks for a website. For cases when the person is registering or editing a user, they fill out a form and the request is handled in a servlet. At the moment, the servlet is taking all the request parameters and building a User object from them, like this:
User toRegister = new User(request.getParameter("name"),
request.getParameter("lastName"));
There's more parameters but you get the point.
So this sort of code is being reused in a bunch of different servlets (registering, admin adding user, user updating self, admin updating others etc) and it's kinda ugly, so I wanted to clean it up. The two alternatives I could think of were a constructor that takes the request object or a static method in the User class to create and return a new User based on the request.
It's not much of a question since I know they would both work but I couldn't find any sort of best practices for this situation. Should I keep to handling the requests individually in the servlets in case the forms change or should I implement one of the above methods?
DON'T add a c'tor that takes a Request as an argument. You only couple your User class to the Servlet API this way.
Instead use a Web Framework as #skaffman suggests. There are many of these, and it will make your life easier.
EDIT: If you refuse to learn a new framework you can at least use BeanUtils of some similar framework to do the data binding only. I do recommend the Web Framework option though.
Instead of coding all the business logic in the servlet, why dont you use basic MVC framework. Using a framework will make your coding and testing a lot easier.

One or multiple servlets per webapp?

I know, it depends on the webapp. But in the normal case, what do you do: one servlet, that serves different pages (like an standalone-application with changing content) or for every page a single servlet.
Take for instance a blog. There is the start-page with the most recent blog-entries, an article-view for displaying one blog-entry and an archive. Do you implement this with three different servlets, or one that is dispatching to the functions. At least a good part of the stuff is shared, like http-headers.
So, what are your experiences, what works best?
Usually you will create a servlet per use case. Servlets acts like controllers for your application. When you identify an interaction from a user then implement a servlet to control that interaction.
That is, if you are using plain servlet/JSP to build the site. If you are using a framework like struts you will find that they implement the front controller pattern and use a single servlet that recieves all the requests and forwards these requests to action classes that implement the actual logic of the user request. this is much harder to do yourself but its a good practice...its the reason why so many people use these frameworks.
So the short answer is, you will create many servlets per webapp since each webapp will expose several use cases.
[EDIT] Re-reading your question it seems as if you are using the term site to mean page or view. Again, it depends on what is happening on that view. For instance, To display the newest blog entry, you can have a servlet that constructs the list of entries from the database for display. If the user clicks on an entry then another servlet can retrieve that single entry for viewing and so on. Mainly, each action is a use case therefore a different servlet.
Most web frameworks use a dispatcher servlet (ex: Spring MVC) that takes care of routing requests to appropriate classes/controllers.
When you start having lots of pages, this approach works best because you have a more user friendly way (in regard to web.xml) of declaring/managing a class that handles http requests and its url. Example (spring mvc again):
#Controller
public class MyController {
#RequestMapping("/viewPosts")
public void doViewPosts(HttpRequest r, HttpResponse res) {
//...
}
}
Besides, having a dispatcher servlet keeps your code flow centralized.
It depends.
In my latest projects, I have implemented a single servlet that delegates to several servlet-like objects which are instantiated in a dependency injection fashion. For instance, I have something like this in my servlet (pseudo-code):
for(Handler handler : handlers) {
if(handler.handle(request, response)) {
return;
}
}
where Handler is an interface with a boolean handle(request, response) method. I obtain my handlers from a container (be it Spring or something even more lightweight).
The reason for this is that I really like dependency injection, and it is difficult to achieve it in Servlets; and I really don't feel much at home with most frameworks that provide web-component dependency injection- I like the simplicity of servlets.
Were not for this, I would go with multiple servlets, although there's a trade-off; either you have an enormous web xml with lots (and lots) of servlet mappings or you have a very complex servlet (unless you use something like my d-i approach).

Categories

Resources