2014-04-23 183 views
1

我正在使用MultiPartEntity的HttpPut通过webHDFS REST API将文件写入HDFS。请求本身经过并给出了正确的响应,307和201.但是,图像具有多部分头文件,如下所示,它也被写入为其一部分,并且它不是检索和打开的有效图像。通过webHDFS将图像上传到HDFS的问题REST API

--8DkJ3RkUHahEaNE9Ktw8NC1TFOqegjfA9Ps
内容处置:形状数据; 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(); 
}  

任何帮助表示赞赏。

回答

1

使用Content-Type“application/octet-stream”将图像添加为FileEntity,ByteArrayEntity或InputStreamEntity。

1

我遇到了与python请求相同的问题。我最终解决它的方法是在发送出去之前将图像读入内存。并使用一个步骤调用webhdfs api而不是两个。希望这可以有点帮助。

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,我建议你试试InputStreamBodyByteArrayBody

+0

我用ByteArrayEntity来解决它。它也适用于InputStreamEntity和FileEntity。 –

0

这是为我工作的基础上公认的答案代码:

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>