一般我们做文件上传,都是在页面上传到服务器。有时候,我们在做系统的时候,我们需要将文件先上传到我们自己的服务器,然后通过server-to-server的方式上传文件到另一个服务器,如云存储服务器。java中利用httpclient可以实现get,post等http请求,但是如果需要上传文件,需要结合httpmime,将文件作为二进制流加入到post请求体中,这里介绍如何通过httpclient将文件上传到服务器上。
这里开启一个struts2的工程,里面有保存文件上传的方法,将该服务作为httpclient最终需要上传的服务器。关键代码:
package com.xxx.action;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
public class MainAction {
private File image;
private String imageFileName;
private String imageContentType;
public File getImage() {
return image;
}
public void setImage(File image) {
this.image = image;
}
public String getImageFileName() {
return imageFileName;
}
public void setImageFileName(String imageFileName) {
this.imageFileName = imageFileName;
}
public String getImageContentType() {
return imageContentType;
}
public void setImageContentType(String imageContentType) {
this.imageContentType = imageContentType;
}
public String uploadByJson() {
HttpServletRequest request = ServletActionContext.getRequest();
String checksum = request.getHeader("X-File-Checksum");
System.out.println(checksum);
String path = ServletActionContext.getServletContext().getRealPath("/uploads");
File target = new File(path,imageFileName);
try {
FileUtils.copyFile(image, target);
System.out.println("file -> path "+path);
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("{\"code\":200,\"status\":\"success\"}");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
我们来准备httpclient上传的工程,如果是maven工程,我们需要引入httpclient,httpmime两个主要的依赖库。我这里使用的是普通的项目,加入了commons-codec-1.4.jar,httpclient-4.4.1.jar,httpcore-4.4.1.jar,httpmime-4.4.1.jar。
核心的代码:HttpUtils.java
package com.xxx.http;
import java.io.File;
import java.io.IOException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
public class HttpUtils {
private static final String
URL_PREFIX_STRING="http://127.0.0.1:8080/struts2hack/main!uploadByJson.action";
//http
private static final PoolingHttpClientConnectionManager cm;
private static final CloseableHttpClient HTTP_CLIENT;
static{
cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(100);
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(1000)
.setSocketTimeout(2000)
.build();
HTTP_CLIENT = HttpClientBuilder.create()
.setConnectionManager(cm)
.setDefaultRequestConfig(config)
.build();
}
public static String upload(File file){
HttpPost post = new HttpPost(URL_PREFIX_STRING);
post.addHeader("X-File-Checksum", DigestUtils.md5Hex("123456"));
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.addPart("image", new FileBody(file));
entityBuilder.addPart("imageFileName", new StringBody(file.getName(),
ContentType.MULTIPART_FORM_DATA));
post.setEntity(entityBuilder.build());
String result = "";
try {
CloseableHttpResponse response = HTTP_CLIENT.execute(post);
HttpEntity entity = response.getEntity();
if(entity!=null){
result = EntityUtils.toString(entity, "UTF-8");
}
EntityUtils.consume(entity);
response.close();
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
String path = "C:\\Users\\Administrator\\downloads\\big_img.png";
File file = new File(path);
upload(file);
}
}
上传文件和普通的http请求不同的是,我们的文件要当做一种流的方式传输,而不是当作普通的参数传输,所以我们需要借助MulipartEntityBuilder提供的api,该api是在httpmime包中,所以仅仅是单独的httpclient无法完成这个工作,将文件文件加入到httppost的entity当中。 如果还带有别的参数,可以通过entityBuilder.addPart(paramName,paramValue)的方式增加,如本例中,struts2上传,需要传入imageFileName参数,我们就是通过entityBuilder.addPart("imageFileName", new StringBody(file.getName(),ContentType.MULTIPART_FORM_DATA))来添加的。
4528

被折叠的 条评论
为什么被折叠?



