001package io.freefair.spring.okhttp.client; 002 003import okhttp3.MediaType; 004import okhttp3.RequestBody; 005import okio.BufferedSink; 006import okio.Okio; 007import org.springframework.core.io.ByteArrayResource; 008import org.springframework.core.io.FileSystemResource; 009import org.springframework.core.io.InputStreamResource; 010import org.springframework.core.io.Resource; 011import org.springframework.lang.Nullable; 012import org.springframework.util.MimeType; 013 014import java.io.IOException; 015import java.io.InputStream; 016 017/** 018 * @author Lars Grefer 019 */ 020public class ResourceRequestBody extends RequestBody { 021 022 private final Resource resource; 023 024 @Nullable 025 private final MediaType mediaType; 026 027 public ResourceRequestBody(Resource resource) { 028 this.resource = resource; 029 this.mediaType = null; 030 } 031 032 public ResourceRequestBody(Resource resource, MimeType springMimeType) { 033 this.resource = resource; 034 this.mediaType = MediaType.parse(springMimeType.toString()); 035 } 036 037 public ResourceRequestBody(Resource resource, MediaType okhttpMediaType) { 038 this.resource = resource; 039 this.mediaType = okhttpMediaType; 040 } 041 042 @Override 043 @Nullable 044 public MediaType contentType() { 045 return mediaType; 046 } 047 048 @Override 049 public void writeTo(BufferedSink bufferedSink) throws IOException { 050 try (InputStream inputStream = resource.getInputStream()) { 051 bufferedSink.writeAll(Okio.source(inputStream)); 052 } 053 } 054 055 @Override 056 public long contentLength() throws IOException { 057 if (resource instanceof InputStreamResource && resource.getClass().equals(InputStreamResource.class)) { 058 return -1; 059 } 060 return resource.contentLength(); 061 } 062 063 @Override 064 public boolean isOneShot() { 065 if (resource instanceof InputStreamResource) { 066 return true; 067 } 068 069 if (resource instanceof ByteArrayResource) { 070 return false; 071 } 072 073 if (resource instanceof FileSystemResource) { 074 return false; 075 } 076 077 return super.isOneShot(); 078 } 079}