Проблемы с загрузкой изображения в HDFS через API REST webHDFS
Я делаю HttpPut с MultiPartEntity для записи файла в HDFS через API REST webHDFS. Сам запрос проходит и дает мне правильные ответы, 307 и 201. Однако у изображения есть составные заголовки, также написанные как часть его, как показано ниже, и это недопустимое изображение для извлечения и открытия.
--8DkJ3RkUHahEaNE9Ktw8NC1TFOqegjfA9Ps
Content-Disposition: форма-данные; Name="файл"; имя файла ="advert.jpg"
Тип контента: приложение / октет-поток
ÿØÿàJFIFHHÿÛC
// Остальная часть содержимого изображения
--8DkJ3RkUHahEaNE9Ktw8NC1TFOqegjfA9Ps
Удаление многокомпонентных заголовков из файла изображения делает его допустимым изображением, но я не уверен, как с самого начала этого избежать. Я даже не уверен, имею ли я контроль над этим, так как webHDFS ответственна за фактическую запись файла.
Вот мой код для этого. Есть ли что-то еще, что я должен делать?
final String LOCATION = "Location";
final String writeURI = "http://<ip>:50070/webhdfs/v1/user/hadoop/advert.jpg";
HttpPut put = new HttpPut(writeURI);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(put);
put.releaseConnection();
String redirectUri = null;
Header[] headers = response.getAllHeaders();
for(Header header : headers)
{
if(LOCATION.equalsIgnoreCase(header.getName()))
{
redirectUri = header.getValue();
}
}
HttpPut realPut = new HttpPut(redirectUri);
realPut.setEntity(buildMultiPartEntity("advert.jpg"));
HttpResponse response2 = client.execute(realPut);
private HttpEntity buildMultiPartEntity(String fileName)
{
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file", new FileBody(new File(fileName)));
return multipartEntity.build();
}
Любая помощь приветствуется.
3 ответа
Добавьте изображение как FileEntity, ByteArrayEntity или InputStreamEntity с Content-Type "application/octet-stream".
Я встречал ту же проблему с запросами Python. Наконец, я решил прочитать изображение в память перед отправкой. И используя один шаг вызова API Webhdfs вместо двух. Надеюсь, это может быть немного полезно.
host_url = current_app.config.get('HDFS_URL', '')
adx_img_path = current_app.config.get('ADX_CUSTOMER_IMAGE', '')
real_path = adx_img_path + remotefile
hdfs_username = current_app.config.get('HDFS_USERNAME', 'xdisk')
parameters = '?user.name=' + hdfs_username + '&op=CREATE&data=true'
img = open(localfile, 'rb').read()
url = host_url + real_path + parameters
r = requests.put(url, data=img, headers={"Content-Type": "application/octet-stream"})
Кажется, что при чтении изображения как двоичного / байтового, странные заголовки не будут добавлены в заголовок файла. Для HttpClient, который вы используете, я бы посоветовал вам попробовать InputStreamBody
или же ByteArrayBody
,
Это код, который работал для меня на основе принятого ответа:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.File;
import java.io.IOException;
public class Test {
public void Test(){
try {
final String writeURI = "http://<IP>:50075/webhdfs/v1/user/sample.xml?op=CREATE&user.name=istvan&namenoderpcaddress=quickstart.cloudera:8020&overwrite=true";
HttpClient client = HttpClientBuilder.create().build();
HttpPut put = new HttpPut(writeURI);
put.setEntity(buildFileEntity("C:\\sample.xml"));
put.setHeader("Content-Type", "application/octet-stream");
HttpResponse response = client.execute(put);
System.out.println(response);
}catch(IOException e){
e.printStackTrace();
}
}
private static FileEntity buildFileEntity (String fileName)
{
FileEntity inputData = new FileEntity(new File(fileName));
return inputData;
}
public static void main(String[] args) {
new Test().Test();
}
}
Maven:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.1</version>
</dependency>