Ioa*_*nis 12 jsf file-upload jsf-2.2
我正在尝试使用添加多个文件上传h:inputFile
.我快速浏览了一下源代码,看来它没有渲染选项multiple="multiple"
.没有编写自定义组件,有没有办法解决这个问题?如果没有,是否有可用的自定义JSF2.2组件可以处理多个Ajax文件上传?
更新:我已经通过了multiple="multiple"
使用passthrough
标签,但是当我调试FileRenderer
相关的代码时,用第二个文件覆盖了第一个文件:
for (Part cur : parts) {
if (clientId.equals(cur.getName())) {
component.setTransient(true);
setSubmittedValue(component, cur);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,由于有两个Part
相同的s clientId
,它总是使用last而不是传递列表.
如果有的话,请推荐替代方案.
Bal*_*usC 13
如何使用JSF 2.2上传多个文件
您确实可以使用另一个JSF 2.2功能实现此功能:直通属性.将multiple
属性设置为passthrough属性(浏览器支持目前相当广泛).
<html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
...
<h:inputFile ... a:multiple="true" />
Run Code Online (Sandbox Code Playgroud)
但是,<h:inputFile>
组件本身不支持Part
从请求中获取多个s并将其设置为数组或Collection
bean属性.它只会设置与输入字段名称匹配的最后一部分.基本上,为了支持多个部分,需要创建一个自定义渲染器(您应该立即利用这个机会立即支持multiple
属性而不依赖于直通属性).
为了在不创建整个渲染器的情况下使用"解决方法",您可以通过HttpServletRequest
以下小实用程序方法手动抓取所有部件:
public static Collection<Part> getAllParts(Part part) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
return request.getParts().stream().filter(p -> part.getName().equals(p.getName())).collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
因此,下面的结构应该与上面的实用方法一起使用:
<h:inputFile value="#{bean.part}" a:multiple="true" />
<h:commandButton ... action="#{bean.submit}" />
Run Code Online (Sandbox Code Playgroud)
private Part file;
public void submit() throws ServletException, IOException {
for (Part part : getAllParts(file)) {
String fileName = part.getSubmittedFileName();
InputStream fileContent = part.getInputStream();
// ...
// Do your thing with it.
// E.g. https://stackoverflow.com/q/14211843/157882
}
}
public Part getFile() {
return null; // Important!
}
public void setFile(Part file) {
this.file = file;
}
Run Code Online (Sandbox Code Playgroud)
请注意,为了安全和清晰,吸气剂可以更好地返回null
.实际上,整个getter方法应该是不必要的,但它就是这样.
在更现代的浏览器上,您甚至可以选择整个文件夹.这只需要一个更新的directory
属性.从Firefox 46开始支持此功能(自42以来,但需要在about:config中明确启用).基于Webkit的浏览器(Chrome 11 +,Safari 4+和Edge)通过专有webkitdirectory
属性支持此功能.因此,如果您同时指定这两个属性,那么通常是安全的.
<h:inputFile ... a:multiple="true" a:directory="true" a:webkitdirectory="true" />
Run Code Online (Sandbox Code Playgroud)
请注意,这不会发送物理文件夹,只会发送包含在这些文件夹中的文件.
更新:如果您碰巧使用JSF实用程序库OmniFaces,那么从版本2.5开始,<o:inputFile>
它应该使多个和目录选择不那么繁琐.
<o:inputFile value="#{bean.files}" multiple="true" />
Run Code Online (Sandbox Code Playgroud)
<o:inputFile value="#{bean.files}" directory="true" />
Run Code Online (Sandbox Code Playgroud)
该值可以绑定到a List<Part>
.
private List<Part> files; // +getter+setter
Run Code Online (Sandbox Code Playgroud)
小智 0
即使是很久以前的事了:考虑到您自己的评论,我会推荐像PrimeFaces fileUploadMultiple这样的组件,并提到不要忘记web.xml
上传所需的更改以及所有所需的库。根据您的需求,将其视为解决方法或完整解决方案。PrimeFaces 是一个非常好的组件库
归档时间: |
|
查看次数: |
10412 次 |
最近记录: |