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.
Related
This is the thing i want it to be done by my javassist agent.
System.out.println(response.getStatus());
But i am not able to get the HttpServletResponse object by javassist.
Or can it be done using reflection
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.
I have a very simple servlet, which contains the following code to build a response:
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType(CONTENT_TYPE);
final PrintWriter out = response.getWriter();
// ...
My Sonar raises a critical issue with the rule: "Exceptions should not be thrown from servlet methods". Sonar explains it's a bad idea to let such exceptions be thrown:
Failure to catch exceptions in a servlet could leave a system in a
vulnerable state, possibly resulting in denial-of-service attacks, or
the exposure of sensitive information because when a servlet throws an
exception, the servlet container typically sends debugging information
back to the user. And that information could be very valuable to an
attacker.
But if I understand their example, I cannot figure how to manage smartly the potential IOException on response.getWriter().
Some people can explain me when this statement can raise an exception, and how/why it's important to manage it by our-self?
EDIT:
I accepted the first answer despite that I was a little frustrated. I understand very well it's a bad practice to let the servlet container manages this exception as the default behavior expose the stacktrace and possible other sensitive information to the world.
In my case, the HTTP end-point was used for internal monitoring. So in my case, I wanted to expose (relevant) information and the question was HOW I can do that if I have no PrintWriter...
What I did: my program prints an error log and it returns an HTTP error code with no content. I don't know if it can really happen... but Sonar and me are happy.
By throwing an exception in a servlet you expose the stacktrace and possible other sensitive information to the world. You should catch the exception and print/show a nice error message.
It's simple: assume all the consumers your service has are idiots and need to be treated with kid gloves - that means sending them a nicely formatted error message with a description of your choosing instead of the whole Exception.
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
This is a method that's used for handle ajax request. So the output is written to the response
public ModelAndView myAction(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception
{
//call other methods and send the response as arg
//call getWriter on the response
}
According to this doc, I would definitely have an IllegalStateException if I call getWriter having already called getOutputStream(), so I suspect the methods I passed the response to did this although I don't really see them doing so...
The only thing for sure is that at some point, one of the methods may do response.sendError().
Does this some how call getOutputStream()?
HttpServletResponse#sendError() commits the response and send an error status code. The javadoc states
If the response has already been committed, this method throws an
IllegalStateException. After using this method, the response should be
considered to be committed and should not be written to.
In other words, after you call that method, the HTTP response has basically been sent. It makes no sense to call any of the getOutputStream() or getWriter() methods. Your Servlet container further makes it foolproof by throwing an Exception if you attempt to.
I had similar issues but I had not called sendError(), just setContentType() before that. As per this source, it can trigger the same behaviour:
I am guessing its because you have already opened the stream by
calling the resp.setContentType("text/plain"); method, and are then
trying to get a Writer object. You can either use Stream based
classes, or Writer based classes - not both.
Either remove the setContentType(), or send the response using
response.getOutputStream() method. That should solve the problem.
And indeed, it resolved the similar error for me.