使用HttpClient实现接口传输multipart/form-data文件数据和文本数据

最近需求需要post接口发送给外部系统中数据,且包含pdf文件,由于之前系统中没有用到,这里记录下实现过程:

1、首先模板存储在资源服务器上,第一步取出附件这里不再赘述,下面代码是下载后的file附件首先要转成MultipartFile

进行传输,如下:

 private static MultipartFile getMulFileByPath(File file, String fieldName) {
        FileItem fileItem = createFileItem(file,fieldName);
        MultipartFile mfile = new CommonsMultipartFile(fileItem);
        return mfile;
    }


 private static FileItem createFileItem(File file, String fieldName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName());
        FileInputStream fis = null;
        OutputStream os = null;
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
             fis = new FileInputStream(file);
             os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
           Log.error("file转化出错createFileItem(File file, String fieldName)报错",e);
        }finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                Log.error("file转化出错createFileItem(File file, String fieldName)时io关闭出现错误");
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                Log.error("file转化出错createFileItem(File file, String fieldName)时io关闭出现错误");
            }
        }
        return item;
    }

2、

 

 /**
     * 使用HttpClient4.5 post提交multipart/form-data数据实现多文件上传
     * @param url 请求地址
     * @param multipartFile post提交的文件列表
     * @param fileParName fileKey
     * @param params 附带的文本参数
     * @param timeout 请求超时时间(毫秒)
     * @return
     */
 public String httpPostRequest(String url, MultipartFile multipartFile, String fileParName,
                                               Map params, int timeout) {
        
        Map resultMap = new HashMap();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(java.nio.charset.Charset.forName("UTF-8"));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
         

            builder.addBinaryBody(fileParName, multipartFile.getInputStream(), ContentType.MULTIPART_FORM_DATA, multipartFile.getOriginalFilename());// 文件流
            //决中文乱码
            ContentType contentType = ContentType.create("application/x-www-form-urlencoded", HTTP.UTF_8);
            for (Map.Entry entry : params.entrySet()) {
                if(entry.getValue() == null)
                    continue;
                // 类似浏览器表单提交,对应input的name和value
                builder.addTextBody(entry.getKey(), entry.getValue().toString(),contentType);
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
          
            // 设置连接超时时间
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
                    .setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            httpPost.setConfig(requestConfig);
            Long time = System.currentTimeMillis();
            // 执行提交
            HttpResponse response = simHttpCilentService.getSimHttpClient().execute(httpPost);
            Log.outSysLog("封装httpclient所需要的时间HttpMultipartFormdata.httpPostRequest" + (System.currentTimeMillis() - time) );
            HttpEntity responseEntity = response.getEntity();
            resultMap.put("scode", String.valueOf(response.getStatusLine().getStatusCode()));
            resultMap.put("data", "");
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, java.nio.charset.Charset.forName("UTF-8"));
                resultMap.put("data", result);
            }
        } catch (Exception e) {
            resultMap.put("scode", "error");
            resultMap.put("data", "HTTP请求出现异常: " + e.getMessage());

            Writer w = new StringWriter();
            e.printStackTrace(new PrintWriter(w));
           Log.error("HTTP请求出现异常: " + w.toString());
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

3、由于请求时https,这里要进行证书验证;

/**
     * 注意:
     * 这里返回的Executor是单例的,并且可以直接注入到其他类中去使用
     * @return
     */
    @SuppressWarnings("deprecation")
    public HttpClient getSimHttpClient(){
        Long time = System.currentTimeMillis();
        FileInputStream fisk = null;
        FileInputStream fist = null;
        HttpClient client = new DefaultHttpClient();
        try{
            fisk = new FileInputStream(keyStorePath);
            fist = new FileInputStream(trustStorePath);

            //CloseableHttpClient client = HttpClients.createDefault();
            SSLContext ctx = SSLContext.getInstance("TLS");
            System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(fisk, keyStorePwd.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
            kmf.init(ks, keyStorePwd.toCharArray());
            KeyStore ts = KeyStore.getInstance("jks");
            ts.load(fist, trustStorePwd.toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
            tmf.init(ts);
            ctx.init(kmf.getKeyManagers(), new TrustManager[] { tm }, null);
            org.apache.http.conn.ssl.SSLSocketFactory ssf = new org.apache.http.conn.ssl.SSLSocketFactory(ctx);
            //SSLConnectionSocketFactory sslsf =
            //         new SSLConnectionSocketFactory(sslcontext, null, null,
            //                 SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            ClientConnectionManager ccm = client.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", ssf, 443));
            client = new DefaultHttpClient(ccm, client.getParams());
            client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
                    soketTimeOut);
            Log.outSysLog("封装httpclient所需要的时间.getSimHttpClient" + (System.currentTimeMillis() - time) );

        }catch (Exception e){
            Log.error("获取证书通讯协议报错",e);
            throw new CommonsException(MessageCode.RSP_SYS_ERROR,"获取证书通讯协议报错",e);
        }finally {
            try {
                if (fisk != null) {
                    fisk.close();
                }
            } catch (IOException e) {
                Log.error("io关闭出现错误",e);
            }
            try {
                if (fist != null) {
                    fist.close();
                }

            } catch (IOException e) {
                Log.error("io关闭出现错误",e);
            }
        }
        return client;
    }

 

你可能感兴趣的:(httpClient,java后端)