扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
图1.阶段1:选择文件上传 图2.阶段2:上传该文件到服务器 图3.阶段3:上传完成 图4.阶段4:文件上传摘要 |
public class UploadMultipartFilter implements Filter{ public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException, ServletException { HttpServletRequest hRequest = (HttpServletRequest)request; //检查是否我们在处理一个多部分请求 String contentHeader = hRequest.getHeader("content-type"); boolean isMultipart = ( contentHeader != null && contentHeader.indexOf("multipart/form-data") != -1); if(isMultipart == false){ chain.doFilter(request,response); }else{ UploadMultipartRequestWrapper wrapper = new UploadMultipartRequestWrapper(hRequest); chain.doFilter(wrapper,response); } ... } |
public class UploadMultipartRequestWrapper extends HttpServletRequestWrapper{ private Map<String,String> formParameters; private Map<String,FileItem> fileParameters; public UploadMultipartRequestWrapper(HttpServletRequest request) { super(request); try{ ServletFileUpload upload = new ServletFileUpload(); upload.setFileItemFactory(new ProgressMonitorFileItemFactory(request)); List fileItems = upload.parseRequest(request); formParameters = new HashMap<String,String>(); fileParameters = new HashMap<String,FileItem>(); for(int i=0;i<fileItems.size();i++){ FileItem item = (FileItem)fileItems.get(i); if(item.isFormField() == true){ formParameters.put(item.getFieldName(),item.getString()); }else{ fileParameters.put(item.getFieldName(),item); request.setAttribute(item.getFieldName(),item); } } }catch(FileUploadException fe){ //请求时间超过-用户可能已经转到另一个页面。 //作一些记录 //... } ... |
public class ProgressMonitorFileItemFactory extends DiskFileItemFactory { private File temporaryDirectory; private HttpServletRequest requestRef; private long requestLength; public ProgressMonitorFileItemFactory(HttpServletRequest request) { super(); temporaryDirectory = (File)request.getSession().getServletContext().getAttribute("javax.servlet.context.tempdir"); requestRef = request; String contentLength = request.getHeader("content-length"); if(contentLength != null){requestLength = Long.parseLong(contentLength.trim());} } public FileItem createItem(String fieldName, String contentType,boolean isFormField, String fileName) { SessionUpdatingProgressObserver observer = null; if(isFormField == false) //这必须是一文件上传. observer = new SessionUpdatingProgressObserver(fieldName,fileName); ProgressMonitorFileItem item = new ProgressMonitorFileItem( fieldName,contentType,isFormField, fileName,2048,temporaryDirectory, observer,requestLength); return item; } ... public class SessionUpdatingProgressObserver implements ProgressObserver { private String fieldName; private String fileName; ... public void setProgress(double progress) { if(request != null){ request.getSession().setAttribute("FileUpload.Progress."+fieldName,progress); request.getSession().setAttribute("FileUpload.FileName."+fieldName,fileName); } } } } |
public class ProgressMonitorFileItem extends DiskFileItem { private ProgressObserver observer; private long passedInFileSize; ... private boolean isFormField; ... @Override public OutputStream getOutputStream() throws IOException { OutputStream baseOutputStream = super.getOutputStream(); if(isFormField == false){ return new BytesCountingOutputStream(baseOutputStream); }else{return baseOutputStream;} } ... private class BytesCountingOutputStream extends OutputStream{ private long previousProgressUpdate; private OutputStream base; public BytesCountingOutputStream(OutputStream ous){ base = ous; } ... private void fireProgressEvent(int b){ bytesRead += b; ... double progress = (((double)(bytesRead)) / passedInFileSize); progress *= 100.0 observer.setProgress(); } } } |
<comp:fileUpload value="#{uploadPageBean.uploadedFile}" uploadIcon="images/upload.png" styleClass="progressBarDiv" progressBarStyleClass="progressBar" cellStyleClass="progressBarCell" activeStyleClass="progressBarActiveCell"> <%--下面是一旦文件上传完成将成为可见的组件--%> <h:panelGrid columns="2" cellpadding="2" cellspacing="0" width="100%"> <f:facet name="header"> <h:outputText styleClass="text" value="文件上传成功." /> </f:facet> <h:panelGroup style="text-align:left;display:block;width:100%;"> <h:commandButton action="#{uploadPageBean.reset}" image="images/reset.png"/> </h:panelGroup> <h:panelGroup style="text-align:right;display:block;width:100%;"> <h:commandButton action="#{uploadPageBean.nextPage}" image="images/continue.png"/> </h:panelGroup> </h:panelGrid> </comp:fileUpload> |
图5.选择文件上传 |
//文件上传组件 writer.startElement("input", component); writer.writeAttribute("type", "file", null); writer.writeAttribute("name", component.getClientId(context), "id"); writer.writeAttribute("id", component.getClientId(context),"id"); if(input.getValue() != null){ //如果可用,则生成该文件名. FileItem fileData = (FileItem)input.getValue(); writer.writeAttribute("value", fileData.getName(), fileData.getName()); } writer.endElement("input"); String iconURL = input.getUploadIcon(); //生成图像,并把JavaScript事件依附到其上. writer.startElement("div", component); writer.writeAttribute("style","display:block;width:100%;text-align:center;", "style"); writer.startElement("img", component); writer.writeAttribute("src",iconURL,"src"); writer.writeAttribute("type","image","type"); writer.writeAttribute("style","cursor:hand;cursor:pointer;","style"); UIForm form = FacesUtils.getForm(context,component); if(form != null) { String getFormJS = "document.getElementById('" + form.getClientId(context) + "')"; String jsFriendlyClientID = input.getClientId(context).replace(":","_"); //设置表单的编码为multipart以用于文件上传,并且通过一个IFRAME //来提交它的内容。该组件的第二个阶段也在500毫秒后被初始化. writer.writeAttribute("onclick",getFormJS + ".encoding='multipart/form-data';" + getFormJS + ".target='" + iframeName + "';" + getFormJS + ".submit();" + getFormJS + ".encoding='application/x-www-form-urlencoded';" + getFormJS + ".target='_self';" + "setTimeout('refreshProgress" + jsFriendlyClientID + "();',500);",null); } ... writer.endElement("img"); //现在实现我们将要把该文件/表单提交到的IFRAME. writer.startElement("iframe", component); writer.writeAttribute("id", iframeName, null); writer.writeAttribute("name",iframeName,null); writer.writeAttribute("style","display:none;",null); writer.endElement("iframe"); writer.endElement("div"); writer.endElement("div"); //阶段1结束 |
图6.上传文件到服务器 |
writer.startElement("div",component); writer.writeAttribute("id", input.getClientId(context) + "_stage2", "id"); ... writer.writeAttribute("style","display:none", "style"); String progressBarID = component.getClientId(context) + "_progressBar"; String progressBarLabelID = component.getClientId(context) + "_progressBarlabel"; writer.startElement("div", component); writer.writeAttribute("id",progressBarID,"id"); String progressBarStyleClass = input.getProgressBarStyleClass(); if(progressBarStyleClass != null) writer.writeAttribute("class",progressBarStyleClass,"class"); for(int i=0;i<100;i++){ writer.write("<span> </span>"); } writer.endElement("div"); writer.startElement("div",component); writer.writeAttribute("id",progressBarLabelID,"id"); ... writer.endElement("div"); writer.endElement("div"); //阶段2结束 |
图7.上传完成 |
public void encodeChildren(FacesContext context, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); UIFileUpload input = (UIFileUpload)component; //一旦文件上传成功,处理将被显示的子结点 writer.startElement("div", component); writer.writeAttribute("id", input.getClientId(context) + "_stage3", "id"); //阶段3. if(input.getValue() == null){ writer.writeAttribute("style","display:none;",null); }else{ writer.writeAttribute("style","display:block",null); } List<UIComponent> children = input.getChildren(); for(UIComponent child : children){ FacesUtils.encodeRecursive(context,child); } writer.endElement("div"); //阶段3结束 } |
public void decode(FacesContext context, UIComponent component) { UIFileUpload input = (UIFileUpload) component; //检查是否这是一个上传进度请求,或是一个实际的上传请求. ExternalContext extContext = context.getExternalContext(); Map parameterMap = extContext.getRequestParameterMap(); String clientId = input.getClientId(context); Map requestMap = extContext.getRequestParameterMap(); if(requestMap.get(clientId) == null){ return;//什么也不做,返回 } if(parameterMap.containsKey(PROGRESS_REQUEST_PARAM_NAME)){ //这是一个在该文件请求中的得到进度信息的请求. //得到该进度信息并把它生成为XML HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse(); //设置响应的头信息 response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); try { ResponseWriter writer = FacesUtils.setupResponseWriter(context); writer.startElement("progress", input); writer.startElement("percentage", input); //从会话中获得当前进度百分数(由过滤器所设置). Double progressCount = (Double)extContext.getSessionMap(). get("FileUpload.Progress." +input.getClientId(context)); if(progressCount != null){ writer.writeText(progressCount, null); }else{ writer.writeText("1", null);//我们还没有收到上传 } writer.endElement("percentage"); writer.startElement("clientId", input); writer.writeText(input.getClientId(context), null); writer.endElement("clientId"); writer.endElement("progress"); } catch(Exception e){ //做一些错误记录... } }else{ //正常的译码请求. ... |
//正常的译码请求. if(requestMap.get(clientId).toString().equals("file")){ try{ HttpServletRequest request = (HttpServletRequest)extContext.getRequest(); FileItem fileData = (FileItem)request.getAttribute(clientId); if(fileData != null) input.setSubmittedValue(fileData); //现在我们需要清除与该项相关的任何进度 extContext.getSessionMap().put("FileUpload.Progress." + input.getClientId(context),new Double(100)); }catch(Exception e){ throw new RuntimeException("不能处理文件上传" +" - 请配置过滤器.",e); } } |
function refreshProgress(){ // 假定我们正在进入到阶段2. document.getElementById('fileUpload1_stage1').style.display = 'none'; document.getElementById('fileUpload1_stage2').style.display = ''; document.getElementById('fileUpload1_stage3').style.display = 'none'; //创建AJAX寄送 AjaxRequest.post( { //指定正确的参数,以便 //该组件在服务器端被正确处理 'parameters':{ 'uploadForm':'uploadForm', 'fileUpload1':'fileUpload1', 'jsf.component.UIFileUpload':'1', 'ajax.abortPhase':'4' } //Abort at Phase 4. //指定成功处理相应的回调方法. ,'onSuccess':function(req) { var xml = req.responseXML; if( xml.getElementsByTagName('clientId').length == 0) { setTimeout('refreshProgress()',200); return; } var clientId = xml.getElementsByTagName('clientId'); clientId = clientId[0].firstChild.nodeValue + '_progressBar'; //从XML获取百分比 var percentage = xml.getElementsByTagName('percentage')[0].firstChild.nodeValue; var innerSpans = document.getElementById(clientId).getElementsByTagName('span'); document.getElementById(clientId + 'label').innerHTML = Math.round(percentage) + '%'; //基于当前进度,设置这些span的式样类。 for(var i=0;i<innerSpans.length;i++){ if(i < percentage){ innerSpans[i].className = 'active'; }else{ innerSpans[i].className = 'passive'; } } //如果进度不是100,我们需要继续查询服务器以实现更新. if(percentage != 100){ setTimeout('refreshProgress()',400); } else { //文件上传已经完成,我们现在需要把该组件送入到第3个阶段. document.getElementById('fileUpload1_stage1').style.display = 'none'; document.getElementById('fileUpload1_stage2').style.display = 'none'; document.getElementById('fileUpload1_stage3').style.display = ''; } } }); } return builder.toString(); |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者