这辈子没办法做太多事情,所以每一件都要做到精彩绝伦!
People can't do too many things in my life,so everything will be wonderful
项目使用技术SpringMVC + spring + mybatis
HttpClient技术
1 HttpClientService工具类
该工具类封装了get、post、put、delete以及post上传多个文件等方法;包含了有无参数。日常开发,够用了!
一般来说,有些公司会有自己独立的上传下载文件服务器;有些是单应用服务!以上这两种情况,暂用不到该方法。
本文重点讲解使用httpClient进行post请求多文件上传功能(底层是模拟表单提交)。
-
依赖包及版本
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.5</version>
</dependency>
-
方法代码:
//注入httpClient和requestConfig(spring集成httpClient配置)
@Autowired
privateCloseableHttpClient httpClient;
@Autowired
privateRequestConfig requestConfig;
/**
*
* @描述:httpCilent多图片上传和多个参数
* @创建人:wyait
* @创建时间:2017年5月2日 下午1:47:41
* @param url 请求url
* @param params 请求参数
* @param files file对象
* @return
* @throws IOException
*/
publicHttpResult postUploadFile(String url, Map<String, Object> params,
Map<String,File> files) throws IOException {
HttpPosthttpPost = new HttpPost(url);// 创建 HTTP POST 请求
httpPost.setConfig(this.requestConfig);
MultipartEntityBuilderbuilder = MultipartEntityBuilder.create();
builder.setCharset(Charset.forName("UTF-8"));//设置请求的编码格式
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
//设置参数
if(files != null) {
//设置图片参数
for(Map.Entry<String, File> entry : files.entrySet()) {
builder.addBinaryBody(entry.getKey(),entry.getValue());
}
}
//设置参数
if(params != null) {
//设置post参数
for(Map.Entry<String, Object> entry : params.entrySet()) {
//指定编码,防止中文乱码问题。但是某些情况下会导致上传失败
builder.addTextBody(entry.getKey(),
String.valueOf(entry.getValue()),
ContentType.create("text/plain","UTF-8"));
}
}
//生成 HTTP POST 实体
HttpEntityentity = builder.build();
//设置请求参数
httpPost.setEntity(entity);
CloseableHttpResponseresponse = null;
try{
//执行请求
response= httpClient.execute(httpPost);
if(response.getEntity() != null) {
returnnew HttpResult(response.getStatusLine().getStatusCode(),
EntityUtils.toString(response.getEntity(),"UTF-8"));
}
returnnew HttpResult(response.getStatusLine().getStatusCode(),
null);
}finally {
if(response != null) {
response.close();
}
}
}
2 业务场景
现有A前台系统和B服务系统;业务流程:
JSP页面提交文件—>A系统(发送httpClient)—>B系统进行更新数据!
考虑的方案:
1,直接跳过A系统,jsp页面请求B更新数据;
2,A系统进行文件保存后,将路径带到B系统进行更新操作;
以上两种方案的问题点;
方案1,线上B服务,一般是内网服务,不对外开放;否则会有安全问题;
方案2,涉及分布式事务问题;
在网上也百度了很多方法,最终退而求其次,进行两次读写操作,更新数据!
3 实现流程
3.1 jsp页面上传文件
此处略
3.2 A系统处理文件
主要功能是:A系统接收文件,合法性校验后,对图片进行判断和压缩处理,生成一个临时文件;
对于对图片的判断处理这里就不做过多说明了。
重点说一下:
MultipartFile 转成 File对象实现(结合网上资料,总结出最佳实践):
Stringpath=”自定义”+MultipartFile. getOriginalFilename();
File newFile=new File(path);
//直接写文件到指定路径下
MultipartFile.transferTo(newFile);
3.3 调用httpCilent发送请求
主要功能是:调用httpClient已经封装好的postUploadFile(ur,params,files)方法,发送请求;
Map<String, File> files = new HashMap<String, File>();
files.put("newFile", newFile);
//发送请求,并对请求数据进行处理,params自定义
Obj 自定义=httpCilentService.postUploadFile(url, params, files);
3.4 B系统处理数据
B系统通过MultipartFile接收文件数据,并进行更新操作,返回结果;
-
接收文件:
-
保存文件:
// 新file
FilenewFile = new File(newFile);
//写文件到磁盘
newPic.transferTo(newFile);
3.5 A系统回调处理数据
A系统在调用B系统后,无论结果ok,还是fail。都删除临时图片;
将该段代码写在finally代码块中:
boolean flag = new File(path).delete();
if(!flag) {
//删除原始图片失败
return"删除临时图片失败,请稍后再试";
}
最后,返回结果到jsp页面
关于HttpClient工具类最好链接:http://blog.csdn.net/column/details/httpclient-arron.html