001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.http.converter;
018
019import java.io.ByteArrayOutputStream;
020import java.io.IOException;
021
022import org.springframework.http.HttpInputMessage;
023import org.springframework.http.HttpOutputMessage;
024import org.springframework.http.MediaType;
025import org.springframework.lang.Nullable;
026import org.springframework.util.StreamUtils;
027
028/**
029 * Implementation of {@link HttpMessageConverter} that can read and write byte arrays.
030 *
031 * <p>By default, this converter supports all media types (<code>&#42;/&#42;</code>), and
032 * writes with a {@code Content-Type} of {@code application/octet-stream}. This can be
033 * overridden by setting the {@link #setSupportedMediaTypes supportedMediaTypes} property.
034 *
035 * @author Arjen Poutsma
036 * @author Juergen Hoeller
037 * @since 3.0
038 */
039public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<byte[]> {
040
041        /**
042         * Create a new instance of the {@code ByteArrayHttpMessageConverter}.
043         */
044        public ByteArrayHttpMessageConverter() {
045                super(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL);
046        }
047
048
049        @Override
050        public boolean supports(Class<?> clazz) {
051                return byte[].class == clazz;
052        }
053
054        @Override
055        public byte[] readInternal(Class<? extends byte[]> clazz, HttpInputMessage inputMessage) throws IOException {
056                long contentLength = inputMessage.getHeaders().getContentLength();
057                ByteArrayOutputStream bos =
058                                new ByteArrayOutputStream(contentLength >= 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE);
059                StreamUtils.copy(inputMessage.getBody(), bos);
060                return bos.toByteArray();
061        }
062
063        @Override
064        protected Long getContentLength(byte[] bytes, @Nullable MediaType contentType) {
065                return (long) bytes.length;
066        }
067
068        @Override
069        protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {
070                StreamUtils.copy(bytes, outputMessage.getBody());
071        }
072
073}