Servlet question --- getting 505 error....sometimes

L

Larry Coon

Here's an SSCCE. First a simple servlet (Tomcat 5.5):

- - - begin TestServlet.java - - -

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("In doGet()");
}
}

- - - end TestServlet.java - - -

This servlet just logs "In doGet()" to Tomcat's stdout_xxx.log file
whenever it's called. Using a web browser to invoke the servlet, here
are a couple of URLs that work just fine:

http://localhost:8080/larry/test?cmd=abc

http://localhost:8080/larry/test?cmd=abc 123

Both of the above URLs work fine from my browser. In both cases, the
message is logged to Tomcat's log file, and no errors are produced.

Now here's a Swing app to call the servlet:

- - - begin TestApplication.java - - -

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;

public class TestApplication extends JFrame {
private JTextField cmdField;

public TestApplication() {
super("Test Servlet Call");

Container container = getContentPane();

cmdField = new JTextField();
cmdField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processCommand(cmdField.getText());
}
});
container.add(cmdField, BorderLayout.NORTH);

setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);
}

private void processCommand(String cmd) {
try {
URL url = new URL(cmd);
URLConnection urlConnection = url.openConnection();

urlConnection.getInputStream();
} catch (Exception x) {
x.printStackTrace();
}
}

public static void main(String[] args) {
new TestApplication();
}
}

- - - end TestApplication.java - - -

This application invokes the same servlet via the same URLs as the web
browser. When I use this URL:

http://localhost:8080/larry/test?cmd=abc

Everything works fine -- the message appears in Tomcat's log. However,
when I use this URL:

http://localhost:8080/larry/test?cmd=abc 123

(i.e., if I add a space) I get an IOException that the web server
returned
a 505 error (and the "In doGet()" message does not appear in the log)

Can anyone tell me why the call to the same servlet returns a 505 error
if
called by the Swing app, but works fine if called by a browser?

Note: In the previous version of the SCCEE, the servlet actually got the
content of the cmd parameter and echoed that to the log. When called
from
the browser, it echoed the full content of the parameter, including the
space, to the log. So I know the servlet was seeing and processing the
URL correctly, even with the space, when I used a browser.
 
C

Chris Smith

Larry Coon said:
This application invokes the same servlet via the same URLs as the web
browser. When I use this URL:

http://localhost:8080/larry/test?cmd=abc

Everything works fine -- the message appears in Tomcat's log. However,
when I use this URL:

http://localhost:8080/larry/test?cmd=abc 123

(i.e., if I add a space) I get an IOException that the web server
returned a 505 error (and the "In doGet()" message does not appear in
the log)

A valid URL is required to escape certain characters using %xx, where
'x' is a hexadecimal digit. Your web browser knows this, and is
performing the conversion for you. Java's URL class doesn't do this
properly, and therefore causes an error. This is a bug in the class
java.net.URL.

Unfortunately, because some older programs might rely on the broken
behavior, Sun has refused to fix the bug. Instead, they have created a
new class called java.net.URI (Java 1.4 and later). The correct way to
create a URL object is now:

URL url = new URI("...").toURL();

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Roedy Green

http://localhost:8080/larry/test?cmd=abc 123

(i.e., if I add a space) I get an IOException that the web server
returned
a 505 error (and the "In doGet()" message does not appear in the log)

Can anyone tell me why the call to the same servlet returns a 505 error
if
called by the Swing app, but works fine if called by a browser?

use a packet sniffer. You will see the message the browser sends is
not quite what you type.

See http://mindprod.com/jgloss/sniffer.html
 
L

Larry Coon

Chris said:
A valid URL is required to escape certain characters using %xx, where
'x' is a hexadecimal digit. Your web browser knows this, and is
performing the conversion for you.

Thanks Chris (and Roedy). What threw me here is that when I
log the message on the server side, it includes the space when
called by the browser. So when I do this from the browser:

http://localhost:8080/larry/test?cmd=abc 123

then "abc 123" is logged. However, if I do -this- from the
browser:

http://localhost:8080/larry/test?cmd=abc 123

Then "abc%20123" is logged. I had suspected that the browser
was converting the space to %20, but that wouldn't explain how
the %20 was being logged as a space if and only if the browser
had converted it (any ideas why?).
Java's URL class doesn't do this
properly, and therefore causes an error. This is a bug in the class
java.net.URL.

Unfortunately, because some older programs might rely on the broken
behavior, Sun has refused to fix the bug. Instead, they have created a
new class called java.net.URI (Java 1.4 and later). The correct way to
create a URL object is now:

URL url = new URI("...").toURL();

Didn't know this....thanks!


Larry Coon
University of California
 
L

Larry Coon

I have another case where the servlet's response is different
depending on whether I'm using a browser or a Java app.

My servlet is returning an XML document, which contains a DOCTYPE
SYSTEM. If I imvoke the servlet from a browser, the DOCTYPE SYSTEM
appears in the response.

I also wrote an application that uses a Transformer to transform
the XML document to a String, then I display the String in a
JTextArea. Something like (I'll provide an SSCCE if needed, but
for now, just an excerpt):

// The TransformerFactory transformer and DocumentBuilder builder
// are already instantiated.
transformer.setOutputProperty("indent", "yes");
URL url = new URI(cmdField.getText()).toURL();
URLConnection urlConnection = url.openConnection();

Document document = builder.parse(urlConnection.getInputStream());
Source xmlSource = new DOMSource(document);
StringWriter writer = new StringWriter();

transformer.transform(xmlSource, new StreamResult(writer));

textArea.setText(writer.toString());

- - - end sample code - - -

When the transformed document is displayed in the textArea, everything
is there EXCEPT for the DOCTYPE SYSTEM (which, again, is there when I
use a browser).

I looked for arguments to setOutputProperty() that tell the transformer
to include the DOCTYPE SYSTEM it finds in the document, but I didn't
see anything that would work. The DOCTYPE_SYSTEM output property is
used to set it to a specific URL.

How do I get the DOCTYPE SYSTEM to appear?
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top