0

I have a Servlet that sends back a JSON Object and I would like to use this servlet in another Java project. I have this method that gets me the results:

public JSONArray getSQL(String aServletURL)
{
 JSONArray toReturn = null;
 String returnString = "";
 try
 {
    URL myUrl = new URL(aServletURL);
        URLConnection conn = myUrl.openConnection();
        conn.setDoOutput(true);
        BufferedReader in = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String s;
        while ((s = in.readLine()) != null )
         returnString += s;
        in.close();

        toReturn = new JSONArray(returnString);
 }
 catch(Exception e)
 {
    return new JSONArray();
 }
        return toReturn;
}

This works pretty will, but the problem I am facing is the following: When I do several simultaneous requests, the results get mixed up and I sometimes get a Response that does not match the request I send.

I suspect the problem to be related to the way I get the response back: The Reader reading a String from the InputStream of the connection.

How can I make sure that I get one reques -> one corresponding reply ? Is there a better way to retrieve my JSON object from my servlet ?

Cheers, Tim

Tim
  • 3,910
  • 8
  • 45
  • 80
  • Is this ajax call? If so, are you checking responsestatus code? – kosa Jan 13 '12 at 08:55
  • Mark this method as synchronized. What type of your current project in which you are requesting servlet. – KV Prajapati Jan 13 '12 at 08:58
  • `toReturn` is never declared in the method. So I would guess : global variable -> concurrency problems. Or is it just a bad copy/paste ? – Grooveek Jan 13 '12 at 09:00
  • Hello, @Grooveek: Sry Copy Paste Error, I edited it. It is declared now. – Tim Jan 13 '12 at 09:03
  • @thinksteep: What do you mean with AJAX call ? This is a normal Java project - I am simply trying to call and use a servlet that exists somewhere. – Tim Jan 13 '12 at 09:04
  • @AVD: I will try the Synchronized method - but I doubt that it will change anything. This method is called several times, especially when I have multiple instances of the program running. – Tim Jan 13 '12 at 09:05
  • Why are reading multiple lines? Can't you just send data encoded on a single line? Generally JSON isn't sent around formatted with line breaks. – Viruzzo Jan 13 '12 at 09:10
  • Good point - I will try that. Then again I am reading until it is null, so it should be reading only one line anyway, no ? – Tim Jan 13 '12 at 09:16

2 Answers2

1

When I do several simultaneous requests, the results get mixed up and I sometimes get a Response that does not match the request I send.

Your servlet is not thread safe. I'd bet that you've improperly assigned request scoped data either directly or indirectly as instance or class variables of the servlet. This is a common beginner's mistake.

Carefully read this How do servlets work? Instantiation, sessions, shared variables and multithreading and fix your servlet code accordingly. The problem is not in the URLConnection code shown so far, although it indicates that you're doing exactly the same job in both doGet() and doPost(), which in turn is already a smell as to how the servlet is designed.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

Try removing setDoOutput(true), you are using the connection only for input and so you shouldn't use it.

Edit: alternatively try using HttpClient, it's much nicer that using "raw" Java.

Viruzzo
  • 3,025
  • 13
  • 13
  • It did not change anything. The Servlet I am using with Java is also used by Javascript with JQUERY and there is that JSON Callback thing I have read about. It is used to mark each JSON response with a unique ID. Is it possible that I need something similar ? – Tim Jan 13 '12 at 11:06
  • Here it is: `code` statham = new JSONArray(); ... // Fill the results ... // Send back the results JSON String callBack = request.getParameter("jsoncallback"); if(callBack != null) out.print(callBack + "(" + statham + ");"); else out.print(statham); out.close();`code` – Tim Jan 13 '12 at 11:22
  • Uhm this seems like JSONP, which would in fact need to send back a request id to work correctly, but it's only done if the "jsoncallback" is sent. With what `aServletURL` are you calling the method? – Viruzzo Jan 13 '12 at 11:25
  • I am using org.json. The servletUrl is like this: http://host:8080/ToolsWeb/MyServlet?sqlStatement=getInfos&param0=ABC123 – Tim Jan 13 '12 at 11:31
  • Where are you doing the simultaneous requests? Threads, processes, different machines? – Viruzzo Jan 13 '12 at 11:32
  • One machine, several JVMs running the code from my first post. – Tim Jan 13 '12 at 11:45
  • All right, the problem was indeed coming from the Servlet itself. I had declared the JSONobjects to be returned as attributes instead of declaring them in the doPost() method. So the Objects were shared among all running processes .... Thanks anyway, you guys still helped me write a better code ! – Tim Jan 13 '12 at 12:34