struts:实现图片的上传 argument type mismatch error

本文详细介绍了使用Struts框架实现文件上传的过程,包括配置表单、处理上传逻辑及解决类型不匹配的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

upload.jsp的部分源代码:

<html:form action="upload.do" method="post">     

      请选择需要上传的照片:

     <html:file property="photoFile"/>

     <html:submit value="上传"/>     

</html:form>
接下来需要在ActionForm中声明这个属性,并设置getter和setter方法,这部分源代码如下:

public class UploadForm extends ActionForm {

    protected FormFile photoFile;

    public FormFile getPhotoFile() {

        return photoFile;

    }

    public void setPhotoFile(FormFile photoFile) {

        this.photoFile = photoFile;

    }

}
这个表单的photoFile属性不是String或boolean,而是 org.apache.struts.upload.FormFile。因为用户上传的是一个二进制文件,而HTTP协议是以文本形式传输数据的,这就需 要进行转换。打个比方,一辆汽车需要从甲地送到乙地,但是两地之间只有一条索道,汽车没法开,所以就想个办法在甲地把汽车先拆了,把零件送到乙地再重新组 装成一辆汽车。FormFile起的就是拆卸和组装的作用,只不过它把拆卸、传输和组装的过程都封装起来了,我们看到的是一辆汽车从甲地开进 FormFile,过一会它就从乙地开出来了J我们要决定的只是把它停到什么地方,这就是Action的活了。

public class uploadAction extends Action{
public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception{
UploadForm uploadForm = (UploadForm) form;
if (!photoFile.getFileName().equals("")) {
    try {

     InputStream stream = photoFile.getInputStream();
     String filePath = request.getRealPath("/");
     filePath=filePath+photoFile.getFileName();
     OutputStream bos = new FileOutputStream(filePath);
     int bytesRead = 0;
     byte[] buffer = new byte[400000];
     while ((bytesRead = stream.read(buffer, 0, 400000)) != -1) {
      bos.write(buffer, 0, bytesRead);
      bos.flush();
      bos.close();
      stream.close();
     }
    } catch (Exception e) {
     System.err.print(e);
    }
    photoFile.destroy();
   }

return (mapping.findForward("toIndex"));
}
}
struts-config.xml中<action-mappings>里如下定义:
<action path="/upload" type="com.webex.tmis.uploadAction" name="UploadForm" scope="request" input="/wrong.jsp" />
运行一下:抛出如下异常:
struts的argument type mismatch错误..
java.lang.IllegalArgumentException: Cannot invoke com.webex.tmis.uploadForm.setPhotoFile - argument type mismatch,

debug 了一下,原来是要把String 强行转换成FormFile,所以才会抛出argument type mismatch,一查,原来是这样的:表单(html:form)中enctype="multipart/form-data"的意思,是设置表单的 MIME编码,默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了 multipart/form-data,才能增加传递文件数据的功能,进行下面的操作.enctype="multipart/form-data"是 上传二进制数据; form里面的input的值以2进制的方式传过去。在html的form中加入enctype="multipart/form-data"的时候,图 片上传问题解决了。
upload.jsp代码如下:
<html:form action="upload.do" enctype="multipart/form-data" method="post">     

      请选择需要上传的照片:

     <html:file property="photoFile"/>

     <html:submit value="上传"/>     

</html:form>

<think>嗯,用户遇到了A2114 INVOKE参数类型不匹配的错误,需要解决这个问题。首先,我要回想一下常见的参数类型不匹配的原因。根据引用[4]提到的BeanUtils.populate问题,可能是因为类型转换失败,比如字符串无法转为目标类型。这可能涉及到反射调用时参数类型与实际方法签名不符的情况。 接下来,用户可能在调用方法时传递了错误类型的参数。例如,方法期望的是整数,但实际传了字符串。这时候需要检查方法声明和调用处的参数是否一致。还要考虑自动装箱/拆箱的问题,比如int和Integer之间的转换是否正常。 然后,考虑到用户可能使用框架如Struts,可能需要检查表单字段与ActionForm的属性类型是否匹配。如果表单提交的数据类型与后端定义的属性类型不一致,BeanUtils在填充数据时就会报错。例如,表单中的字段是字符串,但ActionForm中的属性是日期类型,这时需要自定义转换器。 另外,用户提到的INVOKE可能涉及到动态方法调用或反射。这时候需要确认通过反射获取的方法参数类型是否正确,传递的参数顺序和类型是否与方法签名完全一致。比如,使用Method.invoke时,参数数组中的每个元素类型必须与方法参数类型严格匹配。 还有可能是在使用某些库或框架时,版本不兼容导致类型处理方式变化。检查依赖库的版本是否有变化,或者是否有遗漏的类型转换配置。 解决方案方面,首先要仔细查看错误堆栈,定位到具体的代码行。然后逐一核对参数类型,使用调试工具或日志输出参数的实际类型。对于框架问题,可能需要配置自定义的类型转换器,比如在Struts中注册转换器来处理特定类型的转换。此外,单元测试可以帮助验证每个方法的参数传递是否正确。 最后,用户可能需要检查是否有重载方法导致混淆,或者泛型在编译后被擦除,导致运行时类型不匹配。确保调用的是正确的方法,并且泛型信息得到妥善处理。</think>### A2114 INVOKE参数类型不匹配错误解决方案 #### 问题原因分析 该错误通常发生在以下场景: 1. **类型转换失败**:方法调用时传入的参数类型与方法签名声明的类型不兼容(例如将字符串传递给整型参数)[^4] 2. **自动装箱问题**:原始类型与包装类型之间未正确转换(如`int`与`Integer`) 3. **框架配置问题**:Struts等框架的表单字段类型与ActionForm属性类型不匹配 4. **反射调用错误**:通过反射调用方法时参数类型定义不准确 #### 分步解决方案 1. **定位错误源头** - 查看完整异常堆栈,找到具体的类和方法调用位置 - 示例错误信息: ```java java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at com.example.MyService.process(MyService.java:42) // 关键行号 ``` 2. **核对方法签名** ```java // 被调用方法示例 public void processData(int id, String name, Date createTime) { // 方法实现 } // 调用处检查 Object[] params = { "123", "John", new Date() }; // 错误:第一个参数应为int类型 ``` 3. **类型验证与转换** - 添加类型检查: ```java if(params[0] instanceof Integer) { // 安全转换 } else { System.out.println("参数类型错误:" + params[0].getClass().getName()); } ``` 4. **框架特殊处理(Struts示例)** - 在`struts-config.xml`中注册自定义转换器: ```xml <form-beans> <form-bean name="myForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="createDate" type="java.util.Date"/> </form-bean> </form-beans> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in> ``` 5. **反射调用规范写法** ```java Class<?>[] paramTypes = { Integer.TYPE, String.class, Date.class }; Method method = clazz.getMethod("processData", paramTypes); Object[] args = { 123, "John", new Date() }; // 严格匹配参数类型 method.invoke(targetObject, args); ``` #### 预防措施 1. **单元测试验证** ```java @Test public void testParameterTypes() throws Exception { Method method = MyService.class.getMethod("processData", int.class, String.class, Date.class); Class<?>[] paramTypes = method.getParameterTypes(); assertEquals(int.class, paramTypes[0]); } ``` 2. **日志调试技巧** ```java Arrays.stream(method.getParameterTypes()) .forEach(t -> System.out.println("参数类型要求:" + t.getName())); ``` 3. **使用注解辅助检查** ```java public void processData(@NotNull Integer id, @Size(max=50) String name, @Past Date createTime) { // 方法体 } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值