doPost super causing - HTTP Status 405 - servlets

Till now I believed it was a common practice to call a super.doPost(req, resp) from your servlet's doPost(req, resp){}
But here's the issue I faced -
I have a very simple servlet having a doPost(req, resp) and since it was auto generated method from eclipse it was having super.doPost(req, resp) which is fine as it is calling its parent's doPost() but I was getting
HTTP Status 405 - HTTP method GET is not supported by this URL
whenever the servlet was hit.
I went through a lot of post and this post
had been talking about the same issue and one of the solution suggested was remove the super.doGet().
I did the same with my Post method and to my surprise it worked!!!!
I cannot find a logical reason for this. Can someone please explain what was happening?
Why was
405
flashing due to call of super.doPost().
Thanks,
Saurabh.

The default implementation of HttpServlet.doPost returns a 405 error (method not allowed). You have to implement the doPost method if you want to support the POST method in your servlet.
This is the code of HttpServlet.doPost:
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}

Related

Can I write code after RequestDispatcher?

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//some code here
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//performTask(req, resp);
//some code here
}
private void insertRequestTemplate() {
HttpSession session = req.getSession();
responsePage = req.getParameter("ResponsePage");
ServletContext ctx = getServletConfig().getServletContext();
ctx.getRequestDispatcher(responsePage).forward(req,resp);
readMessage();
public void readMessage()
{
System.out.println("calling MessageTrigger_ABean");
MessageTrigger_ABean msg = new MessageTrigger_ABean();
msg.read();
}
msg.read() has the code to read messages from MQ. Inside insertRequestTemplate method, I am calling readMessage method after ctx.getRequestDispatcher(responsePage).forward(req,resp);is this the correct way of calling this?
But inside insertRequestTemplate method, the page is not getting forwarded to the next page untill readMessage() is executed because of which the page keeps on loading for a long time until message is read from MQ. Could you please help me on this.
Most examples I have seen of a servlet forwarding the request to another servlet have the dispatcher forward invocation at the end of the method. ie. there is no more code, other than closing braces at the end of the method.
I am guessing that the forwarding doesn't happen until the invoking method completes. So where you have your msg.read() will stop the insertRequestTemplate method from completing. This will more than likely be because the code inside msg.read is being performed synchronously. Leading to http timeouts on the http request.
How you solve this will depend on what you want to do with the messages you obtain from msg.read().

Apache Sling - passing request object as part of doPost

Can someone explain and provide code snippet for passing request body (maybe it can accept value Object) as part of apache sling doPost method -
request :
{ "XDPCont" : "XDP sample string"}
Response :
I have tried with below code but it did't work.
#Override
protected void doPost(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
final Resource resource = req.getResource();
resp.getOutputStream().println(resource.toString());
resp.getOutputStream().println(
"This content is generated by the HelloServlet POST"+req.getRequestParameter("XDPCont"));
}
Can you please explain with an working code.

does returning from doGet() or doPost() automatically send a resonse

I have looked around and previously asked this question but did not get a full answer. When you explicity return from doGet() or doPost() does a response get sent regardless of if you have encoded anything or not. If so what is the default code ? Is it enough to simply response.setStatus() and return ? If not: so I have always manually send back a response ? What is the default way to just respond not using forward or redirect ?
If you do nothing, just return (or not even return) from a servlet, it will send back a status code 200(OK) empty response. Tested it in both tomcat and glassfish servers, using the servlet below:
#WebServlet("/a")
public class a extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return;
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return;
}
}
Using the network profiler tool of Chrome you can see what I said:

Serve login page JSP on failed login attempt

My login form is located at /account/login. GET requests to this URL cause a request handler to be invoked, which returns account/login as the logical view name, and /WEB-INF/jsp/account/login.jsp gets served.
#RequestMapping(value="/account/login", method=RequestMethod.GET)
public String login()
{
return "account/login";
}
POST requests to /account/login invoke my UsernamePasswordAuthenticationFilter, so the login form is both served by (via GET) and submits to (via POST) /account/login.
This all works great.
However, in the event of a login failure I would like /WEB-INF/jsp/account/login.jsp to be served without doing an HTTP redirect, i.e. POSTing a bad username/password to /account/login would serve /WEB-INF/jsp/account/login.jsp.
I've tried overriding SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure() like so:
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
{
request.getRequestDispatcher("account/login").forward(request, response);
}
However, this results in a 404 response when POSTing a bad username/password to /account/login.
I've tried passing in /WEB-INF/jsp/account/login.jsp, /account/login.jsp, and many other combinations to ServletRequest.getRequestDispatcher() but nothing seems to work.
Any ideas what I'm doing wrong? I have a feeling the dispatcher is trying to dispatch to my request handler rather than the JSP itself, but I'm not familiar enough with the entire JSP dispatch workflow to know how to get around that.
I accidentally figured this out shortly after posting the question. Answering here in case it becomes of some use to someone else down the road.
In the onAuthenticationFailure(), I passed /account/login to getRequestDispatcher(), and I also called include() rather than a forward(), like so:
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
{
request.getRequestDispatcher("/account/login").include(request, response);
}
Submitting the login form with an incorrect username and/or password causes the login form JSP to be served as the POST's response, and submitting the correct username/password still invokes my UsernamePasswordAuthenticationFilter!!

Servlet doFilter setAttributes not available in Servlet

I'm trying to add an Attribute to the request via doFilter before passing it to the Servlet, so that a value in JSTL will be set. I simply do req.setAttribute("b", "blah") in the filter, but it doesn't seem to get set in the JSTL file. How would I do this?
It's hard to pinpoint the root cause without seeing the code. There are several possible causes.
You're sending a redirect after setting the attribute instead of continuing with the same request.
You're accessing the attribute with the wrong name (case sensitive!).
You're accessing the attribute the wrong way.
The attribute is been overridden somewhere further down in the request processing.
There's a page scoped attribute with the same name which has no value.
You're misinterpreting the results.
Etc.
By the way, there's no such thing as a "JSTL file". Perhaps you meant "JSP file".
The problem is that the doFilter method uses ServletRequest instead of HttpServletRequest which is the one that has the setAttribute method. Most of my filters are something like this:
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// do what you must...
chain.doFilter(servletRequest, servletResponse);
}

Resources