Я пришел к выводу, что знание этого указывает на недостаток знаний о том, как работают REST-подобные API-интерфейсы, и если кто-то может дать мне ссылку, где я могу узнать историю вопроса, я был бы признателен.В то же время, я также был бы признателен за помощь в ответе на этот вопрос!
У меня есть Java-приложение, которое отправляет файлы из локальной файловой системы в API.Моя цель состоит в том, чтобы вместо того, чтобы миллионы файлов сидели на томе со всеми их файловыми дескрипторами, я хочу оставить файлы в файле .tar.gz, а затем в памяти вытащить их из архива и отправить их без записина диск.Я знаю, что могу записать их на диск, POST их, а затем удалить их, но я рассматриваю этот вариант как последнее средство.
Итак, вот код, который работает для POST файла, который существует в файловой системе,отсутствует в архиве
public CloseableHttpResponse submit (File file) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(API_LOCATION + API_BASE);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("files", file, ContentType.APPLICATION_OCTET_STREAM, null);
HttpEntity multipartEntity = builder.build();
post.setEntity(multipartEntity);
CloseableHttpResponse response = client.execute(post);
System.out.println("response: " + IOUtils.toString(response.getEntity().getContent(),"UTF-8"));
client.close();
return response;
}
Я получаю ответ JSON от моего конкретного API, который выглядит следующим образом
response: {"data":[<bunch of json>]}
Я поместил этот же файл в архив .tar.gz.и я использовал сжатие Apache Commons для распаковки файла и извлечения каждого файла как TarArchiveEntry, и я проверил, что он работает правильно, записав текстовый файл на диск и открыв его вручную вне Java - я определенно получаю запись впамять правильно.Я попытался изменить сущность, присоединенную к POST, на ByteArrayEntity и преобразовать запись архива в поток байтов, но API настаивает, что он будет принимать только составную сущность.Итак, глядя на API для MultipartEntityBuilder.addBinaryBody, я обнаружил, что у меня осталось две опции: я могу опубликовать байтовый массив или InputStream.Я пробовал оба, и я не могу заставить их работать - я опубликую свой пример кода для подхода байтового массива, но я не могу понять, как преобразовать архив tar в InputStream - по крайней мере, без преобразованиясначала к байтовому массиву, который в этот момент кажется довольно глупым.
public CloseableHttpResponse submit (byte[] xmlBytes) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(API_LOCATION + API_BASE);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("files", xmlBytes, ContentType.APPLICATION_OCTET_STREAM, null);
HttpEntity multipartEntity = builder.build();
post.setEntity(multipartEntity);
CloseableHttpResponse response = client.execute(post);
System.out.println("response: " + IOUtils.toString(response.getEntity().getContent(),"UTF-8"));
System.out.println(response.getStatusLine().getStatusCode());
client.close();
return response;
}
Я считаю, что код идентичен, за исключением типа данных входного параметра.Вот мой пустой ответ, который приходит с кодом состояния 207:
response: {"data":[]}
Итак, вот мой реальный вопрос: может ли любой API, принимающий файлы, также принимать файл в виде байтового потока или байтового массива?Может ли API определить разницу и что на самом деле происходит, когда я размещаю файл?Должен ли API быть специально настроен для приема этого файла в виде байтового потока или байтового массива?Ссылка на ссылку вместе с кратким объяснением была бы очень признательна - мне действительно нужно изучить этот материал и хорошо его понять.
Есть ли какая-то легкая ошибка, которую я делаю?Я использую неправильный Content-Type или что-то?Я даже не уверен, что означает третий аргумент MultipartEntityBuilder.build (тот, который я оставил нулевым).
Любая помощь приветствуется, большое спасибо!