Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么在通过JSP将多部分文件映像作为字节[]上载到DB时,需要将BindingResult作为方法参数?_Java_Spring_Jsp_Jpa - Fatal编程技术网

Java 为什么在通过JSP将多部分文件映像作为字节[]上载到DB时,需要将BindingResult作为方法参数?

Java 为什么在通过JSP将多部分文件映像作为字节[]上载到DB时,需要将BindingResult作为方法参数?,java,spring,jsp,jpa,Java,Spring,Jsp,Jpa,我遇到了与之类似的问题,感谢那里的提示,我成功地让我的东西“工作”,然而,我很好奇为什么需要BindingResult?我注意到,当我将其作为方法参数添加时,添加图像是很好的,尽管我根本没有在方法体中使用bindingResult 然而,当我从参数中删除BindingResult时,我得到了400: 由于被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或将不会处理该请求 更有趣的是,该方法似乎甚至没有被调用,因为当我在那里放置断点时,调试器不会停止在

我遇到了与之类似的问题,感谢那里的提示,我成功地让我的东西“工作”,然而,我很好奇为什么需要
BindingResult
?我注意到,当我将其作为方法参数添加时,添加图像是很好的,尽管我根本没有在方法体中使用bindingResult

然而,当我从参数中删除
BindingResult
时,我得到了400:

由于被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或将不会处理该请求

更有趣的是,该方法似乎甚至没有被调用,因为当我在那里放置断点时,调试器不会停止在那里

我读了一点关于
BindingResult
(可能太少了),但这里的所有帖子都说这是用于验证目的的

起初我认为这可能与
MulitpartFile
作为
@RequestParam
连接,但我认为情况并非如此,至少不是完全如此。虽然,当我从
addProduct.jsp
更改enctype时,方法被调用而没有中断,但是,上传显然不起作用

总而言之,我让它工作了,但我想进一步了解它或得到一些提示,也许我不应该使用
byte[]
或以不同方式上传图像。这里有一个小代码

HomeController.java

@PostMapping("/admin/productInventory/addProduct")
public String addProductPost(@ModelAttribute("product") Product product, BindingResult bindingResult,
                             @RequestParam("imageFile") MultipartFile multipartImageFile) {

    try {
        if (multipartImageFile != null && !multipartImageFile.isEmpty())
            product.setImageFile(multipartImageFile.getBytes());
        productDAO.addProduct(product);
    } catch (IOException e){
        e.printStackTrace();
    }
    return "redirect:/admin/productInventory";
}
Product.java

@Entity
public class Product {
    ...

    @Lob
    private byte[] imageFile;

    @Transient
    private String base64EncodedImage;

    (Getters & Setters)
}
addProduct.jsp

    <form:form id="imageForm" action="${pageContext.request.contextPath}/admin/productInventory/addProduct"
               method="post" commandName="product" enctype="multipart/form-data">
   ...

    <div class="form-group">
        <label for="productImage" class="control-label">Upload Image</label>
        <form:input path="imageFile" id="productImage" type="file" class="form:input-large"/>
    </div>

    <br><br>
    <input type="submit" value="Submit" class="btn btn-success"/>
    <a href="<c:url value="/admin/productInventory"/>" class="btn btn-warning">Cancel</a>
    </form:form>

...
上传图像


编辑

我怀疑BindingResult捕获了当应用程序尝试将MultipartFile附加到模型时抛出的IllegalArgumentException,该模型具有字节数组,而不是MultipartFile。另一方面,MultipartFile无法持久化,这就是我决定使用byte[]的原因。但是如果我想使用bindingResult进行验证,那么bindingResult中仍然会有错误

这是绑定结果显示的错误:

字段“imageFile”上的对象“product”中的字段错误:拒绝值[org.springframework.web.multipart.commons]。CommonsMultipartFile@5d4938c0];代码[typeMismatch.product.imageFile,typeMismatch.imageFile,typeMismatch.[B,typeMismatch];参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[product.imageFile,imageFile];参数[];默认消息[imageFile]];默认消息[未能将“org.springframework.web.multipart.commons.commons multipartfile”类型的属性值转换为所需类型的“byte[]'对于属性'imageFile';嵌套异常为java.lang.IllegalArgumentException:无法将类型'org.springframework.web.multipart.commons.commons multipartfile'的值转换为属性'imageFile[0]'所需的类型'byte':PropertyEditor[org.springframework.beans.propertyeditors.CustomNumberReditor]返回了类型为“org.springframework.web.multipart.commons.commons multipartfile']的不正确值。“


它需要
BindingResult
,因为这样您就可以处理异常。如果不这样做,它将因错误请求而失败(因为缺少
BindingResult
,您自己无法处理)。问题是您需要一个
字节[]
在您的对象中,但实际上您正在传递一个
多部分文件
。若要避免出现错误,请将表单字段重命名为其他文件,然后
图像文件
,这样它就不会绑定到模型对象,因此也不会失败。或者使用
@InitBinder
方法禁用字段绑定,然后使用
dataBinder.setDisallowedFields(“图像文件”)
以防止绑定。如果我将表单字段重命名为st else,我将无法访问该页面,因为模型中没有此类字段。当我将该字段添加到模型
@Transient MultipartFile multipartImageFile
并将其应用到表单中,提交表单时,我将获得另一个400:
Required part'imageFile'不存在。
至于
@InitBinder
它工作得很好,但在我看来它仍然是一个解决方法。但是,我想知道我是否采取了很好的方法来解决这个问题。我对使用
product.setImageFile(multipartImageFile.getBytes())犹豫不决
在my
HomeContoller中。
在重命名参数的情况下,不要使用
表单:input
。您应该。只对您想要的字段使用spring表单标记。绑定到模型而不是不想绑定到模型的内容。主要问题是您将实体直接用作表单对象。您无法提交/绑定
 byte[]
直接,您必须为此进行手动操作。因此,最终是
.getBytes()
和手动setter是不可避免的?在这种情况下,可能更好的方法是在这两者之间创建一个
DspObject
、一个
BusinessObject
和一个
converterbject
。您认为如何?但是接下来的问题是从
字节[]
多部分文件
…为什么需要将其转换回来?它没有任何作用。您不需要不应该使用的附加对象。表单:为
图像文件
输入,只需常规的
输入
,并使用不同的“名称”,这样您就可以使用
@RequestParam
来获取它。如我统计的那样编辑
form:input
只能用于要绑定到表单对象的字段。