下面列出了怎么用org.springframework.http.HttpOutputMessage的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
@SuppressWarnings("unchecked")
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if (object instanceof ResourceRegion) {
writeResourceRegion((ResourceRegion) object, outputMessage);
}
else {
Collection<ResourceRegion> regions = (Collection<ResourceRegion>) object;
if (regions.size() == 1) {
writeResourceRegion(regions.iterator().next(), outputMessage);
}
else {
writeResourceRegionCollection((Collection<ResourceRegion>) object, outputMessage);
}
}
}
@Override
protected void writeInternal(Properties properties, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
// 获取请求头
HttpHeaders headers = outputMessage.getHeaders();
// 获取 content-type
MediaType contentType = headers.getContentType();
// 获取编码
Charset charset = null;
if (contentType != null) {
charset = contentType.getCharset();
}
charset = charset == null ? Charset.forName("UTF-8") : charset;
// 获取请求体
OutputStream body = outputMessage.getBody();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(body, charset);
properties.store(outputStreamWriter, "Serialized by PropertiesHttpMessageConverter#writeInternal");
}
@Test
@SuppressWarnings("unchecked")
public void shouldHandleReturnValueWithResponseBodyAdvice() throws Exception {
servletRequest.addHeader("Accept", "text/*");
servletRequest.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(MediaType.TEXT_HTML));
ResponseEntity<String> returnValue = new ResponseEntity<>(HttpStatus.OK);
ResponseBodyAdvice<String> advice = mock(ResponseBodyAdvice.class);
given(advice.supports(any(), any())).willReturn(true);
given(advice.beforeBodyWrite(any(), any(), any(), any(), any(), any())).willReturn("Foo");
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
Collections.singletonList(stringHttpMessageConverter), null, Collections.singletonList(advice));
reset(stringHttpMessageConverter);
given(stringHttpMessageConverter.canWrite(String.class, MediaType.TEXT_HTML)).willReturn(true);
processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertTrue(mavContainer.isRequestHandled());
verify(stringHttpMessageConverter).write(eq("Foo"), eq(MediaType.TEXT_HTML), isA(HttpOutputMessage.class));
}
@Test //SPR-16754
public void disableRangeSupportForStreamingResponses() throws Exception {
InputStream is = new ByteArrayInputStream("Content".getBytes(StandardCharsets.UTF_8));
InputStreamResource resource = new InputStreamResource(is, "test");
ResponseEntity<Resource> returnValue = ResponseEntity.ok(resource);
servletRequest.addHeader("Range", "bytes=0-5");
given(resourceMessageConverter.canWrite(any(), eq(null))).willReturn(true);
given(resourceMessageConverter.canWrite(any(), eq(APPLICATION_OCTET_STREAM))).willReturn(true);
processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest);
then(resourceMessageConverter).should(times(1)).write(
any(InputStreamResource.class), eq(APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class));
assertEquals(200, servletResponse.getStatus());
assertThat(servletResponse.getHeader(HttpHeaders.ACCEPT_RANGES), Matchers.isEmptyOrNullString());
}
@Override
public void write(final BufferedImage image, @Nullable final MediaType contentType,
final HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
final MediaType selectedContentType = getContentType(contentType);
outputMessage.getHeaders().setContentType(selectedContentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> writeInternal(image, selectedContentType, outputStream));
}
else {
writeInternal(image, selectedContentType, outputMessage.getBody());
}
}
private void writeMultipart(final MultiValueMap<String, Object> parts, HttpOutputMessage outputMessage)
throws IOException {
final byte[] boundary = generateMultipartBoundary();
Map<String, String> parameters = new LinkedHashMap<>(2);
if (!isFilenameCharsetSet()) {
parameters.put("charset", this.charset.name());
}
parameters.put("boundary", new String(boundary, StandardCharsets.US_ASCII));
MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters);
HttpHeaders headers = outputMessage.getHeaders();
headers.setContentType(contentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> {
writeParts(outputStream, parts, boundary);
writeEnd(outputStream, boundary);
});
}
else {
writeParts(outputMessage.getBody(), parts, boundary);
writeEnd(outputMessage.getBody(), boundary);
}
}
@Override
public void write(final BufferedImage image, @Nullable final MediaType contentType,
final HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
final MediaType selectedContentType = getContentType(contentType);
outputMessage.getHeaders().setContentType(selectedContentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> writeInternal(image, selectedContentType, outputStream));
}
else {
writeInternal(image, selectedContentType, outputMessage.getBody());
}
}
/**
* This implementation sets the default headers by calling {@link #addDefaultHeaders},
* and then calls {@link #writeInternal}.
*/
public final void write(final T t, @Nullable final Type type, @Nullable MediaType contentType,
HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
final HttpHeaders headers = outputMessage.getHeaders();
addDefaultHeaders(headers, t, contentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> writeInternal(t, type, new HttpOutputMessage() {
@Override
public OutputStream getBody() {
return outputStream;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}));
}
else {
writeInternal(t, type, outputMessage);
outputMessage.getBody().flush();
}
}
@Override
@SuppressWarnings("unchecked")
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if (object instanceof ResourceRegion) {
writeResourceRegion((ResourceRegion) object, outputMessage);
}
else {
Collection<ResourceRegion> regions = (Collection<ResourceRegion>) object;
if (regions.size() == 1) {
writeResourceRegion(regions.iterator().next(), outputMessage);
}
else {
writeResourceRegionCollection((Collection<ResourceRegion>) object, outputMessage);
}
}
}
@Override
protected final void writeInternal(Object o, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
Writer writer = getWriter(outputMessage);
if (this.jsonPrefix != null) {
writer.append(this.jsonPrefix);
}
try {
writeInternal(o, type, writer);
}
catch (Exception ex) {
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
}
writer.flush();
}
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage) throws IOException {
Assert.notNull(region, "ResourceRegion must not be null");
HttpHeaders responseHeaders = outputMessage.getHeaders();
long start = region.getPosition();
long end = start + region.getCount() - 1;
Long resourceLength = region.getResource().contentLength();
end = Math.min(end, resourceLength - 1);
long rangeLength = end - start + 1;
responseHeaders.add("Content-Range", "bytes " + start + '-' + end + '/' + resourceLength);
responseHeaders.setContentLength(rangeLength);
InputStream in = region.getResource().getInputStream();
try {
StreamUtils.copyRange(in, outputMessage.getBody(), start, end);
}
finally {
try {
in.close();
}
catch (IOException ex) {
// ignore
}
}
}
private void writeForm(MultiValueMap<String, Object> formData, @Nullable MediaType contentType,
HttpOutputMessage outputMessage) throws IOException {
contentType = getMediaType(contentType);
outputMessage.getHeaders().setContentType(contentType);
Charset charset = contentType.getCharset();
Assert.notNull(charset, "No charset"); // should never occur
final byte[] bytes = serializeForm(formData, charset).getBytes(charset);
outputMessage.getHeaders().setContentLength(bytes.length);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> StreamUtils.copy(bytes, outputStream));
}
else {
StreamUtils.copy(bytes, outputMessage.getBody());
}
}
private void writeMultipart(final MultiValueMap<String, Object> parts, HttpOutputMessage outputMessage)
throws IOException {
final byte[] boundary = generateMultipartBoundary();
Map<String, String> parameters = new LinkedHashMap<>(2);
if (!isFilenameCharsetSet()) {
parameters.put("charset", this.charset.name());
}
parameters.put("boundary", new String(boundary, StandardCharsets.US_ASCII));
MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters);
HttpHeaders headers = outputMessage.getHeaders();
headers.setContentType(contentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> {
writeParts(outputStream, parts, boundary);
writeEnd(outputStream, boundary);
});
}
else {
writeParts(outputMessage.getBody(), parts, boundary);
writeEnd(outputMessage.getBody(), boundary);
}
}
@Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
Result result;
if(o instanceof Result){
result = (Result) o;
}else{
result = new Result(true,o);
}
outputMessage.getHeaders().add("Content-Type","application/json;charset=utf-8");
super.writeInternal(result,outputMessage);
}
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
GeminiWrappers.EntityRecordListApiType record = GeminiWrappers.EntityRecordListApiType.class.cast(object);
GeminiWrappers.EntityRecordsList entityRecordList = record.getEntityRecordList(); // unwrap
Map<String, Object> responseBody = new HashMap<>();
responseBody.put("meta", getMeta(entityRecordList));
responseBody.put("data", getData(entityRecordList));
super.writeInternal(responseBody, type, outputMessage);
}
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
GeminiWrappers.EntityRecordsList recordsWrapper = GeminiWrappers.EntityRecordsList.class.cast(object);
Collection<EntityRecord> records = recordsWrapper.getRecords();
List<Object> listOfFields = new ArrayList<>(records.size());
for (EntityRecord record : records) {
listOfFields.add(RecordConverters.fieldsToJSONMap(record));
}
super.writeInternal(listOfFields, type, outputMessage);
}
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
GeminiWrappers.CountRequest req = GeminiWrappers.CountRequest.class.cast(object);
Map<String, Object> res = new HashMap<>();
res.put("count", req.getResult());
super.writeInternal(res, type, outputMessage);
}
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
GeminiWrappers.CountRequestApiType record = GeminiWrappers.CountRequestApiType.class.cast(object);
GeminiWrappers.CountRequest countRequest = record.getCountRequest();// unwrap
Map<String, Object> responseBody = new HashMap<>();
responseBody.put("meta", getMeta(countRequest));
responseBody.put("data", getData(countRequest));
super.writeInternal(responseBody, type, outputMessage);
}
@Test
public void handleReturnValue() throws Exception {
MediaType accepted = MediaType.TEXT_PLAIN;
servletRequest.addHeader("Accept", accepted.toString());
String body = "Foo";
given(stringMessageConverter.canWrite(String.class, null)).willReturn(true);
given(stringMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN));
given(stringMessageConverter.canWrite(String.class, accepted)).willReturn(true);
processor.handleReturnValue(body, returnTypeString, mavContainer, webRequest);
assertTrue("The requestHandled flag wasn't set", mavContainer.isRequestHandled());
verify(stringMessageConverter).write(eq(body), eq(accepted), isA(HttpOutputMessage.class));
}
@Test
public void handleReturnTypeResource() throws Exception {
Resource returnValue = new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8));
given(resourceMessageConverter.canWrite(ByteArrayResource.class, null)).willReturn(true);
given(resourceMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.ALL));
given(resourceMessageConverter.canWrite(ByteArrayResource.class, MediaType.APPLICATION_OCTET_STREAM))
.willReturn(true);
processor.handleReturnValue(returnValue, returnTypeResource, mavContainer, webRequest);
then(resourceMessageConverter).should(times(1)).write(any(ByteArrayResource.class),
eq(MediaType.APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class));
assertEquals(200, servletResponse.getStatus());
}
@Override
protected void writeInternal(DataInputStream in, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
HttpHeaders httpHeaders = outputMessage.getHeaders();
String subtype = httpHeaders.getContentType().getSubtype();
logger.debug("Trying write DataInputStream into servlet OutputStream. Output subtype:{}", subtype);
IOUtils.copy(in, outputMessage.getBody());
in.close();
outputMessage.getBody().close();
}
@SuppressWarnings({ "unchecked", "rawtypes", "resource" })
private ModelAndView handleResponseBody(Object returnValue, ServletWebRequest webRequest)
throws ServletException, IOException {
HttpInputMessage inputMessage = new ServletServerHttpRequest(webRequest.getRequest());
List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
if (acceptedMediaTypes.isEmpty()) {
acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
}
MediaType.sortByQualityValue(acceptedMediaTypes);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(webRequest.getResponse());
Class<?> returnValueType = returnValue.getClass();
if (this.messageConverters != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : this.messageConverters) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(returnValue, acceptedMediaType, outputMessage);
return new ModelAndView();
}
}
}
}
if (logger.isWarnEnabled()) {
logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " +
acceptedMediaTypes);
}
return null;
}
@Test
public void shouldHandleReturnValue() throws Exception {
String body = "Foo";
ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK);
MediaType accepted = TEXT_PLAIN;
servletRequest.addHeader("Accept", accepted.toString());
initStringMessageConversion(accepted);
processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertTrue(mavContainer.isRequestHandled());
verify(stringHttpMessageConverter).write(eq(body), eq(accepted), isA(HttpOutputMessage.class));
}
@Test
public void shouldHandleReturnValueWithProducibleMediaType() throws Exception {
String body = "Foo";
ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK);
servletRequest.addHeader("Accept", "text/*");
servletRequest.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(MediaType.TEXT_HTML));
given(stringHttpMessageConverter.canWrite(String.class, MediaType.TEXT_HTML)).willReturn(true);
processor.handleReturnValue(returnValue, returnTypeResponseEntityProduces, mavContainer, webRequest);
assertTrue(mavContainer.isRequestHandled());
verify(stringHttpMessageConverter).write(eq(body), eq(MediaType.TEXT_HTML), isA(HttpOutputMessage.class));
}
@Test
public void shouldHandleResource() throws Exception {
ResponseEntity<Resource> returnValue = ResponseEntity
.ok(new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8)));
given(resourceMessageConverter.canWrite(ByteArrayResource.class, null)).willReturn(true);
given(resourceMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.ALL));
given(resourceMessageConverter.canWrite(ByteArrayResource.class, APPLICATION_OCTET_STREAM)).willReturn(true);
processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest);
then(resourceMessageConverter).should(times(1)).write(
any(ByteArrayResource.class), eq(APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class));
assertEquals(200, servletResponse.getStatus());
}
@Override
@SuppressWarnings("unchecked")
public void write(MultiValueMap<String, ?> map, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if (!isMultipart(map, contentType)) {
writeForm((MultiValueMap<String, String>) map, contentType, outputMessage);
}
else {
writeMultipart((MultiValueMap<String, Object>) map, outputMessage);
}
}
private void testVaryHeader(String[] entityValues, String[] existingValues, String[] expected) throws Exception {
ResponseEntity<String> returnValue = ResponseEntity.ok().varyBy(entityValues).body("Foo");
for (String value : existingValues) {
servletResponse.addHeader("Vary", value);
}
initStringMessageConversion(TEXT_PLAIN);
processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertTrue(mavContainer.isRequestHandled());
assertEquals(Arrays.asList(expected), servletResponse.getHeaders("Vary"));
verify(stringHttpMessageConverter).write(eq("Foo"), eq(TEXT_PLAIN), isA(HttpOutputMessage.class));
}
@Override
@SuppressWarnings("unchecked")
public void write(MultiValueMap<String, ?> map, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if (!isMultipart(map, contentType)) {
writeForm((MultiValueMap<String, Object>) map, contentType, outputMessage);
}
else {
writeMultipart((MultiValueMap<String, Object>) map, outputMessage);
}
}
@Test
public void testSwagger() throws HttpMessageNotWritableException, IOException{
Json value = new Json("{\"swagger\":\"2.0\"");
HttpOutputMessage outMessage = new MockHttpOutputMessage(){
@Override
public HttpHeaders getHeaders() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return httpHeaders;
}
};
new FastJsonHttpMessageConverter().write(value, null, outMessage);
Assert.assertTrue((outMessage.getBody().toString().startsWith("{\"swagger\":\"2.0\"")));
}
/**
* ⑤
*/
@Override
protected void writeInternal(DemoObj obj, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
String out = "hello:" + obj.getId() + "-"+ obj.getName();
outputMessage.getBody().write(out.getBytes());
}