Servlet error 405

M

Matthew Zimmer

Hi all,
I've got a question about what I'm doing wrong with a servlet I'm
running. Basically, imagine that I have a servlet that runs some
operation and then returns a simple value. The client code makes the
request to the servlet which properly does the operation. However, the
client then attempts to read the result and throws an IOException like this:
java.io.IOException: Server returned HTTP response code: 405 for URL:
http://localhost:8080/myServlets/myServlet
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:709)


Here's some of the code that's causing the problems:

Servlet:
public void service(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
super.service(request, response);

boolean sentResponse = false;
response.setContentType("text/xml");
try
{
boolean ok = false;
// do a bunch of code here, including writing a file to the
hard drive. This appears to be working as I check the server and all
the stuff is there.
// ok = some result based on the code.

String res = (ok ? "woo hoo" : "doh");
PrintWriter out = response.getWriter();
out.write(res);
out.flush();
out.close();
sentResponse = true;
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
if (!sentResponse)
{
PrintWriter out = response.getWriter();
out.write("<doh>doh</doh>");
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}


Client: (note, HttpMessage is nothing more than a wrapper class to
create a url)
private void contactServlet()
{
try
{
HttpMessage servletMessage = new HttpMessage();
// fill in my servletMessage with the appropriate data
URL servlet = servletMessage.getURL();
byte[] args = servletMessage.getArguments();

InputStream istream = sendPostMessage(servlet, args);
}
catch (Exception e)
{
// I always crash on sendPostMessage(...) at con.getInputStream
e.printStackTrace();
}
}

public InputStream sendPostMessage(URL servlet, byte[] args) throws
IOException
{
URLConnection con = servlet.openConnection();

con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded");
sendHeaders(con);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(args);
out.flush();
out.close();

return con.getInputStream(); // this crashes
}

I'm sorry for the length of code, but I wanted to make sure you got most
of what I had. I've trimmed out the stuff that's not really related
(AFAIK) to the problem. Also, I use the same mechinism for several
different servlets and none of them are giving me this problem. Does
anybody have any idea what I might be doing wrong here? I've tried
using both "get" and "post" methods with no success. Thanks for any
help you have.
Matthew Zimmer
 
M

Matthew Zimmer

Okay, I solved this. It was nothing more than me being stupid in this
particular class. I forgot to add the "doPost" and "doGet" methods in
my class since they didn't do anything. Well, it turns out that if you
don't have those and just use the "service" method, it seems that
servlets are unable to create a stream to respond to. Not sure what
happens exactly, but by putting them in things worked again.

Matthew

Matthew said:
Hi all,
I've got a question about what I'm doing wrong with a servlet I'm
running. Basically, imagine that I have a servlet that runs some
operation and then returns a simple value. The client code makes the
request to the servlet which properly does the operation. However, the
client then attempts to read the result and throws an IOException like
this:
java.io.IOException: Server returned HTTP response code: 405 for URL:
http://localhost:8080/myServlets/myServlet
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:709)



Here's some of the code that's causing the problems:

Servlet:
public void service(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
super.service(request, response);

boolean sentResponse = false;
response.setContentType("text/xml");
try
{
boolean ok = false;
// do a bunch of code here, including writing a file to the
hard drive. This appears to be working as I check the server and all
the stuff is there.
// ok = some result based on the code.

String res = (ok ? "woo hoo" : "doh");
PrintWriter out = response.getWriter();
out.write(res);
out.flush();
out.close();
sentResponse = true;
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
if (!sentResponse)
{
PrintWriter out = response.getWriter();
out.write("<doh>doh</doh>");
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}


Client: (note, HttpMessage is nothing more than a wrapper class to
create a url)
private void contactServlet()
{
try
{
HttpMessage servletMessage = new HttpMessage();
// fill in my servletMessage with the appropriate data
URL servlet = servletMessage.getURL();
byte[] args = servletMessage.getArguments();

InputStream istream = sendPostMessage(servlet, args);
}
catch (Exception e)
{
// I always crash on sendPostMessage(...) at con.getInputStream
e.printStackTrace();
}
}

public InputStream sendPostMessage(URL servlet, byte[] args) throws
IOException
{
URLConnection con = servlet.openConnection();

con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded");
sendHeaders(con);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(args);
out.flush();
out.close();

return con.getInputStream(); // this crashes
}

I'm sorry for the length of code, but I wanted to make sure you got most
of what I had. I've trimmed out the stuff that's not really related
(AFAIK) to the problem. Also, I use the same mechinism for several
different servlets and none of them are giving me this problem. Does
anybody have any idea what I might be doing wrong here? I've tried
using both "get" and "post" methods with no success. Thanks for any
help you have.
Matthew Zimmer
 
J

John C. Bollinger

Matthew said:
Okay, I solved this. It was nothing more than me being stupid in this
particular class. I forgot to add the "doPost" and "doGet" methods in
my class since they didn't do anything. Well, it turns out that if you
don't have those and just use the "service" method, it seems that
servlets are unable to create a stream to respond to. Not sure what
happens exactly, but by putting them in things worked again.

If your servlet extends HttpServlet then it is almost never appropriate
to override its service(ServletRequest, ServletResponse) method. You
should override doGet, doPost, etc. instead. Most of those will return
an HTTP 405 error if not overridden. Moreover, note that you _didn't_
override GenericServlet.service(ServletRequest, ServletResponse).
Instead you created a new method with a different (albeit related)
signature. The signatures of all method invocations are determined at
compile time, taking allowed parameter conversions into account as
visible then. That means that you can only override a method with
another method of the exact same signature (name, parameter types, and
return type). What was happening, therefore, was this:

(1) When the servlet container received a request it was invoking
HttpServlet.service(ServletRequest, ServletResponse) on an instance of
your servlet.
(2) HttpServlet.service was choosing the appropriate doGet, doPut, etc.
method to service the request.
(3) Since you had not overridden the selected method, HttpServlet's
version was invoked, which returned an HTTP 405 response.

Your custom service method was never invoked.


John Bollinger
(e-mail address removed)
Matthew said:
Hi all,
I've got a question about what I'm doing wrong with a servlet I'm
running. Basically, imagine that I have a servlet that runs some
operation and then returns a simple value. The client code makes the
request to the servlet which properly does the operation. However,
the client then attempts to read the result and throws an IOException
like this:
java.io.IOException: Server returned HTTP response code: 405 for URL:
http://localhost:8080/myServlets/myServlet
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:709)



Here's some of the code that's causing the problems:

Servlet:
public void service(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
super.service(request, response);

boolean sentResponse = false;
response.setContentType("text/xml");
try
{
boolean ok = false;
// do a bunch of code here, including writing a file to the
hard drive. This appears to be working as I check the server and all
the stuff is there.
// ok = some result based on the code.

String res = (ok ? "woo hoo" : "doh");
PrintWriter out = response.getWriter();
out.write(res);
out.flush();
out.close();
sentResponse = true;
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
if (!sentResponse)
{
PrintWriter out = response.getWriter();
out.write("<doh>doh</doh>");
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}


Client: (note, HttpMessage is nothing more than a wrapper class to
create a url)
private void contactServlet()
{
try
{
HttpMessage servletMessage = new HttpMessage();
// fill in my servletMessage with the appropriate data
URL servlet = servletMessage.getURL();
byte[] args = servletMessage.getArguments();

InputStream istream = sendPostMessage(servlet, args);
}
catch (Exception e)
{
// I always crash on sendPostMessage(...) at con.getInputStream
e.printStackTrace();
}
}

public InputStream sendPostMessage(URL servlet, byte[] args) throws
IOException
{
URLConnection con = servlet.openConnection();

con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded");
sendHeaders(con);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(args);
out.flush();
out.close();

return con.getInputStream(); // this crashes
}

I'm sorry for the length of code, but I wanted to make sure you got
most of what I had. I've trimmed out the stuff that's not really
related (AFAIK) to the problem. Also, I use the same mechinism for
several different servlets and none of them are giving me this
problem. Does anybody have any idea what I might be doing wrong
here? I've tried using both "get" and "post" methods with no
success. Thanks for any help you have.
Matthew Zimmer
 
M

Matthew Zimmer

John said:
If your servlet extends HttpServlet then it is almost never appropriate
to override its service(ServletRequest, ServletResponse) method. You
should override doGet, doPost, etc. instead. Most of those will return
an HTTP 405 error if not overridden. Moreover, note that you _didn't_
override GenericServlet.service(ServletRequest, ServletResponse).
Instead you created a new method with a different (albeit related)
signature. The signatures of all method invocations are determined at
compile time, taking allowed parameter conversions into account as
visible then. That means that you can only override a method with
another method of the exact same signature (name, parameter types, and
return type). What was happening, therefore, was this:

(1) When the servlet container received a request it was invoking
HttpServlet.service(ServletRequest, ServletResponse) on an instance of
your servlet.
(2) HttpServlet.service was choosing the appropriate doGet, doPut, etc.
method to service the request.
(3) Since you had not overridden the selected method, HttpServlet's
version was invoked, which returned an HTTP 405 response.

Your custom service method was never invoked.


John Bollinger
(e-mail address removed)

Thanks for the information on what was going on. The crazy thing though
is that my service method was getting invoked. Everything was working
except for the ability to open an InputStream on the client side.
However, I'm sure you're right about the doGet and doPut being needed as
adding those in (even though they are empty) solved the problem.
Thanks.
Matthew Zimmer
Matthew said:
Hi all,
I've got a question about what I'm doing wrong with a servlet I'm
running. Basically, imagine that I have a servlet that runs some
operation and then returns a simple value. The client code makes the
request to the servlet which properly does the operation. However,
the client then attempts to read the result and throws an IOException
like this:
java.io.IOException: Server returned HTTP response code: 405 for URL:
http://localhost:8080/myServlets/myServlet
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:709)



Here's some of the code that's causing the problems:

Servlet:
public void service(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
super.service(request, response);

boolean sentResponse = false;
response.setContentType("text/xml");
try
{
boolean ok = false;
// do a bunch of code here, including writing a file to the
hard drive. This appears to be working as I check the server and all
the stuff is there.
// ok = some result based on the code.

String res = (ok ? "woo hoo" : "doh");
PrintWriter out = response.getWriter();
out.write(res);
out.flush();
out.close();
sentResponse = true;
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
if (!sentResponse)
{
PrintWriter out = response.getWriter();
out.write("<doh>doh</doh>");
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}


Client: (note, HttpMessage is nothing more than a wrapper class to
create a url)
private void contactServlet()
{
try
{
HttpMessage servletMessage = new HttpMessage();
// fill in my servletMessage with the appropriate data
URL servlet = servletMessage.getURL();
byte[] args = servletMessage.getArguments();

InputStream istream = sendPostMessage(servlet, args);
}
catch (Exception e)
{
// I always crash on sendPostMessage(...) at con.getInputStream
e.printStackTrace();
}
}

public InputStream sendPostMessage(URL servlet, byte[] args)
throws IOException
{
URLConnection con = servlet.openConnection();

con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded");
sendHeaders(con);
DataOutputStream out = new
DataOutputStream(con.getOutputStream());
out.writeBytes(args);
out.flush();
out.close();

return con.getInputStream(); // this crashes
}

I'm sorry for the length of code, but I wanted to make sure you got
most of what I had. I've trimmed out the stuff that's not really
related (AFAIK) to the problem. Also, I use the same mechinism for
several different servlets and none of them are giving me this
problem. Does anybody have any idea what I might be doing wrong
here? I've tried using both "get" and "post" methods with no
success. Thanks for any help you have.
Matthew Zimmer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top