我需要上传专门用于上传文件的表单。在我的项目中,我可以使用JSF 1.2和RichFaces 3.3.3但我不能使用<rich:fileUpload/>
,因为我的客户端想要一个简单的输入,就像<input type="file"/>
一样。
如果我可以使用Primeface或Tomahawk的文件上传,但我禁止,我不能使用其他库,我也不能使用Servlet 3.0 nether Apache fileupload。我现在能做什么?我见过其他类似的问题,但他们可以使用其他的库,我就是不能,我受限制......
答案 0 :(得分:1)
我已经有一段时间了,因为我必须为JSF编写一个MIME解析器,但这是我对这个过程的记忆。
您需要编写一个解析器来从multi-part/formdata
有效负载中提取数据。有一个很好的overview of multi-part/formdata
on the W3 site。
您需要决定是否定位:
定位普通的servlet
只要上传POST操作不需要调用依赖于JSF上下文(托管bean等)的代码,这将是更简单的方法。
您的servlet会解析输入流中的数据并根据需要对其进行操作。
定位JSF视图/操作
在这里,您需要修饰请求(理想情况下使用HttpServletRequestWrapper
)以向JSF框架提供已解析的parameters。这通常在filter中完成,该{{3}}检测HTTP标头中的帖子类型。在调用任何表单操作之前以及如何将该数据公开给托管bean时,需要决定文件数据的存储位置。
您还需要考虑是否要为文件上传输入类型创建自定义JSF控件,或者是否可以使用纯HTML元素。
值得研究一下您无法使用的解析器/控件的功能,以确保您提供简单的功能 - 例如最大有效负载大小,以防止攻击者将数GB的数据上传到您的应用程序。 < / p>
答案 1 :(得分:1)
要使用可接受的解决方案解决此问题,我创建了一个普通表单和一个servlet,servlet接收multipart/form-data
请求并使用RichFaces 3.3.3中包含的org.ajax4jsf.request.MultipartRequest
来解析收到的参数和附加文件,然后我在会话中保存File
实例,并在JSF上下文中恢复它。
<强> XHTML:强>
<a4j:form >
<a4j:jsFunction name="finishUpload"
action="#{importacaoController.actionUploadArquivoDadosXX}"
reRender="uploadedFile,globalMensagens" />
<a4j:jsFunction
name="tipoNaoSuportado" reRender="globalMensagens" action="#{importacaoController.actionTipoNaoSuportado }"
/>
</a4j:form>
<form target="uploader" id="uploaderForm" action="#{request.contextPath}/MyServlet"
method="post" enctype="multipart/form-data" style="position: absolute;margin: -210px 0 0 300px;">
<div class="modulo-6-12">
<label for="uploadFileField">Anexar arquivo</label><br/>
<input type="file" id="uploadFileField" name="upload" onchange="jQuery('#uploaderForm').submit();" />
<br />
<small><h:outputText id="uploadedFile" value="#{importacaoController.arquivoConfig.name}" /></small>
</div>
</form>
<iframe id="uploader" width="0" height="0" src="" style="display: none; border: 0; margin:0;padding:0;"></iframe>
的的Servlet 强> 的
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String encoding = request.getCharacterEncoding();
if(encoding == null) request.setCharacterEncoding("UTF-8");
MultipartRequest mpRequest = new MultipartRequest(request,true,10*1024*1024,"importarXX");
String field = "upload";
Object o =mpRequest.getFile(field);
if(o instanceof File)
{
File file = (File)o;
HttpSession sess = request.getSession();
String name = mpRequest.getFileName(field);
Writer w = response.getWriter();
w.write("<html><head><script>");
if(!name.endsWith(".xls"))
{
w.write("parent.window.tipoNaoSuportado()" +
//"alert('Só são permitidos arquivos com extensão .xls');" +
"</script></head><body></body></html>");
w.close();
file.delete();
return;
}
sess.setAttribute("importarXXFile", o);
sess.setAttribute("importarXXFileName", name);
w.write("parent.window.finishUpload();</script></head><body>Sucesso</body></html>");
w.close();
}
}
}
<强>控制器:强>
public boolean actionUploadArquivoDadosXX(){
flgTipoNaoSuportado = false;
HttpSession sess = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession();
File uploadedFile = (File) sess.getAttribute("importarXXFile");
String uploadedFileName = (String) sess.getAttribute("importarXXFileName");
boolean ret = false;
if(uploadedFile != null && uploadedFileName != null){
BeanArquivoUpload arquivo = new BeanArquivoUpload();
arquivo.setFile(uploadedFile);
arquivo.setName(uploadedFileName);
arquivo.setFileSize(uploadedFile.length());
setArquivoConfig(arquivo);
ret = true;
}
else
{
setArquivoConfig(null);
}
sess.removeAttribute("importarXXFile");
sess.removeAttribute("importarXXFileName");
return ret;
}
答案 2 :(得分:0)
我之前遇到过同样的问题。我在用户点击浏览按钮时打开弹出窗口解决了这个问题,这个新的弹出窗口直接链接到支持文件上传和下载的servlet。 上传文件后,servlet在servlet主体的负载上调用window.close()直接关闭弹出窗口。 以下是所做的更改:
在addItem.jsp中,提示用户输入文件:
<script type="text/javascript">
...
function newWindow()
{
popupWindow = window.open('addItemImage.jsp','name','width=200,height=200');
}
...
</script>
<f:view>
<h:form id="search" onsubmit="return validateDetails()">
...
<h:panelGroup>
<font color="black">Item Image :</font>
</h:panelGroup>
<h:panelGroup>
<input type="button" value="Upload Image" onClick="newWindow()"/>
</h:panelGroup>
...
</h:form>
</f:view>
在打开的新弹出窗口中:addItemImage.jsp
<script type="text/javascript">
function validate()
{
var file = document.getElementById("file").value;
if(file == null || file == "")
return true;
if(file.indexOf(".jpg") == -1 && file.indexOf(".gif") && file.indexOf(".bmp") == -1 && file.indexOf(".jpeg") == -1)
{
alert("Invalid File Format!! Please upload jpg/bmp/gif");
return false;
}
return true;
}
</script>
<body>
<form enctype="multipart/form-data" method="post" action="FileUploaderServler.view" onsubmit="return validate()">
<input type="file" name="file" id="file" />
<input type="submit" value="Upload Image">
</form>
</body>
这将发布到servlet,然后该servlet将呈现图像并将其保存在某个位置。 FileUploaderServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
List<FileItem> items = null;
try
{
MultipartHTTPServletRequest multipartHTTPServletRequest = new MultipartHTTPServletRequest(Connection.getRequest());
items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(multipartHTTPServletRequest);
}
catch (FileUploadException e)
{
e.printStackTrace();
}
if(!Util.isNullList(items))
{
for (FileItem item : items)
{
if (!item.isFormField())
{
String itemName = item.getFieldName();
InputStream filecontent = null;
try
{
filecontent = item.getInputStream();
}
catch (IOException e)
{
e.printStackTrace();
}
/* String currDirPath = System.getProperty("user.dir"); // C:\Users\KISHORE\Desktop\eclipse
File file = new File(currDirPath+"\\itemImages");*/
new File(Constants.ABS_FILE_PATH_TO_IMAGES).mkdir();
File fw = new File(Constants.ABS_FILE_PATH_TO_IMAGES+"\\"+Connection.getRequest().getSession().getId()+".jpg"); // E:\Kishore Shopping Cart\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ShoppingCart\WEB-INF\itemImages\EC34EEE58065AD674192D3D57124F07E.jpg
fw.delete();
fw.createNewFile();
try
{
item.write(fw);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
PrintWriter out = response.getWriter();
out.print("<html><title>Add Image to Item</title><body onload='window.close()'>Uploaded Successfully!!</body>");
System.out.print("</html>");
}
完成在配置的地方保存文件后,此servlet将直接关闭先前打开的弹出窗口。
所以这样我就可以使用托管bean,jsf 1.2并实现fiel上传。 我在stackoverflow上找到了其他方法,但觉得实现起来有点复杂。