图片上传流CloseableHttpClient 问题(血案)

一、起因

这段时间一直都在对接第三方平台数据,其中对方传输过来的图片有可能是外网url或者是base64。如果是一般的外网url还好,直接读取流,上传即可,如果是base64的话必须先得转为输出流。记录下base64直接转输入流的方法。

二、代码
  • base64转输入流
//base64字符串
String file = "XXXXXXXXXX";
//将字符串转换为byte数组
byte[] bytes = new BASE64Decoder().decodeBuffer(file.trim());
//转化为输入流
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
  • 根据输入流将图片上传到第三方接口(其中,sbbh字段为自定义表单上传参数,视对方接口而定,不一定要上传)
    public static String inputStreamUpload(InputStream inputStream, String url, String sbbh) {
        //创建HttpClient对象
        //CloseableHttpClient client = HttpClients.createDefault();
        HttpClient client= new DefaultHttpClient();
        //构建POST请求   请求地址请更换为自己的。
        //1)
        HttpPost post = new HttpPost(url);
        try {
            //文件路径请换成自己的
            //2)
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //第一个参数为 相当于 Form表单提交的file框的name值 第二个参数就是我们要发送的InputStream对象了
            //第三个参数是文件名 必须要文件名称 不然接口返回有问题
            builder.addBinaryBody("file", inputStream, ContentType.create("multipart/form-data"),"test.jpg");
            //4)构建请求参数 普通表单项(自定义,可不定义)
            StringBody stringBody = new StringBody(sbbh,ContentType.MULTIPART_FORM_DATA);
            builder.addPart("自定义请求参数",stringBody);
            HttpEntity entity = builder.build();
            post.setEntity(entity);
            //发送请求
            HttpResponse response = client.execute(post);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                return  EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            client.getConnectionManager().shutdown();
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
  • 根据在线图片url上传到第三方接口存储(其中,sbbh字段为自定义表单上传参数,视对方接口而定,不一定要上传)
    public static String inputStreamUpload(String picUrl, String uploadUrl, String sbbh) {
        //创建HttpClient对象
        //CloseableHttpClient client = HttpClients.createDefault();
        HttpClient client= new DefaultHttpClient();
        //构建POST请求   请求地址请更换为自己的。
        //1)
        HttpPost post = new HttpPost(uploadUrl);
        InputStream inputStream = null;
        try {
            // 创建URL
            URL url = new URL(picUrl);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            inputStream = conn.getInputStream();

            //文件路径请换成自己的
            //2)
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //第一个参数为 相当于 Form表单提交的file框的name值 第二个参数就是我们要发送的InputStream对象了
            //第三个参数是文件名 必须要文件名称 不然接口返回有问题
            builder.addBinaryBody("file", inputStream, ContentType.create("multipart/form-data"), "test.jpg");
            //4)构建请求参数 普通表单项
            StringBody stringBody = new StringBody(sbbh, ContentType.MULTIPART_FORM_DATA);
            builder.addPart("kkid", stringBody);
            HttpEntity entity = builder.build();
            post.setEntity(entity);
            //发送请求
            HttpResponse response = client.execute(post);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                return EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
三、关于bug血案

以上代码中,在创建httpClient中,之前使用的是CloseableHttpClient

CloseableHttpClient client = HttpClients.createDefault();

可是过了一段时间后发现这边报错

{   "timestamp": 1568649907795, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "org.springframework.web.multipart.MultipartException", 
    "message": "Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Invalid end of line sequence (character other than CR or LF found)", 
    "path": "/images"
}

奇怪的是postman测试正常,证明对方接口没问题,而且其他项目使用的是同一个方法上传也没问题,非常奇怪。后来只能将初始化方式改为现在这种,才恢复正常。

HttpClient client= new DefaultHttpClient();

过时的方法居然还可以!可以说非常疑惑了,求解~

你可能感兴趣的:(图片上传流CloseableHttpClient 问题(血案))