Search code examples
javaandroidkotlinhttprequestokhttp

Is the conversion from Java 11 HttpClient to okhttp right?


The task I want to achieve is to get a PDF file from a POST method and show it to the user.

What I have tried:

I have a Java example that uses the Java 11 HttpClient API to send a POST request to convert a ZPL string to a PDF file from labelary:

var zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";

// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
var uri = URI.create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/");
var request = HttpRequest.newBuilder(uri)
    .header("Accept", "application/pdf") // omit this line to get PNG images back
    .POST(BodyPublishers.ofString(zpl))
    .build();
var client = HttpClient.newHttpClient();
var response = client.send(request, BodyHandlers.ofByteArray());
var body = response.body();

if (response.statusCode() == 200) {
    var file = new File("label.pdf"); // change file name for PNG images
    Files.write(file.toPath(), body);
} else {
    var errorMessage = new String(body, StandardCharsets.UTF_8);
    System.out.println(errorMessage);
}

Per my knowledge this code is not possible with Android. So I have tried it with Squareup okhttp library like follow:

fun fetch(completion: (InputStream?) -> Unit) {
    val url = "https://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/"
    val postBody = "^xa^cfa,50^fo100,100^fdHello World^fs^xz"
    val text = MediaType.parse("text/plain;charset=utf-8")
    val body = RequestBody.create(text, postBody)
    val labelFetch = OkHttpClient()
    val request = Request.Builder()
        .header("Accept", "application/pdf")
        .url(url)
        .post(body)
        .build()

    labelFetch.newCall(request).enqueue(object : Callback {
        override fun onFailure(request: Request?, e: IOException?) {

        }

        override fun onResponse(response: Response?) {
            val pdfData = response?.body()?.byteStream()
            completion(pdfData)
        }
    })
}

Later on I am getting InputStream and if it is not null I am showing it with a pdfViewer, but I get an error like:

java.io.IOException: file not in PDF format or corrupted


Solution

  • It looks like this it would work but I would like to know a better solution

    fun fetch(completion: (InputStream?) -> Unit) {
        val url = "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/^xa^cfa,50^fo100,100^fdHello World^fs^xz"
        val labelFetch = OkHttpClient()
        val request = Request.Builder()
            .header("Accept", "application/pdf")
            .url(url)
            .build()
    
        labelFetch.newCall(request).enqueue(object : Callback {
            override fun onFailure(request: Request?, e: IOException?) {
            }
    
            override fun onResponse(response: Response?) {
                val pdfData = response?.body()?.byteStream()
                completion(pdfData)
            }
        })