利用springmvc上传文件的各种坑 http编码类型为multipart/form-data

上传文件后端获取不到信息

今天遇到了一个bug,前端传递一个表单 里面包含了一个文件 和 一个 json字符串
在这里插入图片描述
ContentType 为 multipart/form-data 前端没啥问题
在这里插入图片描述
但是后端想获取请求参数shopStr的时候死活获取不到值。。。。
Controller的代码是按照视频敲的(有时候视频挺害人的)

public Map<String,Object> regeisterShop(HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //接收前端的json信息 保存着店铺的各种信息
        String json = RequestUtil.getStringValue(request,"shopStr");
        //利用jackson把json数据转化为entity对象
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try{
            shop = mapper.readValue(json, Shop.class);
        }catch (Exception e){
            map.put("success",false);
            map.put("error_msg",e.getMessage());
            return map;
        }
        CommonsMultipartFile shopImg = null;
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        if(commonsMultipartResolver.isMultipart(request)){
            MultipartHttpServletRequest multipartHttpServletRequest =
                    commonsMultipartResolver.resolveMultipart(request);
            shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
        }else{
            map.put("success",false);
            map.put("error_msg","上传图片不能为空");
            return map;
        }

遇到的坑如下

  1. 在网上查了要添加依赖的jar包才可以解析这种类型的请求,于是添加了comons-fileupload,并且配置了springmvc的multipartresolver。成功获取了字符串类型的参数,但是文件为null了。。。。。。
  2. 如果去掉配置的multipartresolver 就不能获取到shopStr这个请求参数

解决办法

首先,我去查了网上的资料,发现这种类型的表单不能通过request.getparameter的方式来获取这样的请求
在这里插入图片描述
这种请求的编码类型为 multipart/form-data 它需要一些辅助的组件才能解析。
一种是利用apache的commons-fileupload组件解析
一种是利用servlet3.0及其以上版本的容器内置支持来解析

这里我们选择第一种方式

springmvc中上传代码的编写

编写springmvc的上传文件又面临两种方式,

  1. 第一个是在配置文件中配置multipartresolver,但是代码跟第二个方法不同
  2. 第二个是不用配置multipartresolver,由我们自己将request转换
第一种配置multipartResolver

首先配置文件中配置multipartResolver

<!--文件上传解析器-->
    <bean id="multipartResolver"
       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="2000000" />
        <property name="defaultEncoding" value="utf-8"/>
        <property name="resolveLazily" value="true"/>
    </bean>

Controller写法

public Map<String, Object> regeisterShop(
            @RequestParam(value="shopImg",required = false) MultipartFile shopImg,
            @RequestParam(value = "shopStr",required = false) String shopStr
    ) {
        Map<String, Object> map = new HashMap<>();
        //利用jackson把json数据转化为entity对象
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try {
            shop = mapper.readValue(shopStr, Shop.class);
        } catch (Exception e) {
            map.put("success", false);
            map.put("error_msg", e.getMessage());
            return map;
        }
        if (shopImg == null) {
            map.put("success", false);
            map.put("error_msg", "上传图片不能为空");
            return map;
        }

直接利用注解@RequestParam让框架帮咱们封装好

第二种不用配置multipartResolver
public Map<String,Object> regeisterShop(HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        CommonsMultipartFile shopImg = null;
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        if(commonsMultipartResolver.isMultipart(request)){
            MultipartHttpServletRequest multipartHttpServletRequest =
                    commonsMultipartResolver.resolveMultipart(request);
            shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
        }else{
            map.put("success",false);
            map.put("error_msg","上传图片不能为空");
            return map;
        }
        String shopStr = multipartHttpServletRequest.getParameter("shopStr");

原理 用resolver检测request是否为multipart的,然后把request转换为MultipartHttpServletRequest,在利用转换后的request获取请求参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值