好久好久没写博客了,记一次不留意的惨痛教训,白白浪费一整个下午的时间。

1. 问题描述:

前端是iview+vue写的页面(这个不重要,都一样),然后引入了上传附件的这么一个功能,正常上传附件是可以的,当不选择任何文件的时候,点击保存直接报错,前台没有任何报错,方法也都走了,确定走到了后台但是后台没有任何反应,不仔细看也没有任何反应,经东东同事提醒,发现控制台有1行报错信息,还是正常的文本样色,不注意一定看不到,我就是这么忽略了,导致走了很多弯路。

2. 报错信息:

2020-02-28 19:46:00.383  WARN 1320 --- [nio-9906-exec-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by handler execution: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'zkdgwhEntity' on field 'kcdgFile': rejected value [[object Object]]; codes [typeMismatch.zkdgwhEntity.kcdgFile,typeMismatch.kcdgFile,typeMismatch.org.springframework.web.multipart.MultipartFile,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [zkdgwhEntity.kcdgFile,kcdgFile]; arguments []; default message [kcdgFile]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile' for property 'kcdgFile'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile' for property 'kcdgFile': no matching editors or conversion strategy found]

3. 走过的弯路:

因为没有看到后台报的错误,就一直在前台找错误,查找netWork的header参数、给js打断点、console输出、json格式化都试过了,数据都没有问题,都可以获取到, 参数也都正确。

在其中发现了另一个问题,就是如果你的表单是上传的附件文件,因为他是byte格式的二进制流数据,所以,表单的提交万万不能使用 json 的数据格式往后台传数据,否则到了后台你接收到了是一个String类型的数据,毫无意义,上传会失败。

4. 本人本次具体原因:

本人因为赶工期,又是刚上手的新框,来不及学习,处处碰钉子,实际具体的原因是因为在实体类里面我建立了跟controller方法参数里面一样的接收参数,导致controller接收的时候接收不到,在entity实体类里面就已经被拦截了还没有走到controller方法的第一行代码,所以实际看上去就是代码走丢了。

实际方法的过程“应该”是这样的:从前端的代码跳往后太的时候,先寻找当前方法,然后注入方法的每个参数对象的具体值。然后在走到controller方法的参数中的实体类的时候,因为实体类里面有 MultipartFile 类型的试题,然后我前台又没有选择文件,而 MultipartFile 默认是不允许为空的,而我在controller方法里面也写了同样的 MultipartFile 类型的参数来接收,导致我漏掉了实体类里面的参数。

这么一个粗心的写法,让我浪费了大半天的时间,实在是,,,

特此记录一下。

5. 解决方式及实例代码:

你要使用  const formdata = new FormData(); 的form表单提交,后台使用post方式接收才可以,

前端代码:

const formdata = new FormData();
formdata.append("dgid",self.saveform.dgid);
if(self.file !== null){
    formdata.append("kcdgFile", self.file);
};
$.ajax({
    type: "POST",
    url: baseUrl + 'zkdgwh/saveZkdgwhObj',
    cache: false,
    data: formdata,
    processData: false,
    contentType: false
}).done(function(res) {
    if(res.code == 200){
        self.$Message.success({
            background: true,
            duration: 5,
            content: "保存成功"
        });
        setTimeout(function () {
            window.location.href=baseUrl + 'zkdgwh/queryZkdgList';
        },1600);
    }else{
        self.$Message.error({
            background: true,
            duration: 5,
            content: "保存失败"
        });
    }
}).fail(function(res) {
    self.$Message.error({
        background: true,
        duration: 5,
        content: "服务器繁忙"
    });
});

后端接收代码:

首先删除实体类里面的 MultipartFile 类型的字段值。

post表单方式提交数据:method = RequestMethod.POST

可控制是否必填的附件接收方式:@RequestParam(value="kcdgFile" ,required=false) MultipartFile kcdgFile

@RequestMapping(value = "saveZkdgwhObj" , method = RequestMethod.POST)
public ReturnT<String> saveZkdgwhObj(HttpServletRequest request, ZkdgwhEntity zkdgwhEnt,
        @RequestParam(value="kcdgFile" ,required=false) MultipartFile kcdgFile){
    try {
        return zkdgwhService.saveZkdgwhObj(zkdgwhEnt,kcdgFile);
    }catch (Exception e){
        e.printStackTrace();
        return ReturnT.FAIL;
    }
}

一般这样的解决方式就可以解决问题了:

https://blog.csdn.net/qq_34902590/article/details/86718734?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

Logo

前往低代码交流专区

更多推荐