0

I have a double issue concerning my code. I have to make a call to a REST API from KTA (Kofax Total Agility). I send a call to the entry point :

{
    "sessionId" : "EG346A9A4BD94E45C09106DA457596293",
    "reportingData": null,
    "documentId": "c12ebf4e-b756-4c55-a0e6-ab2200f16990"
}

And receive a response :

{
    "d": {
        "__type": "DocumentSourceFile:http://www.kofax.com/agility/services/sdk",
        "MimeType": "application/pdf",
        "SourceFile": [
            37, 80, 68, 70, 226,227,207,211...
        ]
    }
}

According to the documentation it returns a byte array and this byte array should be converted onto a pdf file. So far, so good ! Now i meet some issues :

  • the documentation specifies I should receive a byte containing the file data but it looks like an int array or unsigned bytes (values greater than 127)
  • I tried to retrieve the document and for this I hard coded the byte array in a basic class. Because of length I receive an error message : java: code too large

Here is the code I use in order to try if i can convert it onto a file :

public static int[] sourceFile = new int[]{37,80,68,70,45,49,46,52,10,37,226,227,207,211,

// test variables
private static String FILEPATH = "";
private static File file = new File(FILEPATH);

// convert to byte array
private static void getSourceFile(int[] sourceFile) {
    byte[] returnValue = new byte[sourceFile.length];
    for(int i = 0; i < sourceFile.length; i++) {
        byte b = (byte) Integer.parseInt(String.valueOf(sourceFile[i]));
        returnValue[i] = b;
    }
    // byte to file
    writeByte(returnValue);
}

private static void writeByte(byte[] bytes) {
    try {
        // Initialize a pointer in file using OutputStream
        OutputStream os = new FileOutputStream(file);
        // Starts writing the bytes in it
        os.write(bytes);
        System.out.println("Successfully byte inserted");
        // Close the file
        os.close();
    } catch (Exception e) {
        System.out.println("Exception: " + e);
    }
}

public static void main(String[] args) {
    //getSourceFile(sourceFile);
    System.out.println(sourceFile.length);
}
davidvera
  • 1,292
  • 2
  • 24
  • 55
  • 1
    "sourceFile = new int[]{37,80,68,70,45,49,46,52,10,37,226,227,207,211," Are you copy pasting whole file content like this? How long is the byte array? The maximum length of an array in Java is 2147483647. If you are receiving this array in run time, It might not represent the whole file and might be the file could have been divided into multiple arrays. So you just write an example code with an array less in size compared to the original and write it to a file in appending mode. Whenever you receive another array, you keep appending. – AntiqTech Dec 18 '19 at 11:44
  • In fact my array contained 24k entries. I will build it by reading it from a file. From now i should be able to manage this part... For information: According to the Java Virtual Machine specification, a the code of a method must not be bigger than 65536 bytes. I learnt it today... thanks. – davidvera Dec 18 '19 at 11:46
  • "I will build it by reading it from a file". This file is something you created to test your code or is it a file you created from that REST API ? – AntiqTech Dec 18 '19 at 11:49
  • In fact i test and hard code some output from a rest request. My POST returns me this awful c# byte array that should help me to create a file. In fact I just try to rebuild the file from this array. After this i'll implement this code in my application. I just separate stuff and try out how my API is working. As I can't create a hard coded array, i'll generate it from a file I will create specially for test purpose. My request returns me a JSON – davidvera Dec 18 '19 at 11:53
  • 1
    I'll try to answer as I understand, I hope it will be usefull. In the part where you're parsing json, you could try directly writing bytes, one by one, into File like this : OutputStream os = new FileOutputStream(new File("a.pdf")); JsonArray arr = jsonObject.getAsJsonObject("d").getAsJsonArray("SourceFile"); for (int i = 0; i < arr.size(); i++) { Byte byytt = arr.get(i).getAsByte() ; os.write(byytt); System.out.println(byytt); } This should be useful for you, If you didn't try it already. – AntiqTech Dec 18 '19 at 12:12
  • FYI, I converted sample.pdf file into byte array and pasted the list into the json template you provided then tried out the code sample in the above comment, I was able to create the pdf file, open and read it. – AntiqTech Dec 18 '19 at 12:28

1 Answers1

0

I finally solved my issue concerning the error message and the byte array. This code won't work in a real world situation. I'll use part of it to put it in the application. Instead of hard coding the array in the class, I put the content of the array in a text file. In the application I will receive a json with a byte array.

// convert a file to string
private static String fileToString() {
    StringBuilder stringBuilder = new StringBuilder();
    try(Stream<String> stream = Files.lines(Paths.get("source.txt"), StandardCharsets.UTF_8)) {
        stream.forEach(str -> stringBuilder.append(str).append(","));
    } catch (IOException e) {
        e.printStackTrace();
    }
    // System.out.println("Strinbuilder : " + stringBuilder.toString());
    return stringBuilder.toString();
}

The second and third step are meant to convert the string to a byte array.

// convert a string to array of string
private static String[] stringToArray(String s) {
    String[] returnValue;
    String delimiter = ",";

    returnValue = s.split(delimiter);

    return returnValue;
}

// convert an array of string to an array of byte
private static byte[] stringToByte(String[] str) {
    byte[] returnValue = new byte[str.length];
    try {
        for (int i = 0; i < str.length; i++) {
            returnValue[i] = (byte) Integer.parseInt(String.valueOf(str[i]));
            System.out.println("returnValue[i] = " + returnValue[i]);
        }
        return returnValue;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Finally I convert the byte array to pdf file.

private static void writeByte(byte[] bytes) {
    try {
        // Initialize a pointer in file using OutputStream
        OutputStream os = new FileOutputStream("out.pdf");
        // Starts writing the bytes in it
        os.write(bytes);
        System.out.println("Successfully byte inserted");
        // Close the file
        os.close();
    } catch (Exception e) {
        System.out.println("Exception: " + e);
    }
}

The main class just aim to check if I generate the right output and it works fine.

public static void main(String[] args) {
    String s = fileToString();
    String[] arr = stringToArray(s);
    byte[] byteArray = stringToByte(arr);

    assert byteArray != null;
    writeByte(byteArray);
}

Thanks to AntiqTech !

davidvera
  • 1,292
  • 2
  • 24
  • 55