k-wasilewski
k-wasilewski

Reputation: 4643

Request from Java (HttpURLConnection) - how to send binary content

I have my server (SpringBoot), which expects a file to be uploaded, and my client (plain Java), which needs to send a byte[] array there.

Server endpoint looks like this:

@RequestMapping(value = "/", method = RequestMethod.POST, headers={"content-type=multipart/form-data"})
ResponseEntity<String> postBytes(@ApiParam(value = "Upload bytes.", example = "0") @RequestBody Bytes bytes) {                   
    return ResponseEntity.ok(byteLinkService.postBytes(bytes.getBytes()));
}

Client request looks like this:

//byte[] bytes is my file to be uploaded
URL url = new URL(this.endpoint + "/bytelink/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "Bearer " + token);
con.setRequestProperty("Content-Type", "multipart/form-data");
con.setRequestProperty("Accept", "*");
con.setDoOutput(true);
            
String jsonInputString = "{\"bytes\": \"" + Arrays.toString(bytes) + "\"}";
try (OutputStream os = con.getOutputStream()) {
    byte[] input = jsonInputString.getBytes("utf-8");
    os.write(input, 0, input.length);           
}

int status = con.getResponseCode();
System.out.println(status);

Right now I am getting this Exception:

WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain;charset=UTF-8' not supported]

Upvotes: 0

Views: 1144

Answers (2)

Michael Gantman
Michael Gantman

Reputation: 7808

Actually, I have written an Open source library that includes HttpClient utility. I am working right now to add a feature that would allow uploading binary information. I already have a working code, but the version with this feature is not released yet. But I have tested it and it works, so I can give you my Spring boot server code that I used for testing in receiving side and you you can look at my open source branch with the code that is sending binary info to the server. Lets start with the server side. This code receives POST request and reads binary info from the request and saves it as a file:

@RestController
@RequestMapping("/upload")
public class UploadTestController {
    @PostMapping
    public ResponseEntity<String> uploadTest(HttpServletRequest request) {
        try {
            String lengthStr = request.getHeader("content-length");
            int length = TextUtils.parseStringToInt(lengthStr, -1);
            if(length > 0) {
                byte[] buff = new byte[length];
                ServletInputStream sis =request.getInputStream();
                int counter = 0;
                while(counter < length) {
                    int chunkLength = sis.available();
                    byte[] chunk = new byte[chunkLength];
                    sis.read(chunk);
                    for(int i = counter, j= 0; i < counter + chunkLength; i++, j++) {
                        buff[i] = chunk[j];
                    }
                    counter += chunkLength;
                    if(counter < length) {
                        TimeUtils.sleepFor(5, TimeUnit.MILLISECONDS);
                    }
                }
                Files.write(Paths.get("C:\\Michael\\tmp\\testPic.jpg"), buff);
            }
        } catch (Exception e) {
            System.out.println(TextUtils.getStacktrace(e));
        }
        return ResponseEntity.ok("Success");
    }
}

This is the client code that uses method sendHttpRequest HttpClient class from my library and reads some binary file over to the server side.

private static void testHttpClientBinaryUpload() {
    try {
        byte[] content = Files.readAllBytes(Paths.get("C:\\Michael\\Personal\\pics\\testPic.jpg"));
        HttpClient client = new HttpClient();
        Integer length = content.length;
        Files.write(Paths.get("C:\\Michael\\tmp\\testPicOrig.jpg"), content);
        client.setRequestHeader("Content-Length", length.toString());
        String result = client.sendHttpRequest("http://localhost:8080/upload", HttpMethod.POST, ByteBuffer.wrap(content));
        System.out.println(result);
        System.out.println("HTTP " + client.getLastResponseCode() + " " + client.getLastResponseMessage());
    } catch (Exception e) {
        System.out.println(TextUtils.getStacktrace(e, "com.mgnt."));
    }
}

And finally my library. See class HttpClient See method sendHttpRequest on line 146 and method sendRequest on line 588 to see how it works.

If you are interested in the library in general here is the Javadoc for the latest release, Maven artifacts could be found here, library (jar, Javadoc and source code) here and the source code for unreleased yet branch is here

Upvotes: 1

Fakhar uddin Malik
Fakhar uddin Malik

Reputation: 89

You have to make changes on multiple stages to make it work. Here is a detailed thread which should help in this regards. How to set UTF-8 character encoding in Spring boot?

Upvotes: 0

Related Questions