'Sending binary data to Spring MVC fails with "Content type 'application/octet-stream;charset=UTF-8' not supported"

I want to send binary data to a POST method in Spring MVC. Not as multipart form-data as no additional information is necessary.

@PostMapping(value = "/post", consumes = "application/octet-stream")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void post(final RequestEntity<InputStream> entity) {
    // final InputStream is = entity.getBody(); // process content
}

For test purposes the data is send with cURL:

curl --header "Content-Type:application/octet-stream" --data-binary @pom.xml http://localhost:8080/post

But every request fails with HTTP status 415:

{
    "timestamp": "2020-01-22T08:27:28.063+0000",
    "status": 415,
    "error": "Unsupported Media Type",
    "message": "Content type 'application/octet-stream;charset=UTF-8' not supported",
    "path":"/post"
}

How to make it work?



Solution 1:[1]

The problem is RequestEntity parameter on the post method.

Just use HttpServletRequest as parameter.

@PostMapping(value = "/post", consumes = "application/octet-stream")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void post(final HttpServletRequest request) {
    // final InputStream is = request.getInputStream(); // process content
}

Solution 2:[2]

@PostMapping(value="/uploadBinary", consumes = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
    public ResponseEntity<?> getBinary(HttpEntity<String> reqEntity) {
        System.out.println(reqEntity.getHeaders());
        System.out.println(reqEntity.getBody());
        byte[] arr;
        try {
            arr = reqEntity.getBody().getBytes();
            for(byte b: arr){
                System.out.println(String.format("%02X", b));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

The above code with the following command works for me:

echo -en '\x03\x04' | curl -X POST  --header "Content-Type:application/octet-stream" --data-binary @-  https://localhost:8080/uploadBinary

Alternatively One can use the following on the controller end:

@PostMapping(value = "/uploadBinary", consumes = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
    public ResponseEntity<?> getBinary(@RequestBody byte[] body) {
        for (byte b : body) {
            System.out.println(String.format("%02X", b));
        }
        return new ResponseEntity<>(HttpStatus.OK);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sven Döring
Solution 2