{"id":277,"date":"2005-08-09T07:06:48","date_gmt":"2005-08-09T13:06:48","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=277"},"modified":"2005-08-09T07:06:48","modified_gmt":"2005-08-09T13:06:48","slug":"lesson-learned-copying-bytes-from-an-outputstream-to-an-inputstream-in-weblogic-8","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/277","title":{"rendered":"Lesson learned: copying bytes from an OutputStream to an InputStream in Weblogic 8"},"content":{"rendered":"<p>A few weeks back, I posted <a href='http:\/\/www.mooreds.com\/weblog\/archives\/000272.html'>about calling one servlet from another, passing a <code>multipart\/form-data<\/code> for submission<\/a>.  I ended up using an <code>HttpURLConnection<\/code> and POSTing to the second servlet.  My target platform was Weblogic 8 on Solaris 8, but I was developing on Windows Server 2003; both had Weblogic running on a Java 1.4 platform.<\/p>\n<p>I set both the <code>doOutput<\/code> and <code>doInput<\/code> properties of the connection to true, so I can first post the needed data and then read the response, which I can parse and pass on to the user.  Here&#8217;s the setup:<\/p>\n<div><code><\/p>\n<pre>\n    URL url = new URL(\"http:\/\/localhost\/myws\/myservlet\");\n    URLConnection con = url.openConnection();\n    HttpURLConnection conn = (HttpURLConnection)con;\n    conn.setDoOutput(true);\n    conn.setDoInput(true);\n    conn.setRequestProperty(\"Content-Type\", request.getHeader(\"Content-Type\"));\n    conn.setRequestProperty(\"Cookie\", request.getHeader(\"Cookie\"));\n    BufferedInputStream bis = new BufferedInputStream(request.getInputStream());\n    BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream());\n<\/pre>\n<p><\/code>\n<\/div>\n<p>I set the Cookie property so that the user does not have to reauthenticate to the second servlet.<\/p>\n<p>However, when I was reading from the first servlet&#8217;s <code>InputStream<\/code> and writing to the second servlet&#8217;s <code>OutputStream<\/code>, I encountered some issues. The below code ran perfectly fine in the development environment, but in the production environment, the file being transferred was corrupted.  The corruption happened in a number of ways, actually.  At first, the file was about twice the size.  Then, after fiddling a bit and moving the  <code>bis.close()<\/code> and <code>bos.close()<\/code> closer to the write\/read, I was able to get the file to be smaller than the posted file.  However, it was a zip file and was still corrupt.) <\/p>\n<div><code><\/p>\n<pre>\n    byte[] data = new byte[1024];\n    int res = bis.read(data);\n    while (res != -1) {\n        bos.write(data);\n        res = bis.read(data);\n    }\n    bos.flush();\n    \/\/ other stuff, like getting response code\n    bis.close();\n    bos.close();\n<\/pre>\n<p><\/code>\n<\/div>\n<p>You can see that I&#8217;m double buffering the <code>InputStream<\/code> here, first with the <code>BufferedInputStream<\/code>, and then with my byte array, <code>data[]<\/code>.  That&#8217;s apparently unnecessary; I don&#8217;t know where I got the idea.  It actually leads to loss of data on the Solaris box.<\/p>\n<p>Luckily, the <a href='http:\/\/www.oreilly.com\/catalog\/javacook2\/'>Java Cookbook<\/a> (and for that matter, the <a href='http:\/\/java.sun.com\/docs\/books\/tutorial\/essential\/io\/filestreams.html'>I\/O section of the Java Tutorial<\/a>) suggested code similar to this:<\/p>\n<div><code><\/p>\n<pre>\n    int res;\n    while ((res = bis.read()) != -1) {\n        bos.write(res);\n    }\n    bis.close();\n    bos.close();\n<\/pre>\n<p><\/code>\n<\/div>\n<p>This code works on both Windows and Solaris.   I&#8217;m a bit mystified as to why the first byte transfer method worked on Windows but not Solaris, and I thought I&#8217;d post this so that any other folks struggling with the same problem don&#8217;t endure the debugging that I did.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few weeks back, I posted about calling one servlet from another, passing a multipart\/form-data for submission. I ended up using an HttpURLConnection and POSTing to the second servlet. My [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-277","post","type-post","status-publish","format-standard","hentry","category-java"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=277"}],"version-history":[{"count":0,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/277\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=277"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=277"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}