What is the difference between request dispatcher's forward method and the concept of servlet chaining?
Example
RequestDispatcher rd= req.getRequestDispatcher("pathToServlet");
rd.forward(req,resp);
What this does is forwards the request without involving the client(browser) interaction. But can we achieve the same using Servlet Chaining?. If we can then what is the difference?.
It's not different. "Servlet chaining" is just a term coined in dark J2EE 1.1/1.2 ages when servlet filters didn't exist. Indeed, it's basically the approach of using RequestDispatcher#forward() to forward from one to other servlet (and ensuring that the response isn't already committed as that would otherwise result in IllegalStateException).
Since J2EE 1.3 (Servlet 2.3, over a decade ago already!) servlet filters were introduced which made the process so much more clean and easy. Since then, "Servlet chaining" is frowned upon and usually marked as "bad design". These days, you'd ultimately like to end up with only one front controller servlet and several business models.
I think the concept of 'chaining', as it relates to configuring the server instead of using the forward() method, is that you can configure certain types of requests to activate a particular chain of servlets.
For instance, if a request is from within an Intranet you might want the users to see some internal advertising. So you could have all these requests go through as AddInternalBanner servlet first.
The forward() method is useful if a particular servlet decides it should pass the request along.
Related
Imagine the following situation:
A webapplication gets deployed to a tomcat server. A jersey servlet is started that serves requests at http://localhost/myServlet
Now, when somebody is requesting
http://localhost/myServlet/this/path/shall/be/handled, the myServlet should feel responsible for this request and handle it appropiately.
Edit: To be more specific: I do NOT know the path the user is requesting. Think about this like a virtual file system where the user requests myServlet/path/to/file. MyServlet shall be responsible for this GET request. As you can see mapping those URLs to Annotations is not possible. I'd like to annotate like myServlet/*, if that is more understandable.
Could anybody point me to the right direction? I feel a bit lost, but I am quite sure this is possible!
Jersey Servlet (com.sun.jersey.spi.spring.container.servlet.SpringServlet) is the end point for REST API (if we are using Jersey REST) Call. So, When ever the servlet get any request , The same request is been processed by its Handler.
When the application get a request with myServlet with the appropriate url-pattern then Its corresponding Handler will activate and process the request for the appropriate response.
some of you advise me to handle sessions using filters. I studied a little about the filter following some guides found on the internet, and wrote a filter referring this guide.
I saw that the filter is called for every component of my page (css, images etc); is there a way to call it just when a jsp or a servlet is load? I need a method that can understand if jsp or a servlet is load, in order to make some stuff inside my filter.
Yes, you can do that. Just change the url-pattern for your session filter.
If you are using some web framework (spring mvc,...) with one dispatching servlet, you can map your filter only to this servlet using servlet-name and requests to other resources (js, css) will not be intercepted by this filter.
First off, please don't be misled by the purpose of the tutorial in the link you have specified. Session handling is always done through cookies, URL-rewriting (or for the more advanced, SSL). He's merely using filters to enhance application security, by ensuring the user is redirected to the login page, whenever he goes directly to an "avoid-url".
Think about a filter, a physical filter. Whether it be an excel filter or a physical gravel filter. It stands between one thing and another thing:
Java web filters can do the same thing:
Just like you can choose which water bottle to filter, you can decide which requests you want to filter. You do that using the filter-mapping element in web.xml. You can specify individual servlet names, or a url pattern.
We have a Tomcat ValveBase class implementation that is doing the authentication for our servlet container apps. One way to authenticate our http REST calls is to sign them and then check the signature on the server side. We do this check in the ValveBase class.
The problem is that after we consume the InputStream of the request (for validating the signature), we pass the request (org.apache.catalina.connector.Request) to the next valve implementation and by the time it hits the servlet, the inputStream is gone. No content to be delivered, since it was consumed at the signature verification procedure.
In the javax.servlet api, you can use an HttpServletRequestWrapper to implement your own ServletRequest and pass the real request as a constructor argument. In that case, we were able to avoid the situation where the content was read only once, but in the case of the catalina Request, seemed to be more delicate than we thought. Any ideas? Thanks.
There is a long standing enhancement request open against Tomcat to support wrappers for use in Valves in a similar manner to Filters.
The bug includes a patch that is likely to need updating for Tomcat 7.0.x.
Given that you are already using a custom valve adding the patch may not be too much of a leap. With that patch in place, you should be able wrap the internal Request object and solve this problem in a similar manner to the Filter solution (which I assume involves saving a copy of the request body - watch out for DoS issues).
This is, of course, completely untested. As an incentive to try it, if it does work and you provide the updated patch (attach it to the Bugzilla report) I'll look at getting it included in Tomcat 8.0.x and 7.0.x (providing it doesn't require any changes to the existing API).
I am coding a Tomcat application and am authenticating against Google's oauth2 services. I was originally going to write a simple Filter to do the authentication but there is no way to set the user principal in a Filter. From my understanding you have to have the Filter call an implemented HttpServletRequestWrapper and set it inside of that class as seen in this post
I'm pretty sure Tomcat only instantiates one Filter of each type you may have defined and all requests go through this single object down the Filter chain (correct me if I'm wrong).
In the linked to code, is it correct for the code to call
next.doFilter(new UserRoleRequestWrapper(user, roles, request), response);
where every request is instantiating a new UserRoleRequestWrapper? Should this Filter instead have one request wrapper instatiated that gets shared amonsgst all requests? I'm having a hard time finding documentation on the specs of classes such as these.
I don't think that a Filter is what you're looking for. Doesn't seem right for this purpose... Filters weren't created for such use cases; they were created for pre/post processing requests and responses, with emphasis on manipulating the actual request/response data, rather than other aspects of the client-server communication (such as security). Remember, authenticating a user may have further repercussions than just handling HTTP request cycles. Security ties into the JavaEE framework in a lower level than HTTP cycles.
If you want to authenticate against oauth2, you should be far better off implementing some sort of a JAAS implementation for it, and plug it into Tomcat.
I need to call a servlets POST method from another servlet and pass a blob in the servlets parameters. Is this posible, if so how can it be done. PS: I cant use Apache HttpClient
You need to create and send a HTTP request yourself. You cannot make use of forward/redirect/include because you want to change the method from GET to POST and you want to send a multipart/form-data request.
As HttpClient (and other 3rd party library?) is apparently not an option, your best bet is to use the standard Java SE API provided java.net.URLConnection. Long story short: Using java.net.URLConnection to fire and handle HTTP requests At the bottom you can find a multipart/form-data example.
Please note that this problem is not specific to servlets. In other words, you must be able to execute this code in a plain vanilla Java application with a main() method. This allows for easier testing and finetuning. Once you get it to work, just let the servlet execute the same piece of code.
Unrelated to the problem, I have the impression that there's a major design failure somewhere, certainly if the both servlets runs in the same webapplication context. The other servlet where you want to send the POST request to is apparently too tight coupled and should be refactored.
You can get a dispatcher to another servlet in your application and forward it or include it as #Ryan suggests. The code should be something like this inside your first servlet:
ServletContext context = this.getServletContext();
RequestDispatcher dispatcher = context.getRequestDispatcher("/otherurltoservlet");
// change your request and response accordingly
dispatcher.forward(request, response);
Do you mean call from your application to another web service? If so, then something like HttpClient is what you want. If you mean you want to programmatically invoke another servlet in your app, then you're looking to either forward to it or include it.