[英]Upload files to SharePoint from Java/J2EE application
我們需要從Java / J2EE應用程序向SharePoint上載大文件(最多200 MB)。
我們知道有一些現成的SharePoint Web服務允許將文件上傳到SharePoint。 但是,我們主要擔心的是並發用戶上傳文件會發生什么。 例如,在調用SharePoint發送該數據之前,我們需要為Java服務器(應用程序服務器)上的每個用戶讀取200 MB文件。 即使有5個並發用戶,所消耗的內存大約為1 GB,並且CPU使用率也可能很高。 在這種情況下,是否有任何建議如何處理服務器內存,文件上傳的並發性?
我認為一個選擇可能是使用像Flash / Flex這樣的技術,它們之間不需要其他服務器(Java應用服務器) - 但是,想知道如何在J2EE服務器中實現這一點?
HTTP://servername/sitename/_vti_bin/copy.asmx
謝謝
這是解決方案
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.security.cert.CertificateException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;
import javax.xml.ws.Holder;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import com.microsoft.schemas.sharepoint.soap.copy.CopyResultCollection;
import com.microsoft.schemas.sharepoint.soap.copy.CopySoap;
import com.microsoft.schemas.sharepoint.soap.copy.DestinationUrlCollection;
import com.microsoft.schemas.sharepoint.soap.copy.FieldInformation;
import com.microsoft.schemas.sharepoint.soap.copy.FieldInformationCollection;
import com.microsoft.schemas.sharepoint.soap.copy.FieldType;
public class Upload {
private static String username = "yourusrename";
private static String password = "yourpassword";
private static String targetPath = "https://www.yoursite.target/filename";
private static String sourcePath = "file.txt";
private static String portUrl = "https://www.yoursite.com/_vti_bin/Copy.asmx";
private static CopySoap soapInstance;
public static void main(String[] args) {
activate();
CopySoap sqs = getInstance();
String url = targetPath;
String sourceUrl = sourcePath;
DestinationUrlCollection urls = new DestinationUrlCollection();
urls.getString().add(url);
File file = null;
byte[] content = null;
try {
FileInputStream fileStream = new FileInputStream(file = new File(sourceUrl));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for (int readNum; (readNum = fileStream.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
}
content = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
FieldInformation titleInfo = new FieldInformation();
titleInfo.setDisplayName("testpage");
titleInfo.setType(FieldType.TEXT);
titleInfo.setValue("Test Page");
FieldInformationCollection infos = new FieldInformationCollection();
infos.getFieldInformation().add(titleInfo);
CopyResultCollection results = new CopyResultCollection();
Holder<CopyResultCollection> resultHolder = new Holder<CopyResultCollection>(results);
Holder<Long> longHolder = new Holder<Long>(new Long(-1));
if (content != null) {
sqs.copyIntoItems(sourceUrl, urls, infos, content, longHolder, resultHolder);
}
}
private static void activate() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(CopySoap.class);
factory.setAddress(portUrl);
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
soapInstance = (CopySoap) factory.create();
Authenticator.setDefault(new SPAuthenticator());
Client client = ClientProxy.getClient(soapInstance);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(10000);
httpClientPolicy.setAllowChunking(false);
HTTPConduit conduit = (HTTPConduit) client.getConduit();
conduit.setClient(httpClientPolicy);
TLSClientParameters tcp = new TLSClientParameters();
tcp.setTrustManagers(new TrustManager[] { (TrustManager) new TrustAllX509TrustManager() });
conduit.setTlsClientParameters(tcp);
}
public static CopySoap getInstance() {
return soapInstance;
}
static class SPAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
System.out.println("hitting SP with username and password for " + getRequestingScheme());
return (new PasswordAuthentication(username, password.toCharArray()));
}
}
/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates.
*/
public static class TrustAllX509TrustManager implements X509TrustManager {
/** Empty array of certificate authority certificates. */
private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};
/**
* Always trust for client SSL chain peer certificate chain with any
* authType authentication types.
*
* @param chain
* the peer certificate chain.
* @param authType`enter
* code here` the authentication type based on the client
* certificate.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
/**
* Always trust for server SSL chain peer certificate chain with any
* authType exchange algorithm types.
*
* @param chain
* the peer certificate chain.
* @param authType
* the key exchange algorithm used.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
/**
* Return an empty array of certificate authority certificates which are
* trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
}
}
好的..所以這就是我的理解:
我可以想到兩個選擇:
我不太了解sharepoint,如果可以提供要上傳的文件的位置而不是發送字節,那么你可以將文件ftp / sftp發送到sharepoint服務器,然后使用文件的位置調用webservice。
在Java中,而不是使用開箱即用的api for SOAP消息,編寫自定義api。 當用戶上傳文件時,將其另存為base64編碼文件。 然后你的自定義api將創建一個soap消息並流式傳輸而不是將所有內容加載到內存中。
對於選項2:嘗試是否可以將文件內容作為soap附件發送。 如果你想將它作為消息的一部分發送,它會變得有點復雜。
試試看。 我不確定是否有效。
SharePoint支持用於讀取/寫入文件的WebDAV協議。
您可以使用許多不需要在內存中加載完整文件的WebDAV庫。
或采取對象
@Autowired
ServletContext c;
byte[] bytes = file.getBytes();
String UPLOAD_FOLDEdR=c.getRealPath("/images");
Path path = Paths.get(UPLOAD_FOLDEdR+"/"+file.getOriginalFilename());
Files.write(path, bytes);
String Pic_Name =file.getOriginalFilename() ;
可能是我錯過了一些東西......但是當你讓用戶將文件上傳到你的J2EE服務器時,你是不是先將上傳的內容寫入臨時目錄然后再將其傳輸到服務器?
當您將緩沖區立即寫入磁盤時,您不會遇到內存限制的任何問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.