Servlet should accept POST and GET - java

I try to implement a servlet which should be called either through POST or GET.
So I wrote something like this
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// .. do stuff
// forward to welcome page
this.getServletContext().getRequestDispatcher("/guestbook.jsp").forward(req, resp);
return;
}
But/or because of the forward at the end I get an IllegalStateException, which is only a warning but still. What should I do differently?
Thanks,
-lony
Edit: Wanted Stacktrace
2012-05-26 18:02:16.422:WARN::/wsc/guestbook
java.lang.IllegalStateException: Committed
at org.eclipse.jetty.server.Response.resetBuffer(Response.java:1056)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:216)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:115)
at de.tum.in.dss.GuestbookController.doGet(GuestbookController.java:135)
at de.tum.in.dss.GuestbookController.doPost(GuestbookController.java:37)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1352)
at de.tum.in.dss.XSSFilter.doFilter(XSSFilter.java:76)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323)
at de.tum.in.dss.AccessFilter.doFilter(AccessFilter.java:55)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:476)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:517)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
at org.eclipse.jetty.server.Server.handle(Server.java:346)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:1065)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:823)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:220)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
at java.lang.Thread.run(Thread.java:722)

Your concrete problem is not related by letting GET and POST both do the same thing. Your problem is caused by writing to the response in the servlet and thus implicitly committing it before performing the forward.
Do not touch response.getWriter() or resposne.getOutputStream() in the servlet and just let JSP do that job. If you need to prepare data which JSP needs to display, just set it as an attribute in the request, session or application scope, depending on the scope the data needs to hold in.
See also:
Our servlets wiki page
Doing the same job on GET and POST is by the way smelly. Are you sure you understand what exactly each of those methods are to be used for?

You can override directly the service() method, it's called for all request methods.

replace this.getServletContext() with req

Related

HttpServletRequest session expires while redirect in Microsoft Edge browser

I'm trying some URL on browser, it works well on all browsers including IE 10 but when on Microsoft Edge, it fails at a point while doing HttpServletResponse sendRedirect, which expires HttpServletRequest session and the expected page does not appear.
Please help for how we can resolve this browser specific redirect-session issue.
Basic code:
public class MyServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// some code where values are set in session
session.setAttribute(myAttribute, value);
response.sendRedirect("https://qa.sys.com/MainPage.jsf");
}
public class MyFilter implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
// myAttribute below comes null as request.getSession() is null
Boolean myAttribute = request.getSession().getAttribute(myAttribute);
}
In logs, I got this Exception:-
java.lang.IllegalStateException: Response already committed
at weblogic.servlet.internal.ServletResponseImpl.objectIfCommitted(ServletResponseImpl.java:1861)
at weblogic.servlet.internal.ServletResponseImpl.sendRedirect(ServletResponseImpl.java:961)
at weblogic.servlet.internal.ServletResponseImpl.sendRedirect(ServletResponseImpl.java:956)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
Truncated. see log file for complete stacktrace
You could also use F12 dev tools to check the Network tab in Edge and see if there's any error in console. This error usually occurs when a java servlet is attempting to write to the output stream (response) after the response has been committed. You could refer to this thread to find out why the response will get committed.
In this blog, it gives the solution and you could also refer to the sample code in the post:
It is always better to ensure that no content is added to the response after the forward or redirect is done to avoid IllegalStateException. It can be done by including a ‘return’ statement immediately next to the forward or redirect statement.
I also find an answer with detailed information about this issue and you could check it.

Java Servlet returns response to client before committing the database transaction

I use a 3rd party framework to process my requests by passing HttpServletRequest and HttpServletResponse into the framework. The database transaction handling is done separately from the framework like this:
public class MyServlet extends HttpServlet {
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
startTransaction();
framework.process(req, resp);
commitTransaction();
}
}
As it turns out, the framework writes the full response back to the client before the call to commitTransaction() returns. This creates possible race-conditions: The client might issue a follow-up request that runs in a second new database transaction that can't access the data added or updated in the first transaction, because it is not committed yet.
What are best practices to work around those kind of issues? I can't modify the behavior of the framework I'm using.
I suggest to use a ServletFilter for such concerns. It would look like this:
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
startTransaction();
chain.doFilter(request, wrapper);
commitTransaction();
}
However, you should add exception handling to the filter.

ProcessRequest Method

When do ProcessRequest method called?
I am having a hard time why ,what and how the process request is called? why it is called and how it was called by the servlet container.
The servlet has two important methods for handling the client's request:
1. doPost: in general handles requests coming from forms with post method.
2. doGet: handled requests coming from get method.
Now, ProcessRequest method, is any other method that you can use into your code which is not bound (overridden) to anything.
It is called from the above methods to not complicate the code in them thus the requests are handled in it.
so you can use ProcessRequest to handle your request if and only if it's called from one of the methods above.
The only ProcessRequest I could find, and the example includes this
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
and
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
So, it's called when you call it.

How to execute a method/event as soon as a servlet is called/page is loaded

I have a servlet that is called from a link on another page. The link actually references the servlet which then SHOULD write xml to the screen (outputting RSS XML information). Right now the link properly references and loads the servlet but because I have the code in the doPost method with nothing actually calling the doPost method nothing happens. (I'm new to Java EE) So how do I make that code execute without actually have a form that references the servlet through the "action =.." tag?
Can I call an init or main method that always executes on page refresh/load?
You can implement that logic in your doGet method. It has the same method signature as your doPost method.
Please see this thread
doGet and doPost in Servlets
For the difference between get vs post please see this article.
http://stevenclark.com.au/2008/01/12/get-vs-post-for-the-beginner/
You can also override Servlet.service method which is entry point for serving requests. This way you will handle both POST and GET requests.
Alternatively, you can implement logic in doGet method and invoke doGet from doPost:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// do request processing
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}

Servlet : doGet and doPost [duplicate]

This question already has answers here:
doGet and doPost in Servlets
(5 answers)
Closed 6 years ago.
I have 2 parameters, User and Pass. I want to send them to a servlet.
If I use the doGet method of the servlet it would look like this :
"link?User="+TextFieldValue+"&pass"textFieldValue
user= UserName.getValue();
pass= password.getValue();
Resource newPictureResource = new ExternalResource("http://localhost:8888/PieChart?UserName="+name+"&Password="+pass);
Success.setSource(newPictureResource);
editContent.addComponent(Success);
send them to servlet :
String UserName = request.getParameter("UserName");
String Password = request.getParameter("Password");
It works (tested)
If the Username + pass are right then he get a "success" picture posted on the screen.
But nobody passes the parameters via URL.
My question: How do I send the parameters using doPost method of the servlet ?
info : im working with eclipse on a liferay portal with a Vaadin portlet.
You don't send parameters in doPost(..). You receive them there. HTTP has many methods, two of which are GET and POST. It is up to the client-side to choose which method to use. POST is most often used with html forms - <form method="POST".
Vaadin should be able to send POST requests as well - see this thread
Not sure how Vaadin interacts, but typically portlet requests are handled differently. Looking though The Book of Vaadin - Portal Integration sheds some insights on configuration and action processing.
If you're looking for a way to handle both request types without reusing logic, simply choose your method of submission by either post or get from your application interface:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Enter logic here
}

Categories

Resources