所以我遇到了一个需要通过java应用程序发布bzip2文件的问题。我在执行多部分帖子或使用常规文件时没有问题(请参阅http://zewaren.net/site/?q=node/123上的第三个示例)
但是,上面的示例假设您将文件内容作为字符串发送,我只是发送压缩内容(字节数组)。
public void postSegments(HttpsURLConnection connection, File segment) throws UnsupportedEncodingException, IOException {
PrintWriter OutputStream = null;
try {
OutputStream = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"), true);
OutputStream.append(BOUNDARY_SPLIT).append(BOUNDARY).append("\r\n");
OutputStream.append("Content-Disposition: form-data; name=\"").append("metadata").append("\"").append("\r\n");
OutputStream.append("Content-Type: ").append("application/json; charset=UTF-8").append("\r\n").append("\r\n");
OutputStream.append(META_JSON).append("\r\n");
OutputStream.append(BOUNDARY_SPLIT).append(BOUNDARY).append("\r\n");
OutputStream.append("Content-Disposition: form-data; name=\"data\"; filename=\"NAME\"").append("\r\n");
OutputStream.append("Content-Type: ").append("application/octet-stream; charset=UTF-8").append("\r\n").append("\r\n");
OutputStream.append(fileService.readFile(segment));
OutputStream.append(BOUNDARY_SPLIT).append(BOUNDARY).append(BOUNDARY_SPLIT).append("\r\n");
}
finally {
if (OutputStream != null) {
OutputStream.close();
}
}
在上面的代码中,我尝试使用通用文件扫描程序读取段文件时遇到错误(这不适用于段是bzip2文件)
我一直在寻找一个好的包装器来轻松处理发送这些处理大/压缩文件的多部分请求,但我还没有成功。
提前谢谢大家。
答案 0 :(得分:0)
所以我没有成功使用httpsUrlConnection发布文件。我无法找到原因,我认为这是我声明的标题问题。
但是,我确实设法使用Jersey编写了一些基本的处理程序,以及apache组件。
泽西客户端在Oauth中有自己的构建,而apache客户端使用oauth-signpost插件。
注意:这些示例可以发布由文件和json组成的multipart / form-data。其他输入相当容易实现。它也使用Oauth,而不是Oauth2,它需要不同的库和处理方式(即令牌刷新)
以下是Jersey实施。我不建议在大文件上使用它,因为你将整个文件存储在内存中...你可以将其分解成块并发送它,但我没有这样做,因为我发现apache版本更适合根据我的需要。无论如何,这是代码:
import java.io.ByteArrayInputStream;
import java.io.File;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Providers;
import org.apache.log4j.Logger;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.impl.MultiPartWriter;
import com.sun.jersey.oauth.client.OAuthClientFilter;
import com.sun.jersey.oauth.signature.OAuthParameters;
import com.sun.jersey.oauth.signature.OAuthSecrets;
public class OauthRequestJersey {
private static final Logger log = Logger.getLogger(OauthRequestJersey.class);
private Client client = null;
private FileServiceUtil fileService = new FileServiceUtil();
private FormDataMultiPart multiPart;
private WebResource resource;
/*
* Oauth Request Wrapper constructor
*/
public OauthRequestJersey(String url, String oAuthConsumerKey, String oAuthConsumerSecret){
init();
Providers providers = this.client.getProviders();
OAuthSecrets secrets = new OAuthSecrets().consumerSecret(oAuthConsumerSecret);
OAuthParameters params = new OAuthParameters().consumerKey(oAuthConsumerKey).signatureMethod("HMAC-SHA1");
OAuthClientFilter filter = new OAuthClientFilter(providers,params,secrets);
resource = client.resource(url);
resource.addFilter(filter);
}
private void init(){
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(MultiPartWriter.class);
multiPart = new FormDataMultiPart();
client = com.sun.jersey.api.client.Client.create(config);
}
public void addJsonPart(String name, String json){
multiPart.field(name, json, MediaType.APPLICATION_JSON_TYPE);
}
public void addFilePart(String name, File file){
byte[] data = fileService.fileToByteArray(file);
FormDataBodyPart fdbp = new FormDataBodyPart(
FormDataContentDisposition.name(name)
.fileName(file.getName()).build(),
new ByteArrayInputStream(data),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
multiPart.bodyPart(fdbp);
}
public ClientResponse finish(){
ClientResponse response = null;
response = resource.type(MediaType.MULTIPART_FORM_DATA)
.post(ClientResponse.class,multiPart);
log.debug("Response for the call " + response);
log.debug("Response for the call status " + response.getStatus());
return response;
}
}
Maven for jersey:
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.oauth</groupId>
<artifactId>oauth-signature</artifactId>
<version>1.1.1-ea</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.oauth</groupId>
<artifactId>oauth-client</artifactId>
<version>1.1.1-ea</version>
</dependency>
下面是我的apache实现。这是我首选的方法,因为它自己处理文件流并抽象标题,而不必自己手工制作它们!您会注意到我添加了一些逻辑来处理get请求。
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;
public class OauthRequestApache {
private static final Logger log = Logger.getLogger(OauthRequestApache.class);
private static CloseableHttpClient client;
private static boolean isPost;
private static HttpPost postRequest;
private static HttpGet getRequest;
private static MultipartEntityBuilder builder;
public OauthRequestApache(String requestURL, String consumerKey, String consumerSecret, boolean post) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException{
isPost = post;
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);
if(isPost){
postRequest = new HttpPost(requestURL);
builder = MultipartEntityBuilder.create();
consumer.sign(postRequest);
}else{
getRequest = new HttpGet(requestURL);
consumer.sign(getRequest);
}
client = HttpClients.createDefault();
}
public void addJsonPart(String name, String value){
builder.addTextBody(name, value, ContentType.APPLICATION_JSON);
}
public void addFilePart(String name, File file){
builder.addBinaryBody(name, file);
}
public List<String> finish() throws ClientProtocolException, IOException{
HttpResponse response;
List<String> status = new ArrayList<String>();
ResponseHandler<String> handler = new BasicResponseHandler();
if(isPost){
HttpEntity multipart = builder.build();
postRequest.setEntity(multipart);
response = client.execute(postRequest);
}else{
response = client.execute(getRequest);
}
String body = handler.handleResponse(response);
status.add(Integer.toString(response.getStatusLine().getStatusCode()));
status.add(body);
client.close();
return status;
}
}
maven for apache
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-core</artifactId>
</dependency>
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-commonshttp4</artifactId>
<version>1.2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.6</version>
</dependency>