javajsonspring-bootspring-mvc

Set Content-Length header in Response Entity (Spring Boot) using Java


I would like to set the content-length response header to one of my controllers as it is needed. After referring these two questions (First, Second), I can able to understand that setting response header would be critical. But, I need this for sure. My code snippet is as follows,

@GetMapping(value = /employees, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, List<Object>>> getEmployeeDetails(@RequestParam(value = "organization_id", required = false) Integer orgId) {

      Map<String, List<Object>> responseMap = //some method returns the data
      ObjectMapper objMapper = new ObjectMapper();
      String responseString = objMapper.writeValueAsString(responseMap);
      HttpHeaders httpHeaders = new HttpHeaders();
      httpHeaders.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(responseString.length()));
      return ResponseEntity.ok().headers(httpHeaders).body(responseMap);
}

In the above case, Content-Length is not calculated correctly and the response json is shrinked. (i.e if the map contains 50 objects, response is shrinked somewhere inbetween)

Please help how to achieve the expected outcome. Thanks in advance.


Solution

  • I have done some modifications to the answer in one of the questions linked above. Below code gives me correct value for content-length header and my response json is served fully.

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    @RestController
    @RequestMapping("/rest")
    public class EmployeeController {
        @GetMapping(value = /employees, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<Map<String, List<Object>>> getEmployeeDetails(@RequestParam(value = "organization_id", required = false) Integer orgId) throws IOException {
            Map<String, List<Object>> responseMap = //some method returns the data
            ObjectMapper objMapper = new ObjectMapper();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //getFactory() and createJsonGenerator() methods are deprecated
            JsonGenerator jsonGenerator = objMapper.getFactory().createGenerator(byteArrayOutputStream);
            objMapper.writeValue(jsonGenerator, responseMap);
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add(HttpHeaders.CONTENT_LENGTH,String.valueOf(byteArrayOutputStream.size()));
            return ResponseEntity.ok().headers(httpHeaders).body(responseMap);
        }
    }