I have a servlet that accepts POST requests, and it works perfectly when I'm not trying to read parameters. The inputstream contains an XML file which parses just fine. However, when I try to read a parameter:
String account = request.getParameter("account");
It fails when reading the inputstream.
How can this possibly affect the inputstream?
I suppose you are using a HttpServletRequest and from the ServletRequest#getParameter() documentation:
If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method.
Are you using either getInputStream() or getReader() prior to your getParameter() ?
A related answer here might help you solve your problem: https://stackoverflow.com/a/17129256/1524381
Related
I have a large file download that is served by a RestController on one server, that I need to stream through a RestController on another server. When calling the end server directly the result streams fine. However when using RestTemplate to call this server and then write the response to an OutputStream, the response is buffered on the front server until the whole file is ready, and then streamed. Is there a way I can write the file to an OutputStream as it comes in?
At the moment my code on the front server looks similar to this
#ResponseBody
public void downloadResults(HttpServletRequest request, HttpServletResponse response, #RequestParam("id") String jobId, OutputStream stream)
throws IOException
{
byte[] data = restTemplate.exchange("http://localhost/getFile", HttpMethod.POST, requestEntity, byte[].class, parameters).getBody();
stream.write(data);
}
I've set my RestTemplate to not buffer and I've verified that this is working by checking the Request type that is used, (SimpleStreamingClientHttpRequest).
The data all comes back correct, its just only written to the stream all at once, rather than as it comes in
RestTemplate is not meant for streaming the response body, as pointed out in this JIRA issue.
You can use restTemplate.execute. See https://www.baeldung.com/spring-resttemplate-download-large-file
I'm currently developing a Servlet that runs under Glassfish 4.
I implemented the doPost() method and I need to ensure that the parameters are passed using the POST body, and not in the query string.
I wrote a test implementation to check it:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
response.getOutputStream().print(name);
}
If I call my page with POST with this url:
http://localhost:8080/myservlet/testservlet
and pass name=Nico into the post body, the value Nico is returned, and it's okay.
Now if I call it this way:
http://localhost:8080/myservlet/testservlet?name=Robert
and I still pass name=Nico in the POST body, Robert is returned, and the name=Nico is ignored.
I just would like to avoid parameters to be passed in the URL.
Is there a way to explicitly retrieve parameters from the POST body instead of body + query string?
Check the javadoc for the getParameter method:
https://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29
Like it is stated, you are sending 2 parameters on the request with the same name, one from the query string and another on the body.
Now it is up to you to either validate that no parameter is coming from the query string or read directly values from the request body.
In most cases, you can read both of them using getParameterValues, the first one is query string and the second one is post body. Now you can decide which one to use.
String[] lines = request.getParameterValues("name");
Did you check what request.getAttribute() returns?
Anyway you can't avoid that people will try to send you evil data, either in the url or by tinkering with the post-request.
So when you work with input from a website, always imagine a hacker sitting on the other side and sending you evil content in your parameters, like sql-injections. So you need a good validation to only let good content through to your database.
Because it's not your problem if a user enters his username as a parameter in the url. Let him have the fun, if he prefers this way over the input-field. The hackers are the problem.
I think it is a problem of front end code, instead of servlet. Any post request submission from UI should strip query string.
In a custom tag, I want to include other things through the RequestDispatcher:
RequestDispatcher rd = request.getRequestDispatcher(url);
rd.include(request, response);
but I can not know the state of the response's output stream. I am currently working around this by wrapping the response and the JspWriter available to the tag in another object that implements HttpServletRequest. when there is a call to getWriter() inside, this works fine. But if code handling the request actually wants to get the raw OutputStream (which i cannot safely get within the tag, either), I get an IllegalStateException (because getOutputStream() has already been called).
Now I could ALSO create a new OutputStream and wrap it up in my request wrapper, buffer it until the include() returns, and then get the bytes written into it and write them to the JspWriter.
My question, however, is this: should I try to maintain character encodings? as in: should I "mock" even more of the response object so I can at least try to do a conversion from the character encoding set in the request wrapper I pass into the include and the underlying outputstream? Would this be "clean enough"? Are there any utility classes I should look into?
You cannot use both getServletOutputStream() and getWriter() in same response.
I think somewhere in your code you are using getServletOutputStream() and including JSP's uses getWriter(). This is causing you the exception.
Please see the duplicate question.
java.lang.IllegalStateException: Already using output stream
I have a extJs form with fileupload and servlet. After uploading file i want to get response from servlet.
i do this System.out.println("{success:true, error:'error'}");
But in firebug in POST i dont see anything. This code works in case wiht jsp but not servlet. So how to send parametrs from servlet?
System.out PrintStream is not the the output stream of your servlet response. It is still the "standard" system out stream. Most application servers redirect that to a log file.
Servlet's service() method, as well as do*() methods of HttpServlet, take ServletResponse respectively HttpServletResponse as a parameter. When implementing a servlet, one can call getWriter() on that parameter to get a PrintWriter open on response's output stream. That can be used to print something to the response.
So, your code should be something like:
response.getWriter().println("{success:true, error:'error'}");
I'm building something using Google App Engine and I'm trying to create a java Servlet that reads the raw POST data and does something with it. According to the servlet documentation, this should be possible using either the getReader() method or the getInputStream() method. However it appears that somehow, at least with the App Engine development server that runs locally on my dev box, getInputStream() has already been called before the doPost method is even entered.
My evidence for asserting this is as follows:
getReader throws a java.lang.IllegalStateException (see this)
getInputStream returns a valid input stream, but calling read() on that input stream returns -1 (see this).
I checked and I am not calling getParameter() before I call getInputStream. getInputStream() is the FIRST thing I call in the body of the doPost method.
What is wrong here?
Per this link from google app engine issue tracker :
That is because the content type was sent as
"application/x-www-form-urlencoded". In that case the stream is read
and mapped as key value pair so that you can access the data as
req.getParameter("ParameterName") and for the same reason stream is
empty. We will be able to access the req.getinputStream() when the
content-type is sent as "application/octet-stream".