如何实现Alfresco的多文档上传实现

    上周研究了关于Alfresco的多文档上传方法,官方网站这类资源比较少,通用的方法是开发工程师建议使用NTLM或者FTP来实现多文档上传,由于Alfresco遵循了JSR 170内容库存储标准实现,所以在设计上传文档处理时基于web-client的实现只能传一个文档。
 
    我看了Alfresco的源代码,要实现多文档的web-client实现并不复杂,但是这样做的结果仅仅是现实“文档上传”和“内容存储”,是否与JSR170规范一致,我不敢确定,如下为具体实现方法,其依据参考了如下源文件代码:
  •     1.org.alfresco.web.app.servlet.UploadFileServlet.java
  •     2.org.alfresco.web.bean.ajax.FileUploadBean.java
  •     3.content/add-content-dialog.jsp
  •     4.org.alfresco.web.bean.content.AddContentDialog.java

    具体的实现流程如下:
    add-content-dialog.jsp -> UploadFileServlet -> add-content-dialog.jsp,比源流程的实现要少几个步骤。主要是重写了UploadFileServlet.java的方法,对上传多个文档进行遍历后接着就进行“内容存储”,代码如下:

/*
 * Copyright (C) 2005-2007 Alfresco Software Limited.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * As a special exception to the terms and conditions of version 2.0 of
 * the GPL, you may redistribute this Program in connection with Free/Libre
 * and Open Source Software ("FLOSS") applications as described in Alfresco's
 * FLOSS exception.  You should have recieved a copy of the text describing
 * the FLOSS exception, and it is also available here:
 * 
http://www.alfresco.com/legal/licensing*/

package  org.alfresco.web.app.servlet;

import  java.io.BufferedInputStream;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.Serializable;
import  java.util.HashMap;
import  java.util.List;
import  java.util.Map;
import  java.util.StringTokenizer;

import  javax.faces.context.FacesContext;
import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;
import  javax.servlet.http.HttpSession;

import  org.alfresco.error.AlfrescoRuntimeException;
import  org.alfresco.model.ContentModel;
import  org.alfresco.repo.content.filestore.FileContentReader;
import  org.alfresco.service.ServiceRegistry;
import  org.alfresco.service.cmr.model.FileInfo;
import  org.alfresco.service.cmr.repository.ContentReader;
import  org.alfresco.service.cmr.repository.ContentWriter;
import  org.alfresco.service.cmr.repository.NodeRef;
import  org.alfresco.service.cmr.repository.NodeService;
import  org.alfresco.service.namespace.QName;
import  org.alfresco.util.TempFileProvider;
import  org.alfresco.web.app.Application;
import  org.alfresco.web.bean.FileUploadBean;
import  org.alfresco.web.bean.NavigationBean;
import  org.alfresco.web.bean.content.AddContentDialog;
import  org.alfresco.web.bean.repository.Repository;
import  org.apache.commons.fileupload.FileItem;
import  org.apache.commons.fileupload.RequestContext;
import  org.apache.commons.fileupload.disk.DiskFileItemFactory;
import  org.apache.commons.fileupload.servlet.ServletFileUpload;
import  org.apache.commons.fileupload.servlet.ServletRequestContext;
import  org.apache.commons.io.FilenameUtils;
import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;
import  org.springframework.web.context.WebApplicationContext;
import  org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * Servlet that takes a file uploaded via a browser and represents it as an
 * UploadFileBean in the session
 *
 * 
@author gavinc
 
*/

public   class  UploadFileServlet  extends  BaseServlet  {
    
private static final long serialVersionUID = -5482538466491052873L;
    
private static final Log logger = LogFactory.getLog(UploadFileServlet.class);

    
/**
     * 
@see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     
*/

    
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uploadId 
= null;
        String returnPage 
= null;
        
final RequestContext requestContext = new ServletRequestContext(request);
        
boolean isMultipart = ServletFileUpload.isMultipartContent(requestContext);

        
try {
            AuthenticationStatus status 
= servletAuthenticate(request, response);
            
if (status == AuthenticationStatus.Failure) {
                
return;
            }


            
if (!isMultipart) {
                
throw new AlfrescoRuntimeException("This servlet can only be used to handle file upload requests, make"
                        
+ "sure you have set the enctype attribute on your form to multipart/form-data");
            }


            
if (logger.isDebugEnabled())
                logger.debug(
"Uploading servlet servicing...");

            HttpSession session 
= request.getSession();
            ServletFileUpload upload 
= new ServletFileUpload(new DiskFileItemFactory());

            
// ensure that the encoding is handled correctly
            upload.setHeaderEncoding("UTF-8");

            List
<FileItem> fileItems = upload.parseRequest(request);

            FileUploadBean bean 
= new FileUploadBean();

            
// ------------------------BEGIN
            File file = null;
            
// ------------------------END

            
for (FileItem item : fileItems) {
                
if (item.isFormField()) {
                    
if (item.getFieldName().equalsIgnoreCase("return-page")) {
                        returnPage 
= item.getString();
                    }
 else if (item.getFieldName().equalsIgnoreCase("upload-id")) {
                        uploadId 
= item.getString();
                    }

                }
 else {
                    String filename 
= item.getName();
                    
if (filename != null && filename.length() != 0{
                        
if (logger.isDebugEnabled()) {
                            logger.debug(
"Processing uploaded file: " + filename);
                        }

                        
// workaround a bug in IE where the full path is
                        
// returned
                        
// IE is only available for Windows so only check for
                        
// the Windows path separator
                        filename = FilenameUtils.getName(filename);
                        
final File tempFile = TempFileProvider.createTempFile("alfresco"".upload");
                        item.write(tempFile);
                        bean.setFile(tempFile);
                        bean.setFileName(filename);
                        bean.setFilePath(tempFile.getAbsolutePath());
                        
if (logger.isDebugEnabled()) {
                            logger.debug(
"Temp file: " + tempFile.getAbsolutePath() + " size " + tempFile.length() + " bytes created from upload filename: "
                                    
+ filename);
                        }


                        
                        
// ------------------------BEGIN
                        file = tempFile;
                        FacesContext fc 
= FacesContext.getCurrentInstance();
                        NavigationBean navigator 
= (NavigationBean) FacesHelper.getManagedBean(fc, "NavigationBean");
                        WebApplicationContext wc 
= WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
                        NodeService nodeService 
= (NodeService) wc.getBean("nodeService");

                        NodeRef containerRef;
                        String nodeId 
= navigator.getCurrentNodeId();
                        
if (nodeId == null{
                            containerRef 
= nodeService.getRootNode(Repository.getStoreRef());
                        }
 else {
                            containerRef 
= new NodeRef(Repository.getStoreRef(), nodeId);
                        }


                        
try {
                            
if (file != null{
                                
if (containerRef != null{
                                    
// Guess the mimetype
                                    String mimetype = Repository.getMimeTypeForFileName(fc, filename);

                                    
// Now guess the encoding
                                    String encoding = "UTF-8";
                                    InputStream is 
= null;
                                    
try {
                                        is 
= new BufferedInputStream(new FileInputStream(file));
                                        encoding 
= Repository.guessEncoding(fc, is, mimetype);
                                    }
 catch (Throwable e) {
                                        
// Bad as it is, it's not terminal
                                        logger.error("Failed to guess character encoding of file: " + file, e);
                                    }
 finally {
                                        
if (is != null{
                                            
try {
                                                is.close();
                                            }
 catch (Throwable e) {
                                            }

                                        }

                                    }


                                    
// Try and extract metadata from the file
                                    ContentReader cr = new FileContentReader(file);
                                    cr.setMimetype(mimetype);

                                    
// create properties for content type
                                    String author = null;
                                    String title 
= null;
                                    String description 
= null;
                                    Map
<QName, Serializable> contentProps = new HashMap<QName, Serializable>(51.0f);
                                    
if (Repository.extractMetadata(fc, cr, contentProps)) {
                                        author 
= (String) (contentProps.get(ContentModel.PROP_AUTHOR));
                                        title 
= (String) (contentProps.get(ContentModel.PROP_TITLE));
                                        description 
= (String) (contentProps.get(ContentModel.PROP_DESCRIPTION));
                                    }


                                    
// default the title to the file name if not
                                    
// set
                                    if (title == null{
                                        title 
= filename;
                                    }


                                    ServiceRegistry services 
= Repository.getServiceRegistry(fc);
                                    FileInfo fileInfo 
= services.getFileFolderService().create(containerRef, filename, ContentModel.TYPE_CONTENT);
                                    NodeRef fileNodeRef 
= fileInfo.getNodeRef();

                                    
// set the author aspect
                                    if (author != null{
                                        Map
<QName, Serializable> authorProps = new HashMap<QName, Serializable>(11.0f);
                                        authorProps.put(ContentModel.PROP_AUTHOR, author);
                                        services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_AUTHOR, authorProps);
                                    }


                                    
// apply the titled aspect - title and
                                    
// description
                                    Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(21.0f);
                                    titledProps.put(ContentModel.PROP_TITLE, title);
                                    titledProps.put(ContentModel.PROP_DESCRIPTION, description);
                                    services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_TITLED, titledProps);

                                    
// get a writer for the content and put the
                                    
// file
                                    ContentWriter writer = services.getContentService().getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
                                    writer.setMimetype(mimetype);
                                    writer.setEncoding(encoding);
                                    writer.putContent(file);
                                }

                            }

                        }
 catch (Exception e) {
                            returnPage 
= returnPage.replace("${UPLOAD_ERROR}", e.getMessage());
                        }

                        
// ------------------------END
                    }

                }

            }


            session.setAttribute(FileUploadBean.getKey(uploadId), bean);

            
if (bean.getFile() == null{
                logger.warn(
"no file uploaded for upload " + uploadId);
            }

            
if (returnPage == null || returnPage.length() == 0{
                
throw new AlfrescoRuntimeException("return-page parameter has not been supplied");
            }


            
// finally redirect
            if (logger.isDebugEnabled()) {
                logger.debug(
"redirecting to: " + returnPage);
            }


            response.sendRedirect(returnPage);

        }
 catch (Throwable error) {
            Application.handleServletError(getServletContext(), (HttpServletRequest) request, (HttpServletResponse) response, error, logger, returnPage);
        }


        
if (logger.isDebugEnabled()) {
            logger.debug(
"upload complete");
        }

    }


    
static NodeRef pathToNodeRef(FacesContext fc, String path) {
        
// convert cm:name based path to a NodeRef
        StringTokenizer t = new StringTokenizer(path, "/");
        
int tokenCount = t.countTokens();
        String[] elements 
= new String[tokenCount];
        
for (int i = 0; i < tokenCount; i++{
            elements[i] 
= t.nextToken();
        }

        
return BaseServlet.resolveWebDAVPath(fc, elements, false);
    }

}


然后改写add-content-dialog.jsp,如下:
<% --
* Copyright (C) 2005-2007 Alfresco Software Limited.

* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
--
%>
<% @ taglib uri="http://java.sun.com/jsf/html" prefix="h"  %>
<% @ taglib uri="http://java.sun.com/jsf/core" prefix="f"  %>
<% @ taglib uri="/WEB-INF/alfresco.tld" prefix="a"  %>
<% @ taglib uri="/WEB-INF/repo.tld" prefix="r"  %>

<% @ page buffer="32kb" contentType="text/html;charset=UTF-8"  %>
<% @ page isELIgnored="false"  %>
<% @ page import="javax.faces.context.FacesContext"  %>
<% @ page import="org.alfresco.web.app.Application"  %>
<% @ page import="org.alfresco.web.bean.content.AddContentDialog"  %>
<% @ page import="org.alfresco.web.app.servlet.FacesHelper"  %>
<% @ page import="org.alfresco.web.ui.common.PanelGenerator"  %>

<%
boolean fileUploaded = false;

AddContentDialog dialog 
= (AddContentDialog)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "AddContentDialog");
if (dialog != null && dialog.getFileName() != null)
{
fileUploaded 
= true;
}
%>

< r:page  titleId ="title_add_content" >

< script  type ="text/javascript"  src ="<%=request.getContextPath()%>/scripts/validation.js" ></ script >

< f:view >

<% -- load a bundle of properties with I18N strings -- %>
< f:loadBundle  basename ="alfresco.messages.webclient"  var ="msg" />

< h:form  acceptcharset ="UTF-8"  id ="add-content-upload-start" >

<% -- Main outer table -- %>
< table  cellspacing ="0"  cellpadding ="2" >

<% -- Title bar -- %>
< tr >
< td  colspan ="2" >
<% @ include file="../parts/titlebar.jsp"  %>
</ td >
</ tr >

<% -- Main area -- %>
< tr  valign ="top" >
<% -- Shelf -- %>
< td >
<% @ include file="../parts/shelf.jsp"  %>
</ td >

<% -- Work Area -- %>
< td  width ="100%" >
< table  cellspacing ="0"  cellpadding ="0"  width ="100%" >
<% -- Breadcrumb -- %>
<% @ include file="../parts/breadcrumb.jsp"  %>

<% -- Status and Actions -- %>
< tr >
< td  style ="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)"  width ="4" ></ td >
< td  bgcolor ="#dfe6ed" >

<% -- Status and Actions inner contents table -- %>
<% -- Generally this consists of an icon, textual summary and actions for the current object -- %>
< table  cellspacing ="4"  cellpadding ="0"  width ="100%" >
< tr >
< td  width ="32" >
< h:graphicImage  id ="dialog-logo"  url ="/images/icons/add_content_large.gif"   />
</ td >
< td >
< div  class ="mainTitle" >< h:outputText  value ="#{msg.add_content_dialog_title}"   /></ div >
< div  class ="mainSubText" >< h:outputText  value ="#{msg.add_content_dialog_desc}"   /></ div >
</ td >
</ tr >
</ table >

</ td >
< td  style ="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)"  width ="4" ></ td >
</ tr >

<% -- separator row with gradient shadow -- %>
< tr >
< td >< img  src ="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif"  width ="4"  height ="9" ></ td >
< td  style ="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)" ></ td >
< td >< img  src ="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif"  width ="4"  height ="9" ></ td >
</ tr >

</ h:form >

<% -- Details -- %>
< tr  valign =top >
< td  style ="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)"  width ="4" ></ td >
< td >
< table  cellspacing ="0"  cellpadding ="3"  border ="0"  width ="100%" >
< tr >
< td  width ="100%"  valign ="top" >

< a:errors  message ="#{msg.error_dialog}"  styleClass ="errorMessage"   />

<%
if (fileUploaded)
{
PanelGenerator.generatePanelStart(out, request.getContextPath(), 
"yellowInner""#ffffcc");
out.write(
"<img alt='' align='absmiddle' src='");
out.write(request.getContextPath());
out.write(
"/images/icons/info_icon.gif' />&nbsp;&nbsp;");
out.write(dialog.getFileUploadSuccessMsg());
PanelGenerator.generatePanelEnd(out, request.getContextPath(), 
"yellowInner");
out.write(
"<div style='padding:2px;'></div>");
}
%>

<%  PanelGenerator.generatePanelStart(out, request.getContextPath(), "white""white");  %>

< table  cellpadding ="2"  cellspacing ="2"  border ="0"  width ="100%" >
<%  if (fileUploaded == false) {  %>
< tr >
< td  colspan ="3"  class ="wizardSectionHeading" >< h:outputText  value ="#{msg.upload_content}" /></ td >
</ tr >
< tr >< td  class ="paddingRow" ></ td ></ tr >
< tr >
< td  class ="mainSubText"  colspan ="3" >
< h:outputText  id ="text1"  value ="1. #{msg.locate_content}" />
</ td >
</ tr >
< tr >< td  class ="paddingRow" ></ td ></ tr >

< r:uploadForm >
< tr >
< td  colspan ="3" >
< input  style ="margin-left:12px;"  type ="file"  size ="75"  name ="alfFileInput" />
< input  style ="margin-left:12px;"  type ="file"  size ="75"  name ="alfFileInput" />
< input  style ="margin-left:12px;"  type ="file"  size ="75"  name ="alfFileInput" />
</ td >
</ tr >
< tr >< td  class ="paddingRow" ></ td ></ tr >
< tr >
< td  class ="mainSubText"  colspan ="3" >
2. 
<% = Application.getMessage(FacesContext.getCurrentInstance(),  " click_upload " ) %>
</ td >
</ tr >
< tr >
< td  colspan ="3" >
< input  style ="margin-left:12px;"  type ="submit"  value ="<%=Application.getMessage(FacesContext.getCurrentInstance(), " upload")% > " />
</ td >
</ tr >
</ r:uploadForm >
<%  }  %>

< h:form  acceptcharset ="UTF-8"  id ="add-content-upload-end"  onsubmit ="return validate();" >


</ table >
<%  PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white");  %>
</ td >

< td  valign ="top" >
<%  PanelGenerator.generatePanelStart(out, request.getContextPath(), "greyround""#F5F5F5");  %>
< table  cellpadding ="1"  cellspacing ="1"  border ="0" >
< tr >
< td  align ="center" >
<!--  h:commandButton id="finish-button" styleClass="wizardButton"
value="#{msg.ok}"
action="#{AddContentDialog.finish}"
disabled="#{AddContentDialog.finishButtonDisabled}" / 
-->
</ td >
</ tr >
< tr >
< td  align ="center" >
< h:commandButton  id ="cancel-button"  styleClass ="wizardButton"
value
="#{msg.ok}"
action
="#{AddContentDialog.cancel}"   />
</ td >
</ tr >
</ table >
<%  PanelGenerator.generatePanelEnd(out, request.getContextPath(), "greyround");  %>
</ td >
</ tr >
</ table >
</ td >
< td  style ="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)"  width ="4" ></ td >
</ tr >

<% -- separator row with bottom panel graphics -- %>
< tr >
< td >< img  src ="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif"  width ="4"  height ="4" ></ td >
< td  width ="100%"  align ="center"  style ="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)" ></ td >
< td >< img  src ="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif"  width ="4"  height ="4" ></ td >
</ tr >

</ table >
</ td >
</ tr >
</ table >

< script  type ="text/javascript" >
var finishButtonPressed = false;
window.onload 
= pageLoaded;

function pageLoaded()
{
document.getElementById(
"add-content-upload-end:finish-button").onclick = function() {finishButtonPressed = true; clear_add_2Dcontent_2Dupload_2Dend();}
}


function checkButtonState()
{
if (document.getElementById("add-content-upload-end:file-name").value.length == 0 )
{
document.getElementById(
"add-content-upload-end:finish-button").disabled = true;
}

else
{
document.getElementById(
"add-content-upload-end:finish-button").disabled = false;
}

}


function validate()
{
if (finishButtonPressed)
{
finishButtonPressed 
= false;
return validateName(document.getElementById("add-content-upload-end:file-name"),
'<a:outputText id="text11" value="#{msg.validation_invalid_character}" />'true);
}

else
{
return true;
}

}


</ script >

</ h:form >

</ f:view >

</ r:page >

改写此jsp的目的是完成上传和存储后,直接返回到显示结果页面,无需再往下进行,我发现如果要往下进行对文档进行mimetype,author,description的录入比较麻烦,很不好处理。

这样就实现了多文档的上传和存储
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值