Servlet filters: is there `doFilter(HttpServletRequest)` - servlets

The servlet API defines a GenericServlet which accepts ServletRequest objects, and subclasses it to HttpServlet which accepts HttpServletRequest. However, Filter.doFilter seems to accept only ServletRequest. Is there filter class specific to HTTP requests? If not
Why? Since HTTP is the only method common to all web compoments, wouldn't it make sense to have an HTTP-specific filter, just like servlets? What is the rationale?
How should I pass the ServletRequest to the HttpServletRequestWrapper? Do I have to downcast it manually, or is there a more appropriate way?

You're not the only one who wished this for ages. There's actually no reasonable rationale for this. The upcoming Servlet 4.0 (part of Java EE 8) will therefore as per spec issue 141 finally come with a javax.servlet.http.HttpFilter. It's currently already implemented in Tomcat 9. The method signature is:
protected void doFilter(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
Until then, your best bet is baking a HttpFilter yourself, or if you happen to use a JSF+CDI based web application, grab OmniFaces HttpFilter (which is open source, so you could use it as inspiration for baking on your own), which happens to have the following signature:
public void doFilter(HttpServletRequest request,
HttpServletResponse response,
HttpSession session,
FilterChain chain)
Whereby the session is null if it isn't created yet.
As to your secondary question,
How should I pass the ServletRequest to the HttpServletRequestWrapper? Do I have to downcast it manually, or is there a more appropriate way?
Just look at existing code snippets here for several real world exapmles.

Related

Spring MVC - Can I autowire HttpServletRequest in RestController

Can I autowire HttpServletRequest in my RestController like following and will it returns different servletRequest even if it is executed in highly concurrent environment. I have a restriction that I can not have as method parameter because I am implementing an interface which is auto generated and will not have HttpServletRequest as the method parameter.
#RestController
public class MyController implements MyInterface {
#Autowired
private HttpServletRequest servletRequest;
#Override
#RequestMapping(value = "/test", produces = {"application/json"}, consumes = {"application/json"}, method = RequestMethod.POST)
public ResponseEntity<MyResponse> test(#RequestBody final MyRequest payload){
...
}
...
}
I have gone through these SO questions and some other articles on this. But just wanted to ensure that when we autowire HttpServletRequest in the controller then its Scope is Request?
Spring 3 MVC accessing HttpRequest from controller
How are Threads allocated to handle Servlet request?
Scope of a Spring-Controller and its instance-variables
How do I get a HttpServletRequest in my spring beans?
How To Get HTTP Request Header In Java
Note: I did try this and it seems to work fine. But just wanted to confirm that it's a foolproof solution even in a highly concurrent environment.
Also if this is the correct way to do it, I would appreciate if someone can explain how exactly it works.
I have used this and it works fine. But unfortunately I did not find any official documentation which mentions that this should work.
Here is the explanation based on my understanding from debugging the code with running multiple requests with different headers/payload etc.:
Whether we autowire on field or through the constructor, servletRequest acts like a Proxy object which delegates the call to Current HttpServletRequest which is different for each request. Thus, even though it's injected through constructor in a Singleton RestController, it will still have the call delegated to corresponding HttpServletRequest for each new request. This utilizes AutowireUtils.ObjectFactoryDelegatingInvocationHandler to access the current HttpServletRequest object. The java doc for it also says Reflective InvocationHandler for lazy access to the current target object.
Thus even if the autowired Proxy object is always the same for all requests, the underlying target object to which the call is delegated is the current HttpServletRequest object which is per-request.
There is another way you can get HttpServletRequest is using RequestContextHolder as mentioned in this answer
HttpServletRequest currentRequest =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Note: As this explanation is based on my understanding, please do share any official documentation about this if anyone has it.

response.getWriter(); what is the task of this method?

I know this question has been asked before several times. But the answers are not satisfactory. I know getWriter method returns an object of PrintWriter class.Everyone has answered what it returns but I want to know what is used for?
When ever you request something from Client to Server it must maintain a format. Now in J2EE we bind the request information into an object and send it to server. That's why we need a HttpServletRequest reference in Service class. Now the server has the raw data which should be modify/calcuated/ whatever the code is that is to send back again to client and the result is kept in an object of response type.Thats why needed HttpServletResponse reference. Now in HttpServletResponse there is a method named getWriter() which binds the result into object and returns an object of PrintWriter class. Hope this helped you.

FIlterChain exception Handling

I am trying to understand Spring security which involves method security and URL based security . URL based security is completely based on Servlet Filters. There are some scenarios when Spring security deals with exception thrown by filters chain to do its work.
I know how filters are executed by Servlet Container but I am particularly interested in how filterChain handle exceptions thrown by doFilter method in filter chain.
I am particularly interested in how filterChain handle exceptions thrown by doFilter method in filter chain.
It does nothing with them. In other words, it just lets them go and bubble up. They'll eventually end up in servletcontainer's builtin exception handler which already knows how to deal with them based on <error-page> configuration in web.xml.
You can however control it yourself by placing FilterChain#doFilter() call in a try-catch block like so:
try {
chain.doFilter(request, response) {
} catch (ServletException e) {
Throwable cause = e.getRootCause();
// ... (handle it)
}
If anything else down the chain (filter, servlet, jsp, etc) throws an uncaught exception, it'll end up there.
See also:
How does server prioritize which type of web.xml error page to use?
What is the good approach to forward the exception from servlets to a jsp page?
I don't think you are able to return anything meaningful in an errorMessage in the HttpServletResponse stream when trying/catching the doFilter method like that, unless you specifically intercept the HttpServletResponse stream and call something like sendError. And that has to be done even before the call to doFilter.
I am particularly interested in how filterChain handle exceptions
thrown by doFilter method in filter chain.
But I am interested in knowing how to send a meaningful response back into the stream when the exception happens within the filterChain. Because even if there is no Exception, how would you go about handling the success response if you have already called a method like sendError before the doFilter (?)

How to track the HTTP request and response time in jetty

I am trying to track the HTTP request and response time in Jetty. I have extended the jetty server and i am able to get the request timestamp using following snippet :
public void handle(HttpChannel connection) throws IOException,
ServletException {
super.handle(connection);
connection.getRequest().getTimeStamp();
}
I need to get the exact time of the response for the request.
How can i achieve it by extending jetty server ?
If any way of doing other than extending jetty. please let me know
Thank you
Since you seem to only be interested in the latency, do this.
The RequestLog mechanism is now to do this.
Instantiate a new RequestLogHandler and add it as the root of your server Handler tree (think nested, not collection).
Add a custom implementation of RequestLog to the RequestLogHandler
In your custom RequestLog.log(Request,Response) method, grab the Request.getTimeStamp() and work out the latency.
This approach is more durable to changes internally in Jetty, and does not require a fork Jetty + modify approach to work.

SessionAware design in Struts 2

I have been working with Struts 2 for a long time.
In case of implementing SessionAware interface to our action class we will get SessionMap but not HttpSession object.
In case of ServletRequestAware and ServletResposeAware we get HttpServletRequest and HttpServletResponse object but not wrapper objects like SessionMap in case of SessionAware.
My question is, if Struts is giving us SessionMap instead of HttpSession to decouple our action classes from Servlet API and Http protocol,then why it is giving us HttpServletRequest and HttpServletResponse objects in case ServletRequestAware and ServletResponseAware.
If Struts doesn't want to decouple Servlet API and HTTP protocol from the action classes then why it is giving us SessionMap in case of SessionAware interface.
Why we don't get HttpSession object?
In case of ServlectRequestAware and ServletResposeAware we get HttpServletRequest and HttpServletRespose object but not wrapper objects like SessionMap in case of SessionAware.
Because those directly expose the servlet request and response on rare occasions where they're actually necessary (or at least useful).
My question is, if struts is giving us SessionMap instead of HttpSession to decouple our action classes from Servlet API and Http protocol,then why it is giving us HttpServletRequest and HttpServletRespose objects in case ServlectRequestAware and ServletResposeAware.
Because it's much less likely you'd specifically need an HttpSession than the actual request or response.
If struts don't want to decouple Servlet API and HTTP protocol from the action classes then why it is giving us SessionMap in case of SessionAware interface.
It does want to decouple the Servlet API, for good reasons. It forces you to explicitly ask for Servlet API artifacts because they're a code smell. It doesn't prevent you from getting them because on rare occasions they're important.
An HttpSession is pretty much just an attribute map, it doesn't contain information generally useful in an action. On the even-rarer occasions you need one you can still get it.
Why we don't get HttpSession object?
You can get this object from the servlet's HTTP request. No reason to define additional interface to inject the HttpSession into the action. On the other hand Struts defines maps for HTTP request, session, application for easier access/modify its attributes using a Map interface. The servletConfig interceptor can inject these objects to the action if it implements corresponding xxxAware interface.
The list of interfaces that could be injected by this interceptor:
ServletContextAware
ServletRequestAware
ServletResponseAware
ParameterAware
RequestAware
SessionAware
ApplicationAware
PrincipalAware

Resources