I am required to do some small tasks with JSP; being very new to JSP I was wondering if there was any possibility to get only GET or only POST parameters from the HTTP request.
I have seen ServletRequest.getParameter (and alikes) but it seems that those methods get both GET and POST parameters. Is there a way to get only one of them, without parsing the URL or the request body myself? And if not, is there any precedence rule which values overwrite which (like POST parameters always overwriting GET parameters)?
Generally, requests should better be handled in servlets. They have doGet(request, response) and doPost(request, response) methods, to differentiate the two.
If you really insist on doing it in a JSP, you can differentiate the methods using request.getMethod(). It would return GET or POST.
Since this is homework, I guess the point is to learn how to use servlets and their doX methods, so do it that way.
Update: You can get the query string (request.getQueryString()), which is only the get parameters, and parse it, but I wouldn't say that's a common and good practice.
In JSP, you can look at the request object to determine what kind of request it was (GET or POST), but there's only one parameter map.
Try [Servlet + JSP]. At Servlet you can choose between doPost() or doGet()
Related
I really like functional programming, I like its immutability concepts and also it's no side-effects concepts for functions.
I'm trying to take some of these concepts into java.
Now I have some kind of a servlet which receives a request and if browser did not send a cookie to server then i would like to create a cookie with a certain path to the user.
now inside the servlet i don't want to hold that logic because its common to multiple servlets.
so i extract it into some kind of a cookie manager which will do that:
CookieManager.java.handleCookies(request, response)
Check if browser sent cookie.
If not set cookie with new session cookie value with certain path.
however i don't like it because now the servlet will call the CookieManager.java.handleCookie will have a side effect I would rather it to return some kind of a response and further use it in my servlet wihtout having it effect its parameters that i'm passing into it.
anyone can suggest a solution which would both be elegant, no side effects, and excellent in performance?
thanks
You can make use of servlet filter. It would be well suited for your case. You can map your filter to URL pattern and write your code inside dofilter method. Filters are recommended if you want to have pre and post prcoess of request/response. Since you are doing preprocess for you request it would fit in your case. If is also loosely coupled, because you can remove it, modify it, or add another rule anytime without modifying the core servlet code.
One good solution is to use create a servlet which will act as a parent class for all other servlets.
Now in this servlet put this logic of cookie handling in a common function say handlecookie.
In your get and post APIs of this servlet first call this handleCookie and then service API of servlet (keep this empty)
In al child servlet classes you can only override the service class inherited from the parent class and things should work fine for you
Servlet filters are other solution that you can make use of.
After I added a filter to my app, I am not able to read anything from HttpServletRequest.getReader() in my controllers.
I am calling request.getParameter() a few times, but other than that my filter doesn't do much.
Okay I just thought through the problem and realized that for POST requests, calling getParameter() can cause a problem because POST params would typically be in the request body. The input stream will indeed be opened implicitly by the filter.
In my filter (and in my case) I need to check:
if (((HttpServletRequest) request).getMethod().equals("GET")) {...}
From within a servlet, how can I tell if the servlet is being called by a RequestDispatcher("").include, or if it was called normally?
There should be a bunch of request attributes present, listed here:
http://www.caucho.com/resin-3.0/webapp/faq.xtp#forward-path
For example, request.getAttribute("javax.servlet.include.request_uri") should return a non-null value if an include is in progress.
I'm not sure you can tell directly in a request object, however you can (in servlet 2.4+) insert Filters based on whether the request was a request, a forward, or an include with a declaration in your web.xml.
The setup is described on this developerworks article.
You could, for example, use this technique to intercept includes destined for the URLs you are interested in, and add an attribute to the request which you could then see in your servlet.
I'm trying to log the raw body of HTTP POST requests in our application based on Struts, running on Tomcat 6. I've found one previous post on SO that was somewhat helpful, but the accepted solution doesn't work properly in my case. The problem is, I want to log the POST body only in certain cases, and let Struts parse the parameters from the body after logging. Currently, in the Filter I wrote I can read and log the body from the HttpServletRequestWrapper object, but after that Struts can't find any parameters to parse, so the DispatchAction call (which depends on one of the parameters from the request) fails.
I did some digging through Struts and Tomcat source code, and found that it doesn't matter if I store the POST body into a byte array, and expose a Stream and a Reader based on that array; when the parameters need to get parsed, Tomcat's Request object accesses its internal InputStream, which has already been read by that time.
Does anyone have an idea how to implement this kind of logging correctly?
In fact, Struts doesn't parse the parameters, it relies on the Servlet container to do that. And once the container has read the inputStream to create the parameters Map, of course there is nothing left to read. And in the Tomcat implementation, if you read the inputStream first, then the getParameter* family of methods has nothing left to work on, since, as you correctly note, it doesn't use getInputStream or getReader but accesses internally its optimized reader.
So your only solution in your ServletRequestWrapper is to override getInputStream, getReader, AND the getParameter* family on which Struts relies to read the parameters. Maybe you can have a look at org.apache.catalina.util.RequestUtil to not duplicate the POST body parsing part.
What you have to do in your filter is read the post content in its entirety then when you go to pass the request on to the chain; back the input stream with your own. For example you read the post to file on disk, then when you call:
chain.doFilter(new ServletRequest() {}, response);
You can delegate most methods invocations of your class to the original request, but when it comes time to opening the input stream you need to read from your file on disk.
You need to make sure you don't leak resources as this will be invoked quite frequently and can hurt if done incorrectly.
The in the question linked filter example looks good and ought to work. Maybe you're defining it in the web.xml after the Struts dispatcher filter. It would then indeed be too late to parse and log the request body and still make it available for Struts. You need to declare this filter before the Struts dispatcher filter. The filter ordering matters, they are invoked in the order as they're definied in web.xml.
When you get a doGet or doPost call in a servlet you can use getparameterxxx() to get either the query string or the post data in one easy place.
If the call was a GET, you get data from the url/query string.
If the call was a POST, you get the post data all parsed out for you.
Except as it turns out, if you don't put an 'action' attribute in your form call.
If you specify a fully qualified or partially qualified url for the action param everything works great, if you don't, the browser will call the same url as it did on the previous page submit, and if there happens to be query string data there, you'll get that as well as POST data, and there's no way to tell them apart.
Or is there?
I'm looking through the request object, I see where the post data comes from, I'm just trying to figure out where the GET data comes from, so I can erase the GET data on a post call and erase the post data on a GET call before it parses it out if possible.
Any idea what the safe way to do this is?
And lemme guess: you never tried to not put an action field in a form tag. :-)
You're right, I never tried not to put an action field in a form tag ;-) and I wouldn't, because of exactly what you're talking about. (Also, I think it's not valid HTML)
I don't know of any "clean" way to distinguish between GET and POST parameters, but you can access the raw query string using the getQueryString() method of HttpServletRequest, and you can access the raw POST data using the getInputStream() method of ServletRequest. (I'm looking at the Tomcat API docs specifically here, although I think those are both part of the standard Servlet API) Then you could parse the POST data and GET data separately if you want. They will (or should normally) both be formatted the same way, i.e.
name1=value1&name2=value2&...
though possibly with the ampersands replaced by semicolons (which you can technically do in HTTP/1.1, I didn't know that until recently)
In HTML, action is REQUIRED, so I guess the behavior will vary among clients.
The HttpServletRequest.getParameterxxx() methods don't distinguish between GET and POST parameters. If you really need to distinguish between them, you'll need to parse them manually using getQueryString() for the GET parameters and getInputStream()/getReader() for the POST data.
I would write a ServletFilter and decorate the request object to clean things up a bit (using what Hilton suggested above). This is the classic decorator pattern in an intercepting filter.