file upload using array of bytes (Java)

We are trying to use rest api "Create Node" in our Java code and implemented upload functionality.

But whenever we are passing array bytes of document, we are getting success (200) but not getting node id in response and document is not getting uploaded.

Is there any sample to upload file using array bytes (Java code)?

Thanks,
Shekhar

Comments

  • This is in C# and i believe can easily be converted to Java. You would also need to replace some variable with their contextual values.

        public string UploadDocument(string Type, string ParentID, string FileName, byte[] FileBytes)
        {
            string NewFolderId = string.Empty;
    
            var values = new NameValueCollection();
            values["username"] = LiveLinkUser;
            values["password"] = LiveLinkPassword;
    
    
            using (var client = new WebClient())
            {
                client.Credentials = new NetworkCredential(ServiceAccount, ServiceAccountPassword);
                //client.UseDefaultCredentials = true;
    
                var response = client.UploadValues(GetAuthUrl, values);
                var responseString = Encoding.Default.GetString(response);
    
                dynamic o = JsonConvert.DeserializeObject(responseString);
    
    
                NameValueCollection nvc = new NameValueCollection();
                nvc.Add("type", Type);
                nvc.Add("parent_id", ParentID);
                nvc.Add("name", FileName);
    
    
                string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
                byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
    
                HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(GetNodesUrl);
                wr.ContentType = "multipart/form-data; boundary=" + boundary;
                wr.Method = "POST";
                wr.KeepAlive = true;
                wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
                wr.Headers.Add("OTCSTICKET", (string)o.ticket);
    
    
                Stream rs = wr.GetRequestStream();
    
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (string key in nvc.Keys)
                {
                    rs.Write(boundarybytes, 0, boundarybytes.Length);
                    string formitem = string.Format(formdataTemplate, key, nvc[key]);
                    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                    rs.Write(formitembytes, 0, formitembytes.Length);
                }
                rs.Write(boundarybytes, 0, boundarybytes.Length);
    
                string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
                string header = string.Format(headerTemplate, "file", "undefined", "undefined");
                byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
                rs.Write(headerbytes, 0, headerbytes.Length);
    
                rs.Write(FileBytes, 0, FileBytes.Length);
    
                byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                rs.Write(trailer, 0, trailer.Length);
                rs.Close();
    
                WebResponse wresp = null;
                try
                {
                    wresp = wr.GetResponse();
                    Stream stream2 = wresp.GetResponseStream();
                    StreamReader reader2 = new StreamReader(stream2);
    
                    string result = reader2.ReadToEnd();
    
                    dynamic oResp = JsonConvert.DeserializeObject(result);
                    NewFolderId = (string)oResp.id;
    
                    //log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
                }
                catch (Exception ex)
                {
                    //log.Error("Error uploading file", ex);
                    if (wresp != null)
                    {
                        wresp.Close();
                        wresp = null;
                    }
                }
                finally
                {
                    wr = null;
                }
            }
    
    
            return NewFolderId;
        }
    
  • I got below code working in JAVA..not well formatted, but works for now. Thanks to Khurram.

    public int createDocument(String parentID, String authTicket, String filePath, String hostname){

        String output = null;
        String result = null;
        int docDataID = 0;
        JsonObject dataVal = null;
        URL restURL;
    
        try {
            restURL = new URL(hostname+"/OTCS/livelink.exe/api/v1/nodes");
    
            HttpURLConnection conn = (HttpURLConnection) restURL.openConnection();
    
            File filetoupload = new File(filePath);
    
             byte[] bFile = new byte[(int) filetoupload.length()];
    
             try {
                    //convert file into array of bytes
                FileInputStream fileInputStream = new FileInputStream(filetoupload);
                fileInputStream.read(bFile);
                fileInputStream.close();
    
    
                }catch(Exception e){
                    e.printStackTrace();
                }
    
            String boundary = "===" + System.currentTimeMillis() + "===";
            // two hyphens required before start of the boundary..not sure why..but it wont work without that
            byte[] boundryBytes = ("--"+boundary+"---\r\n").getBytes( StandardCharsets.UTF_8);
    
            conn.setRequestMethod("POST");
            conn.setRequestProperty("OTDSTICKET", authTicket);
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            conn.setDoOutput(true);
            conn.setDoInput(true);
    
            // Set to multi part form fields instead of URL parameters..this way we can write the file byte array too
            String  subType = "Content-Disposition: form-data; name=\"type\"\r\n\r\n144\r\n";
            String  parentName = "Content-Disposition: form-data; name=\"parent_id\"\r\n\r\n"+parentID+"\r\n";
            String  docName = "Content-Disposition: form-data; name=\"name\"\r\n\r\n"+filetoupload.getName()+"\r\n";
    
            byte[] subTypeBytes = subType.getBytes(StandardCharsets.UTF_8);
            byte[] parentBytes = parentName.getBytes(StandardCharsets.UTF_8);
            byte[] docNameBytes = docName.getBytes(StandardCharsets.UTF_8);
    
            conn.getOutputStream().write(boundryBytes, 0, boundryBytes.length);
            conn.getOutputStream().write(subTypeBytes, 0, subTypeBytes.length);
    
            conn.getOutputStream().write(boundryBytes, 0, boundryBytes.length);
            conn.getOutputStream().write(parentBytes, 0, parentBytes.length);
    
            conn.getOutputStream().write(boundryBytes, 0, boundryBytes.length);
            conn.getOutputStream().write(docNameBytes, 0, docNameBytes.length);
    
            conn.getOutputStream().write(boundryBytes, 0, boundryBytes.length);
    
    
            String fileHeader =  "Content-Disposition: form-data; name=\"file\"; filename=\""+filetoupload.getName()+"\"\r\nContent-Type: "+( new MimetypesFileTypeMap()).getContentType(filetoupload)+"\r\n\r\n";
            byte[] fileHeaderBytes = fileHeader.getBytes(StandardCharsets.UTF_8);
            conn.getOutputStream().write(fileHeaderBytes, 0, fileHeaderBytes.length);
            conn.getOutputStream().write(bFile, 0, bFile.length);
    
            byte[] trailerBytes = ("\r\n--"+boundary+"---\r\n").getBytes(StandardCharsets.UTF_8);
            conn.getOutputStream().write(trailerBytes, 0, trailerBytes.length);
    
            System.out.println(conn.getOutputStream());
    
    
    
            if (conn.getResponseCode() != 200) {
    
                throw new RuntimeException("Failed : HTTP error code : "
                        + conn.getResponseCode()+":"+conn.getResponseMessage()+" reason "+conn.getContentLength());
            }
    
            BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));
    
            while ((output = br.readLine()) != null) {
                System.out.println(output);
                result=output;
            }
            System.out.println(result);
            conn.disconnect();
    
            JsonReader jsonReader = Json.createReader(new StringReader(result));
            JsonObject object = jsonReader.readObject();
            docDataID = object.getInt("id");
    
    
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        return docDataID;
    }
    
  • Ferdinand Prantl
    Ferdinand Prantl E Community Moderator

    When you work more with CS REST API, you will find yourself in need of a library, which will simplify making requests, format multipart/form-data requests and parse JSON responses for you. JDK does not include implementations of JSR-311 and JSR-353 yet. You can try some sample implementation, like Jersey and JSON-P.

    There is another sample below using HttpClient from Apache HttpComponents and Crockford's JSON API. You would need ByteArrayBody - ByteArrayBody(byte[] data, String mimeType, String filename) - for POSTing byte array content. There is a complete example for Multipart encoded request entity.

    import java.io.File;
    import java.io.IOException;
    import java.net.URI;
    import java.net.URISyntaxException;
    
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpDelete;
    import org.apache.http.client.methods.HttpUriRequest;
    import org.apache.http.client.methods.RequestBuilder;
    import org.apache.http.HttpEntity;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.entity.mime.content.StringBody;
    import org.apache.http.entity.ContentType;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.util.EntityUtils;
    
    import org.json.JSONObject;
    
    // Authenticate, upload a document, get information about it and delete it.
    public class UploadDocument {
    
        public static void main(String[] args) {
            // Server connection parameters
            String cgiUrl = "http://myserver/myinstance/cs";
            String userName = "myuser";
            String password = "mypassword";
            // Document upload parameters
            int parentId = 2000;
            String documentName = "myname";
            String filePath = "myname.txt";
    
            CloseableHttpClient client = HttpClients.createDefault();
            try {
                try {
                    String ticket = authenticate(client, cgiUrl,
                                        userName, password);
                    int documentId = uploadDocument(client, cgiUrl, ticket,
                                        parentId, documentName, filePath);
                    JSONObject documentInfo = getNodeInfo(client, cgiUrl, ticket,
                                                    documentId);
                    deleteNode(client, cgiUrl, ticket, documentId);
                } finally {
                    client.close();
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    
        private static String authenticate(CloseableHttpClient client,
                String cgiUrl, String userName, String password
                ) throws IOException, URISyntaxException {
            // Initialize a request to POST /api/v1/auth with username and
            // password form fields to application/x-www-form-urlencoded
            HttpUriRequest request = RequestBuilder
                                        .post()
                                        .setUri(new URI(cgiUrl + "/api/v1/auth"))
                                        .addParameter("username", userName)
                                        .addParameter("password", password)
                                        .build();
    
            // Send the request and parse the JSON response
            System.out.println(request.getRequestLine());
            CloseableHttpResponse response = client.execute(request);
            try {
                JSONObject output = getJSONOutput(response);
                int status = response.getStatusLine().getStatusCode();
                if (status != 200) {
                    throw new IOException("Authentication failed for \"" +
                        userName + "\"");
                }
                return output.getString("ticket");
            } finally {
                response.close();
            }
        }
    
        private static int uploadDocument(CloseableHttpClient client,
                String cgiUrl, String ticket, int parentId, String documentName,
                String filePath) throws IOException {
            // Initialize an authenticated request to POST /api/v1/nodes
            HttpPost request = new HttpPost(cgiUrl + "/api/v1/nodes");
            request.addHeader("OTCSTicket", ticket);
    
            // Provide all input parameters as JSON
            JSONObject input = new JSONObject();
            input.put("parent_id", parentId);
            input.put("type", 144);
            input.put("name", documentName);
    
            // Format body and file form fields to multipart/Form-data
            StringBody body = new StringBody(input.toString(),
                                    ContentType.TEXT_PLAIN);
            FileBody file = new FileBody(new File(filePath));
            HttpEntity inputEntity = MultipartEntityBuilder
                                        .create()
                                        .addPart("body", body)
                                        .addPart("file", file)
                                        .build();
            request.setEntity(inputEntity);
    
            // Send the request and parse the JSON response
            System.out.println(request.getRequestLine());
            CloseableHttpResponse response = client.execute(request);
            try {
                JSONObject output = getJSONOutput(response);
                int status = response.getStatusLine().getStatusCode();
                if (status != 200 && status != 201) {
                    throw new IOException("Document upload failed for \"" +
                        documentName + "\"");
                }
                return output.getInt("id");
            } finally {
                response.close();
            }
        }
    
        private static JSONObject getNodeInfo(CloseableHttpClient client,
                String cgiUrl, String ticket, int nodeId) throws IOException {
            // Initialize an authenticated request to GET /api/v1/nodes/{id}
            HttpGet request = new HttpGet(cgiUrl + "/api/v2/nodes/" + nodeId);
            request.addHeader("OTCSTicket", ticket);
    
            // Send the request and parse the JSON response
            System.out.println(request.getRequestLine());
            CloseableHttpResponse response = client.execute(request);
            try {
                JSONObject output = getJSONOutput(response);
                int status = response.getStatusLine().getStatusCode();
                if (status != 200) {
                    throw new IOException("Node enquiry failed for \"" +
                        nodeId + "\"");
                }
                return output;
            } finally {
                response.close();
            }
        }
    
        private static void deleteNode(CloseableHttpClient client, String cgiUrl,
                String ticket, int nodeId) throws IOException {
            // Initialize an authenticated request to DELETE /api/v1/nodes/{id}
            HttpDelete request = new HttpDelete(cgiUrl + "/api/v2/nodes/" +
                                    nodeId);
            request.addHeader("OTCSTicket", ticket);
    
            // Send the request and parse the JSON response
            System.out.println(request.getRequestLine());
            CloseableHttpResponse response = client.execute(request);
            try {
                JSONObject output = getJSONOutput(response);
                int status = response.getStatusLine().getStatusCode();
                if (status != 200) {
                    throw new IOException("Node deletion failed for \"" +
                        nodeId + "\"");
                }
            } finally {
                response.close();
            }
        }
    
        private static JSONObject getJSONOutput(CloseableHttpResponse response
                ) throws IOException {
            // Parse the response to a JSON object
            System.out.println(response.getStatusLine());
            HttpEntity outputEntity = response.getEntity();
            String content = EntityUtils.toString(outputEntity);
            EntityUtils.consume(outputEntity);
            JSONObject output = new JSONObject(content);
            System.out.println(output.toString(2));
            return output;
        }
    
    }
    
  • @Ferdinand, followed your UploadDocument sample but I failed to upload files bigger then 250MB. Same results using Jersey2 client.

    Getting 404 back:

    ...
    404 - File or directory not found.
    The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.
    ...

    Env: Content Server 16.0.3 (2016-12), build 1197

    Any idea where the limitation is coming from?

    Regards,
    Cristian