我想根据需要将内容长度响应标头设置为我的控制器之一。在参考这两个问题(First,Second)之后,我可以理解设置响应头是至关重要的。但是,我确实需要这个。我的代码片段如下,
@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);
}
在上述情况下,Content-Length计算不正确,响应json被收缩。 (即,如果地图包含 50 个对象,则响应会在中间某处缩小)
请帮忙如何达到预期的结果。预先感谢。
我对上面链接的问题之一的答案做了一些修改。下面的代码为我提供了内容长度标头的正确值,并且我的响应 json 已完全提供。
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);
}
}
您的代码可以通过做两件事来改进:
ObjectMapper
OutputStream
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 {
@Autowired
private ObjectMapper objMapper;
@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
var countingOutputStream = new CountingOutputStream();
objMapper.writeValue(countingOutputStream, responseMap);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HttpHeaders.CONTENT_LENGTH,String.valueOf(countingOutputStream.count));
return ResponseEntity.ok().headers(httpHeaders).body(responseMap);
}
}
private static class CountingOutputStream extends OutputStream {
private int count;
@Override
public void write(int b) {
count++;
}
@Override
public void write(byte[] b) {
count += b.length;
}
@Override
public void write(byte[] b, int off, int len) {
count += b.length;
}
}