资讯专栏INFORMATION COLUMN

后端接收前端上传的文件,构造post请求,调用上传文件的外部接口

Panda / 1936人阅读

摘要:由后端来发送请求来调用这些接口。是中用来传递文件对象而定义的。中设置如下中设置上传文件的大小单个文件可上传的最大整个请求的最大还包括等内容

本文概述:
可能会存在一些需求,一些部署在内部的或者多带带一个环境的服务,提供rest服务。由后端来发送http请求来调用这些接口。那在后端就需要构造http请求。本文要解决的场景如下:
前端multipartfile 上传文件,后端接收后构造post请求,调用外部接口,传送文件流及其他参数
内容包括:
1.前端postman调用上传接口
2.后端接收multipartfile文件
3.后端用httpclient构造post请求
4.调用外部接口后返回结果的处理

先上代码:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

/**
*前端上传文件,后端接收后构造post请求,调用外部文件上传接口
*/
@PostMapping(value = "uploadImage")
public void uploadImage(Model model, @RequestParam(value = "image") MultipartFile image, String label) {
    log.info("=============uploadImage  start=================");
    log.info("图像处理的标签"+label);
        Map data = new HashMap();
        log.info("开始post请求构造======");
        String url ="http://ip:port/mytest/fileup";//服务端要调用的外部接口
        Map resultMap = new HashMap();
        //httpclients构造post请求
        CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
            log.info("post请求的url"+url);
            HttpPost httpPost = new HttpPost(url);
            //HttpMultipartMode.RFC6532参数的设定是为避免文件名为中文时乱码
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            String originFileName = null;
            originFileName = image.getOriginalFilename();
            //    File file1 = new File("/home/temp/下载/1200-560.jpg"); //测试外部接口直接上传本地图片 
            builder.addBinaryBody("image", image.getBytes(), ContentType.MULTIPART_FORM_DATA, originFileName);// 设置上传文件流(需要是输出流),设置contentType的类型
            builder.addTextBody("label",label);//post请求中的其他参数
            //    log.info("上传图的标签label"+label);
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();//接收调用外部接口返回的内容
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//    String imageUrl = stringStringMap.get("data"); //    data.put("path",imageUrl);
            // 返回的内容都在content中
            InputStream content = responseEntity.getContent();
            byte[] bytes = toByteArray(content);
            //将byte数组进行base64编码,此例中调用外部接口返回的是图片流
            String encodeStr = Base64.getEncoder().encodeToString(bytes);
            model.addAttribute("data",encodeStr);
        }
    } catch (Exception e) {
        model.addAttribute("code", "错误码");
        model.addAttribute("message","错误的提示信息");
    }finally {//处理结束后关闭httpclient的链接
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

}


/**
 *将输入流转换为输出流,无需创建临时文件
 * @param input
 * @return
 * @throws IOException
 */
public byte[] toByteArray(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    copy(input, output);
    return output.toByteArray();
}

postman调用接口如下

可能存在的坑:
1.确保后端部署的网络与所调用的外部接口网络是通的
2.后端接收multipartfile文件后若不需处理就调用外部接口的话,可不用生成临时文件。可直接使用multipartfile对象自带的方法,获取byte流
3.构造的post请求,若涉及到文件的上传,要设置正确的contentType,如上文代码中所示
4.构造的post请求中,addBinaryBody()中传递的可以是一个file对象,也可以是流。【若是流则需是输出流】
5.byte数组转换为base64字符串,详情见上文代码备注部分
6.将输入流转换为输出流,不需要写临时文件,见上文代码

multipartfile对象与file的区别:
multipartfile是个接口,通常所说的multipartfile是在springmvc中设置过的。是springmvc中用来传递文件对象而定义的。该接口包括如下方法

        byte[] bytes = multipartFile.getBytes();//获取multipartfile对象的byte数组,可转换文件流等
        String contentType = multipartFile.getContentType();//获取multipartfile的头类型
        InputStream inputStream = multipartFile.getInputStream();//获取输入流
        String name = multipartFile.getName();//获取文件名
        String originalFilename = multipartFile.getOriginalFilename();//获取初始文件名
        long size = multipartFile.getSize();//获取文件大小
        boolean empty = multipartFile.isEmpty();//判断对象内容是否是空
        multipartFile.transferTo(new File("文件路径"));//指定一个文件路径,可将multipartfile对象中的内容写入文件。若需要转换为file对象,需要创建一个临时文件

MultipartFile是个接口,file可以通过设置CommonsMultipartFile对象的属性来进行转换。

springmvc中设置如下:



springboot中设置上传文件的大小:
spring.http.multipart.maxFileSize=50Mb //单个文件可上传的最大size
spring.http.multipart.maxRequestSize=1000Mb //整个请求的最大size(还包括header等内容)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75779.html

相关文章

  • 浅析前端上传

    摘要:项目上也用到很多上传文件的地方,七牛云,阿里云,讯飞上传都接触过,所以在这里做一个记录,总结一下前端上传的几种方式。类型的文件名七牛云上传浅析是一个基于七牛开发的前端。 showImg(https://segmentfault.com/img/bVbvibu?w=1920&h=1080); 图片,音频,视频等等这几种常见的资源类型,如果需要从前端上传到服务端,有几种方式呢?不妨回顾一下...

    terro 评论0 收藏0
  • WEB之常见工作问题总结(1-20)

    摘要:第三种,使用格式,即在中请求参数处理跨域问题当然请求方式只能是。最后发现有网友说版本不稳定引起的,于是把百度地图回退到了,结果还真是可以了。请问在移动端页面中播放优酷里面的视频,怎样实现 1.web扫码登录怎么实现,思路 步骤 WEB平台 手机 第1步 生成二维码 第2步 (ajax监控后台) 扫码 第3步 ...

    genedna 评论0 收藏0
  • 程序员鱼皮 表情包网站项目学习

    摘要:我们可以来看看数据库这个字段就是判断我们的这条数据是否是有效的,表示这条数据是有效的,表示这条数据是无效的。 ? 技术栈 后端 Java 8开发框架:SpringB...

    Yangder 评论0 收藏0
  • axios发送post请求,request.getParamter接收不到

    摘要:场景如下前端使用向后台发了一个为的请求,后台接口如下发现接收不到的信息。改为也一样接收不到。表单请求提交时,使用的是,而使用原生的请求如果不指定请求头,默认使用的是。 场景如下:前端vue使用axios向后台发了一个Content-type为application/json的post请求,后台springmvc接口如下: @RequestMapping(xxx) public Resu...

    Awbeci 评论0 收藏0
  • iMap | 一款基于 Electron 和 Vue 跨平台旅行地图生成器

    摘要:请求错误请求代码封装与基本一致,只是将换成即可。关于的使用是个能把组件的共享状态抽取出来,当做一个全局单例模式进行管理。首先确保你的已经安装,运行来安装。 项目地址:https://huangxizhou.com/project/iMap 技术栈 Vue.js Vuex Axios Webpack Leancloud(express) Echarts Electron(electr...

    dingda 评论0 收藏0

发表评论

0条评论

Panda

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<