Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

java.lang.IllegalStateException: Request Data has already been read reading byte array in servlet

Avatar

Level 4

I have a code in java that sends byte[] to CQ servlet using POST. The code for sending is  :

            URL url = new URL("http://localhost:4503/bin/services/updateslafile"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); String authStr = "admin:admin"; // encode data on your side using BASE64 byte[] bytesEncoded = Base64.encodeBase64(authStr.getBytes()); String authEncoded = new String(bytesEncoded); connection.setRequestProperty("Authorization", "Basic "+authEncoded); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("fileName", "test.docx");         byte[] input;//assume input initialized with some .docx file content as byte[] OutputStream outs = connection.getOutputStream(); outs.write(input); outs.flush(); outs.close(); //for response reading StringBuffer strBuffer = new StringBuffer(); InputStream inputStream = connection.getInputStream(); byte[] b = new byte[1024]; while ( is.read(b) != -1) strBuffer.append(new String(b)); System.out.println("strbuffer : "+strBuffer.toString());

The code in the servlet for reading the byte[] is like below :

String fileName = request.getHeader("fileName"); // opens input stream of the request for reading data InputStream inputStream = request.getInputStream();// This line giving error String filePath = "/home/usr/documents/"+fileName; // opens an output stream for writing file FileOutputStream fileOuputStream = new FileOutputStream(filePath); byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead = -1; LOGGER.info("Receiving data..."); while ((bytesRead = inputStream.read(buffer)) != -1) {           fileOuputStream.write(buffer, 0, bytesRead); } LOGGER.info("Data received."); fileOuputStream.close(); inputStream.close();

Now when I run the code in the error log I am getting some error 

08.03.2016 15:19:37.162 *ERROR* [127.0.0.1 [1457430567960] POST /bin/services/updateslafile HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable
java.lang.IllegalStateException: Request Data has already been read

Apart from this error I am also getting below error but I think this isn't relevant.

08.03.2016 15:17:31.092 *ERROR* [qtp87442412-7274] org.apache.sling.engine.impl.parameters.ParameterSupport getRequestParameterMapInternal: Error parsing request
java.lang.IllegalArgumentException: Bad escape sequence: %ۑ

I know request.getInputStream() is giving some issue but not sure how to fix it.

1 Accepted Solution

Avatar

Correct answer by
Level 4

Hi,

Actually I was getting object there. I converted that object back to raw byte array in the servlet and I got it workign. Code I used is as below :

    String encodingScheme = "UTF-8";     request.setCharacterEncoding(encodingScheme);     String requestStr = request.getParameter("inputstream");     byte[] rawRequestMsg = requestStr.getBytes(encodingScheme);

Now I am writing this byte[] to a file :

public boolean writeToSLAFile(String fileLocation,byte[] byteArray){ try{ String uploadedFileLocation = fileLocation; FileOutputStream fileOuputStream = new FileOutputStream(uploadedFileLocation); fileOuputStream.write(byteArray); fileOuputStream.close(); return true; }catch(IOException e){ LOGGER.error("IO Exception in WriteToSLAFile method"+e.getMessage(),e); } return false; }

Now the writing is successful, file is getting created but the file is corrupt. That I can fix. Thanks Scott.

Regards,

Samir

View solution in original post

5 Replies

Avatar

Level 10

You have to read an input stream in a sling servlet in a certain way. See this community article that shows you how to successfully read an input stream in a sling servlet: 

https://helpx.adobe.com/experience-manager/using/uploading-files-aem1.html

This will help you. 

PS - the article been updated for AEM 6.1. A new package too - which was tested by our AEM super community members. 

Avatar

Level 4

Hi Scott,

That piece of code I tried but its not working for me. I am posting the data using below code :

connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("fileName", filename); OutputStream outs = connection.getOutputStream(); outs.write(input); // input is byte[] outs.flush(); outs.close();

So in the code which you shared in the link first of all isMultipart is false, and if by any way I change it to true then the params comes as empty{}. So I think that code is only for file upload from form. Please suggest.

 

Regards,

Samir

Avatar

Level 4

Hi,

I did a little change in code and now I am getting something which I am not sure is correct or not. I am now setting it as parameter in the post request like below 

connection.setDoOutput(true);         connection.setRequestMethod("POST"); connection.setRequestProperty("fileName", filename); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); System.out.println("input :"+input);// This prints input :[B@2d813d7b writer.write("inputstream="+input);  

Now the input being printed instead of complete byte[] sequence is just [B@2d813d7b and because I am sending the same in parameter, in my cq servlet I am using below code which is giving me only [B@2d813d7b :

                String requestStr = request.getParameter("inputstream");                 byte[] rawRequestMsg = requestStr.getBytes(someSingleByteEncoding);                 LOGGER.info(""+rawRequestMsg); // prints [B@2d813d7b

Now whats happening I don't know but this is definitely not my byte[] which I got by converting a .docx to byte[].

Any suggestions how to deal with this.

Thanks,

Samir

Avatar

Correct answer by
Level 4

Hi,

Actually I was getting object there. I converted that object back to raw byte array in the servlet and I got it workign. Code I used is as below :

    String encodingScheme = "UTF-8";     request.setCharacterEncoding(encodingScheme);     String requestStr = request.getParameter("inputstream");     byte[] rawRequestMsg = requestStr.getBytes(encodingScheme);

Now I am writing this byte[] to a file :

public boolean writeToSLAFile(String fileLocation,byte[] byteArray){ try{ String uploadedFileLocation = fileLocation; FileOutputStream fileOuputStream = new FileOutputStream(uploadedFileLocation); fileOuputStream.write(byteArray); fileOuputStream.close(); return true; }catch(IOException e){ LOGGER.error("IO Exception in WriteToSLAFile method"+e.getMessage(),e); } return false; }

Now the writing is successful, file is getting created but the file is corrupt. That I can fix. Thanks Scott.

Regards,

Samir

Avatar

Employee

This is the correct resolution.