4

I have a xml file content as string in my servlet, I need to call another URL with multipart post request to upload it as xml file.

Is there a way it can be done?

So far this is what i am doing

private def createConfiguration(def sessiontoken)
{
    /*reqParams is request.getParameterMap(), fileParams is again a map*/
    def charset = "UTF-8";
    def query = String.format("emailaddress=%s&projectid=%s&cfgname=%s&cfgdesc=%s&cfgfile=%s",
        URLEncoder.encode(sessiontoken, charset),
        URLEncoder.encode(reqParams.c_Cfgname[0], charset),
        URLEncoder.encode(reqParams.c_Cfgdesc[0], charset),
        URLEncoder.encode(reqParams.c_Cfgtype[0], charset),
        URLEncoder.encode(reqParams.CFGFILE[0], charset),)

    URLConnection connection = new URL(fileParams.login).openConnection()
    connection.setDoOutput(true)
    connection.setRequestProperty("Accept-Charset", charset)
    connection.setRequestProperty("Content-Type", "multipart/form-data;charset=" + charset)
    try {
        connection.getOutputStream().write(query.getBytes(charset))
    }
    finally {
        connection.getOutputStream().close()
    }
    InputStream response = connection.getInputStream()
    def xmlString=response.getText()
    xmlString
}

Below is the exception fetched

SEVERE: Servlet.service() for servlet RedirectRequest threw exception java.io.IOException: Server returned HTTP response code: 800 for URL: http://abhishek157:10070/project/create.action at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$getInputStream.call(Unknown Source) . .

Update

Got this very usefull link by BalusC So I used it.

private def getStreamFromString(str)
{
    // convert String into InputStream
    InputStream is = new ByteArrayInputStream(str.getBytes())
    is
}

private def createConfiguration(def sessiontoken)
{


    println "ok good $sessiontoken"
    def charset = "UTF-8"
    def boundary = Long.toHexString(System.currentTimeMillis())
    def CRLF = "\r\n"
    String param = "value"

    URLConnection connection = new URL(fileParams.create).openConnection()
    println fileParams.create
    connection.setDoOutput(true)
    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    PrintWriter writer = null
    try {

        OutputStream output = connection.getOutputStream()
        writer = new PrintWriter(new OutputStreamWriter(output, charset), true)

        // Sending normal param.
        writer.append("--" + boundary).append(CRLF)
        writer.append("Content-Disposition: form-data; name=\"sessiontoken\"$CRLF$CRLF$sessiontoken").append(CRLF)
        //writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF)
        writer.append(CRLF)
        writer.append(param).append(CRLF).flush()

        writer.append("--" + boundary).append(CRLF)
        writer.append("Content-Disposition: form-data; name=\"cfgname\"$CRLF$CRLF${reqParams.c_Cfgname[0]}").append(CRLF)
        //writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF)
        writer.append(CRLF)
        writer.append(param).append(CRLF).flush()

        writer.append("--" + boundary).append(CRLF)
        writer.append("Content-Disposition: form-data; name=\"cfgdesc\"$CRLF$CRLF${reqParams.c_Cfgdesc[0]}").append(CRLF)
        //writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF)
        writer.append(CRLF)
        writer.append(param).append(CRLF).flush()

        writer.append("--" + boundary).append(CRLF)
        writer.append("Content-Disposition: form-data; name=\"cfgenv\"$CRLF$CRLF${reqParams.c_Cfgtype[0]}").append(CRLF)
        //writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF)
        writer.append(CRLF)
        writer.append(param).append(CRLF).flush()

        // Sending xml file.
        writer.append("--" + boundary).append(CRLF)
        writer.append("Content-Disposition: form-data; name=\"cfgfile\"; filename=\"" + reqParams.FILENAME[0] + "\"").append(CRLF)
        writer.append("Content-Type: text/xml; charset=" + charset).append(CRLF)
        writer.append(CRLF).flush()
        BufferedReader reader = null
        try {
            reader = new BufferedReader(new InputStreamReader(getStreamFromString(reqParams.CFGFILE[0]), charset))
            for (String line; (line = reader.readLine()) != null;) {
                writer.append(line).append(CRLF)
            }
        }
        catch(Exception e)  {
            e.printStackTrace()
        }
        finally {
            if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
        }
        writer.flush();
        writer.append("--" + boundary + "--").append(CRLF)
    } 
    finally {
        if (writer != null) writer.close();
    }
    InputStream response = connection.getInputStream()
    def xmlString=response.getText()
    xmlString
}

and on the console I get

http://abhishek157:10070/project/create.action
done

but it is not at all hitting http://abhishek157:10070/project/create.action
Any help?

More Updates

The real request (working from html form, where I select file from web browser)

-----------------------------7dcf4d30e8a
Content-Disposition: form-data; name="sessiontoken"

4611685684744086913
-----------------------------7dcf4d30e8a
Content-Disposition: form-data; name="cfgname"

sadf
-----------------------------7dcf4d30e8a
Content-Disposition: form-data; name="cfgdesc"

sadf
-----------------------------7dcf4d30e8a
Content-Disposition: form-data; name="cfgenv"

Production
-----------------------------7dcf4d30e8a
Content-Disposition: form-data; name="cfgfile"; filename="C:\Simon\xmls\agentind.xml"
Content-Type: text/xml

<?xml version="1.0" encoding="UTF-8"?> and so on...

Updated params part after matching from the actual request in fiddler. See createConfiguration function

Exception fetched (while calling create.action from servlet)

Note: I checked in the servlet before sending the params in create.action, all are valid

java.lang.NumberFormatException: null 

None of the params are read in the server, all are coming as null. Where is the problem. Please help.

Community
  • 1
  • 1
AabinGunz
  • 10,828
  • 47
  • 140
  • 205
  • 1
    http://stackoverflow.com/questions/1378920/how-can-i-make-a-multipart-form-data-post-request-using-java – tim_yates May 04 '12 at 10:58
  • Try setting connection.setDoInput(true) aswell – jontro May 04 '12 at 13:17
  • I've never heard of http status code 800. What kind of server are you trying to connect to? – jontro May 04 '12 at 14:01
  • @jontro: apache tomcat 6 – AabinGunz May 04 '12 at 17:36
  • Check the server logs then, I doubt that tomcat will send an 800 status code – jontro May 05 '12 at 10:34
  • @jontro: Sorry for the late reply. Tomcat sends the `800` status code in `localhost.2012-05-08/log` file – AabinGunz May 08 '12 at 12:08
  • Another thing might help. There are 3 Projects, so this project (p1) calls a servlet which identifies which project should it hit with the request p2 or p3. So now it identifies p2 and sends a request, which logins into p2 and in a chain sends another request for either create/update. So the things is login works fine because it gives me back `sessiontoken` which I use for create/update so the problem is occurring in sending multipart request. Since `create.action` expects multipart data and I am sending file contents encoded with Base64 as a String. So basically I need to convert into file. – AabinGunz May 08 '12 at 12:15
  • @jontro: ok it is no more sending 800 status code now. Please see my updated question. Even I am getting no error/exception anywhere – AabinGunz May 09 '12 at 12:30

1 Answers1

3

In your updated code, you forgot to call connection.getInputStream(); to actually send the HTTP request (and to retrieve the HTTP response).

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Thanks :) I am still getting some exception (java.lang.NumberFormatException: null), may be some logical error somewhere, so i'll get back, but is the multipart request building fine? – AabinGunz May 09 '12 at 12:37
  • You're using some Groovy syntax here and there, so I can't confirm that. For example I'm not sure if those spaces around those `$CRLF`s are significant. The exception occurs on the servlet side when parsing a request parameter as a number, right? If so, then those spaces are apparently really significant. – BalusC May 09 '12 at 12:40
  • Can you help me by giving an equivalent code in Java where ever you feel like `spaces` & `CRLF` is getting messy? Because in your [link](http://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests) I could not find how to keep value for any field eg: name="sessiontoken" but where to put the actual sessiontoken value and `CRLF`'s. In groovy, `$CRLF` just gets the value of `CRLF` inside double quotes – AabinGunz May 09 '12 at 12:50
  • You've already found the link with the equivalent Java code yourself. Check the "Send normal param" part and repeat the whole block for every param. – BalusC May 09 '12 at 12:51
  • In your [link](http://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests) I could not find how to keep value for any field eg: `name="sessiontoken"` but where to put the actual sessiontoken value and `CRLF's`. Can you just provide me with with sending normal params in java code? – AabinGunz May 09 '12 at 16:29
  • Please check my updated code. I tried to mimic the multipart response, but it seems it is unable to pass the parameters properly, as i get `null` for all params – AabinGunz May 11 '12 at 12:53
  • Apparently the other side is doing it wrong. Is it also your own code? Is it also a servlet? Do you understand that you should use `getPart()` not `getParameter()` to obtain a part of a multipart request? That's also explicitly mentioned in that link. – BalusC May 11 '12 at 12:57
  • It's not my code, it is in struts 2. Also it is using request.getParameterMap(). I'll read about getPart() and try to resolve. Thanks :) I am rewarding u with 50 n i'll post a working example, if everything goes well. – AabinGunz May 15 '12 at 06:14
  • I added `connection.getInputStream();` and is able to upload small files but need help with uploading large files. [Here is question](http://stackoverflow.com/questions/25850077/how-to-upload-large-files-by-multipart-request-in-java) – AabinGunz Sep 19 '14 at 08:51