使用httpClient同时推送文件和参数

使用httpClient同时推送文件和参数

今天收到一个需求是将我们系统的数据同步到另一个系统中使用,主要就是一个更新数据时的推送,这里使用httpClient进行数据推送,废话不说上代码

@RequestMapping(value = "sendData", method = RequestMethod.POST)
	@ResponseBody
	public Result sendData2(@RequestParam Map datas,String type,MultipartFile file){
		Result result = new Result();
		try {
			  MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
			  builder.setCharset(Charset.forName("UTF-8"));
			  
			  String fileName = file.getOriginalFilename();
			  
			  MultipartFile multipartFile = 
		      new MockMultipartFile(fileName,fileName, null, file.getInputStream());
			  
			  System.out.println(fileName);
			  System.out.println(multipartFile.getOriginalFilename());
			  
			  builder.addBinaryBody("upLoadImage", multipartFile.getInputStream(), ContentType.DEFAULT_BINARY, multipartFile.getOriginalFilename());
			  ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));
			  builder.addTextBody("protocolNum",datas.get("protocolNum"),contentType);
		      builder.addTextBody("testCategory",datas.get("testCategory"),contentType);
		      builder.addTextBody("troopCategory",datas.get("troopCategory"),contentType);
		      builder.addTextBody("developOrg",datas.get("developOrg"),contentType);
		      builder.addTextBody("detailSpecificationNo",datas.get("detailSpecificationNo"),contentType);
		      builder.addTextBody("detailSpecificationName",datas.get("detailSpecificationName"),contentType);
		      builder.addTextBody("productModel",datas.get("productModel"),contentType);
		      builder.addTextBody("productName",datas.get("productName"),contentType);
		      builder.addTextBody("recordNo",datas.get("recordNo"),contentType);
		      builder.addTextBody("planTestOrg",datas.get("planTestOrg"),contentType);
			  
			  HttpEntity httpEntity = builder.build();
			  
			  
			  //提交
			  HttpUriRequest request = RequestBuilder.post(datas.get("url")).setEntity(httpEntity).build();
			  CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			  CloseableHttpResponse response = httpClient.execute(request);
			  if(response.getStatusLine().getStatusCode() == 200) {
				  result.setCode("200");
				  result.setMessage("上传成功");
			  }else {
				  
				  result.setCode(response.getStatusLine().getStatusCode()+"");
				  result.setMessage("上传失败");
			  }
			  //添加到日志中
			  Log log = new Log(0, "状态:"+response.getStatusLine().getStatusCode(), 1, new Date(), "手动上传单条数据", datas.toString(), "");
			  logService.addLog(log);
			  return result;
		  }catch(Exception e) {
			  result.setMessage(e.toString());
			  return result;
		  }
		  
	 }

代码很简单也是记录下方便以后查看
有几个联调中的问题记录一下,希望能帮到遇到同样问题的人
1,接收方无法获取到文件的真实名称,在linux服务器中导致错误
new MockMultipartFile(fileName,fileName, null, file.getInputStream());此处的fileName不能用
file.getName,不知怎么回事MultipartFile这个对象的getName只能获取到file这个字符串。。。跟File对象不一样,所以要用getOriginalFilename才能获取文件的原始名称及后缀。
2,添加参数时必须加入contentType,否则中文乱码,而传文件不用
ContentType contentType = ContentType.create(“text/plain”, Charset.forName(“UTF-8”));
builder.addTextBody(“protocolNum”,datas.get(“protocolNum”),contentType);
3,MultipartFile multipartFile = new MockMultipartFile(fileName,fileName, null, file.getInputStream());
这个方法的第三个参数就是contentType,可以为null,写其他应该也没错就是了
其他补充
上传list参数的代码块也放出来吧,我的思路还是传json串,因为NameAndValue这个参数接收方无法接收到。。。也是无语

List> list = stdDao.getApp();//这个就是你自己从数据库获取的数据了,也就是要传的数据
	    	JSONArray json = JSONArray.fromObject(list); 
	    	StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");
	    	httpPost.setEntity(stringEntity);

把接收端的代码也放出来
第一个是接收文件和一个对象,注意是一个对象不是list,数据是存在request里面的

@RequestMapping(value = "getData", method = RequestMethod.POST)
    @ResponseBody
    public Map getData(HttpServletRequest request, MultipartFile upLoadImage){
        Map map = request.getParameterMap();
        String[] strs = map.get("protocolNum");
        for(String str:strs) {
            System.out.print(str);
        }
        File dest = new File("E:\\"+upLoadImage.getOriginalFilename());
        try {
            upLoadImage.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.print(upLoadImage);
        Map result = new HashMap<>();
        result.put("code", "200");
        result.put("message", "成功");
        return result;
    }

第二个负责接收集合
如代码可知需要用requestEntity接收
@RequestMapping(value = “getAllData”, method = RequestMethod.POST)
@ResponseBody
public Map getAllData(HttpEntity requestEntity, HttpServletRequest request){
Map maps = request.getParameterMap();
String[] strs = maps.get(“standardCategory”);
for(String str:strs) {
System.out.print(str);
}
Map result = new HashMap<>();
result.put(“code”, “200”);
result.put(“message”, “成功”);
return result;
}

最后,把用到的jar包列出来方便大家实际运用,这个很关键,我当时找jar包找了好久。。。

 		
        
            org.apache.httpcomponents
            httpclient
            4.5.10
        

        
        
            org.apache.httpcomponents
            httpmime
            4.5.10
        
        
		
		
		    org.springframework
		    spring-mock
		    2.0.8
		

第一个包是httpClient不用多说
第二个包是MultipartEntityBuilder等工具类的包
第三个包是MockMultipartFile的包

查了很久百度也没找到能同时传list和文件的方法,正常按照逻辑的话也是,数据和文件就对不上了。。所以还是反复调用接口达到目的。

你可能感兴趣的:(java,spring,java,spring,http)