java.io.StreamCorruptedException: invalid stream header: C2ACC3Ad

191 Views Asked by At

I was trying to transmit objects between two controllers with StreamingResponseBody. All was pretty much good to me until I noticed that I transferring just a regular String. Its bytes are different from that ones I am sending from /send endpoint...

I would be geatfull if you can help me to figure out what is going on.

SendController:

... 

@GetMapping(value="/send")
public ResponseEntity<StreamingResponseBody> send(){

 List<Student> students = studentManager.getStudents();

 StreamingResponseBody stream = outputStream -> {
  for(Student student: students){
    byte[] data = SerializationUtils.serialize(student);
    outputStream.write(data);
    outputStream.flush();
  }
 };

 ResponseEntity.ok()
   .contentType(MediaType.APPLICATION_STREAM_JSON)
   .body(stream);
}

Another app, Receivier method:

// code ommited
...

HttpHeaders headers = new HttpHeadres();
List<MediaType> mediaList = new ArrayList<>();
headers.setAccept(mediaList);

HttpEntity<Object> entity = new HttpEntity<>(null, headers)
ResponseEntity<String> response = new restTemplate.exchange("http://localhost:8080/send", HttpMethod.GET, entity, String.class);

byte[] bytes = response.getBody().getBytes();
Object responseObj = SerializationUtils.deserialize(bytes);

List<Object> objs = Arrays.asList(responseObj);
List<Student> students = new ArrayList<>();
for(Object o: objs){
 students.add((Students)o);
}

...
1

There are 1 best solutions below

0
On

You are using a lambda. You have neither a guarantee that the lambda is executed during the send() method, nor that the same thread is used.

Since the transactional context used by Spring is stored in a thread-local variable, you might loose this transactional-context. If student is a entity-instance in a transactional-session student might not be deserialized compleatly from the database anymore.