struts有默认的文件拦截器,一般配置maximumSize就可以了。
知道原理,我们可以写一个类继承它,实现自己的配置上传文件大小的方式。
然后细究页面上传文件的时候,发现了一些问题。
action配置中需要三个参数:File uploadFile,String uploadFileFileName, String uploadFileContentType
然而,页面上确实没有后面两个参数的配置,只有一个文件的控件。
最后,完成上传之后,保存的时候那两个属性里却是有值的,不得而知,只有看源码,找答案。
FileUploadInterceptor
这个拦截器就是需要配置的文件上传拦截器,里面的拦截方法里面,有intercept()方法,负责对文件上传的拦截。
研究其中的代码可以看到,上传文件主要是下面这个请求在起作用:
MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper)request;
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
File[] files = multiWrapper.getFiles(inputName);
if (files != null && files.length > 0) {
List<File> acceptedFiles = new ArrayList(files.length);
List<String> acceptedContentTypes = new ArrayList(files.length);
List<String> acceptedFileNames = new ArrayList(files.length);
String contentTypeName = inputName + "ContentType";
String fileNameName = inputName + "FileName";
for(int index = 0; index < files.length; ++index) {
if (this.acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation)) {
acceptedFiles.add(files[index]);
acceptedContentTypes.add(contentType[index]);
acceptedFileNames.add(fileName[index]);
}
}
if (!acceptedFiles.isEmpty()) {
Map<String, Object> params = ac.getParameters();
params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
}
}
上面黄底的就是为什么action中的uploadFile、uploadFileFileName、uploadFileContentType会被赋值了。因为,请求的时候默认把咱们form表单里的File的name属性获取,然后把对应的文件名、内容信息等存入与文件名相关的变量中,都是默认加上“contentType”“fileName”,所以上面的问题就迎刃而解了。
此时,为什么actionContext中的getParameters中的信息,会被存放入action的对应setter、getter项中?
经过一段时间的寻根溯源,又看到一个拦截器,ParametersInterceptor(还有一个excludeParams参数用以过滤不需要赋值的参数,和order参数用以是否按顺序初始化action中的值)。
这个类有如下描述:
* This interceptor sets all parameters on the value stack.
*typically resulting in the values submitted in a form
* request being applied to an action in the value stack.
从描述中可以看到,就是通过这个拦截器,表单提交的信息可以获取,同样actionContext的getparameters方法里的所有参数也会被赋值入。
这个时候,如果细究的话,为什么valueStack中的值会被setter/getter方法知晓并赋值呢?
--最终进行参数赋值是调用的 ValueStack的setValue方法,该方法内部使用是OGNL表达式引擎进行赋值的,虽然内部非常复杂,但我们只需要知道OGNL表达式引擎在 把请求参数设置到ValueStack中时,是从栈顶往栈底寻找有相应setter方法的对象,如果正在赋值的参数在ValueStack找到了一个对象 有setter方法则把该参数的值赋给该对象,如果没有找到则继续往栈底寻找,直到找到为止,如果找到栈底还是没有找到也就没有赋值成功。
以下是valueStack中的描述,当遇到EL表达式时,会找对应的getter/setter方法,获取对应的值。
具体的更深层次的实现,还不清楚,继续看咯。(大神可以指导)
* ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending on the expression being evaluated).
- struts文件上传拦截器中参数的配置(maximumSize,allowedTypes ,allowedExtensions)问题
<interceptor-ref name="fileUpload"> <param name="allowedTypes">image ...
- struts文件上传拦截器maximumSize设置文件大小不起作用
<interceptor-ref name="fileUpload"> <param name="allowedTypes ...
- SpringMVC 文件上传&拦截器&异常处理
文件上传 Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的 MultipartResolver 实现的.Spring 用 Jakarta Commons FileUpload ...
- Java Struts文件上传和下载详解
Struts2文件上传 Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传.上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的 ...
- Struts文件上传allowedTypes问题,烦人的“允许上传的文件类型”
Struts的文件上传问题,相信很多人都会使用allowedTypes参数来配置允许上传的文件类型,如下. <param name="allowedTypes"> im ...
- struts——文件上传
上传文件在一个系统当中是一个很常用的功能,也是一个比较重要的功能.今天我们就一起来学习一下Struts2如何上传文件. 今天讲的上传文件的方式有三种: 1,以字节为单位传输文件: 2,Struts2封 ...
- springMVC整理04--文件上传 & 拦截器 & 异常处理
1. 文件上传 SpringMVC 的文件上传非常简便,首先导入文件上传依赖的 jar: <!-- 文件上传所依赖的 jar 包 --> <dependency> <g ...
- struts文件上传,获取文件名和文件类型
struts文件上传,获取文件名和文件类型 Action中还有两个属 性:uploadFileName和uploadContentType,这两个属性分别用于封装上传文件的文件名.文件类型.这是S ...
- struts文件上传(多文件)
第01步:配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version= ...
随机推荐
- 遇见BUG如何区分前后端
定位前后端bug: 1.经验法: 软件测试人员应不断精进自己的技能,负责的项目多了,自然对功能的实现过程有了解,也就明白如何分类bug了. 例如: 网页上的某个图片的分辨率不对,如果我们了解实现过程, ...
- MySQL重做日志(redo log)
前面介绍了三种日志:error log.slow log.binlog,这三种都是 Server 层的.今天的 redo log 是 InnoDB引擎专有的日志文件. 为什么要有 redo log 用 ...
- C#9.0新特性之四:顶级程序语句(Top-Level Programs)
1 背景与动机 通常,如果只想用C#在控制台上打印一行"Hello World!",这可不是Console.WriteLine("Hello World!"); ...
- 老猿学5G扫盲贴:R15/R16中计费架构和计费原则涉及的规范文档
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在R16的32.240文档对应规范为3G ...
- 第11.15节 Python正则表达式转义符定义的特殊序列
一. 引言 在前面<第11.13节 Python正则表达式的转义符"\"功能介绍>介绍了正则表达式转义符'\',只不过当时作为转义符主要是用于在正则表达式中表示元字符自 ...
- 使用pip安装的Python扩展模块是从哪里下载的?
对于初学者才开始使用Python安装扩展模块时,发现只要输入扩展模块名就可以安装,无需先下载再安装,不免疑惑那些要安装的软件是在哪里下载的?是否可以从别的地方下载? 这个问题答案如下: pip安装第三 ...
- PyQt(Python+Qt)学习随笔:QTreeView树形视图的rootIsDecorated属性
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.属性说明 QTreeView树形视图的rootIsDecorated属性用于控制是否展示对顶层项 ...
- PyQt程序执行时报错:AttributeError: 'winTest' object has no attribute 'setCentralWidget'的解决方法
用QtDesigner设计了一个UI界面,保存在文件Ui_wintest.ui中,界面中使用了MainWindow窗口,窗口名字也叫MainWindow,用PyUIC将其转换成了 Ui_wintest ...
- PyQt(Python+Qt)学习随笔:Qt Designer中QAbstractButton派生按钮部件的checkable和checked属性
checkable属性 checkable属性确认按钮是否可以被选中,缺省情况下该值为False,即按钮是不能被选中的. 可选择的按钮按下之后,按钮不会自动弹起来,此时按钮为选中状态,当再次点击按钮时 ...
- 打造云原生大型分布式监控系统(四): Kvass+Thanos 监控超大规模容器集群
概述 继上一篇 Thanos 部署与实践 发布半年多之后,随着技术的发展,本系列又迎来了一次更新.本文将介绍如何结合 Kvass 与 Thanos,来更好的实现大规模容器集群场景下的监控. 有 Tha ...