最近發現Java的HttpClient從4.1版本以後就開始支援NTLM協議了,之前版本是不支援NTLM協議的(但可以通過開源的JCIFS library實現)。由於項目中其他系統(Java)需要調用基於NTLM協議的SharePoint List Web服務,之前是用了一個開源的Http組件JCIFS library實現類比身份認證的,具體網址如下:http://jcifs.samba.org/src/,這樣就可以正常訪問SharePoint的列表格服務了。
本文主要介紹一種代碼更為簡潔,使用更為簡便的基於最新版本HttpClient 4.2.5,該組件下載網址如下:http://hc.apache.org/downloads.cgi,
如Java程式需要訪問SharePoint的自訂欄表格服務,在瀏覽器中查看此列表的XML如:
需要注意的是此XML的編碼方式是採用UTF-8格式的,如採用Dom4j中解析此XML還需要進行特殊的處理,確保檔案頭是UTF-8格式的,預設並不是此格式,完整的Java範例程式碼如下:
import java.io.*;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import org.apache.http.HttpHost;import org.apache.http.auth.AuthScope;import org.apache.http.auth.NTCredentials;import org.apache.http.client.ClientProtocolException;import org.apache.http.protocol.BasicHttpContext;import org.apache.http.protocol.HttpContext;import java.util.Iterator;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub DefaultHttpClient httpclient = new DefaultHttpClient(); NTCredentials creds = new NTCredentials("UsrName", "PassWord", "my", "contosouat"); httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds); HttpHost target = new HttpHost("portal.contoso.uat", 80, "http"); // Make sure the same context is used to execute logically related requests HttpContext localContext = new BasicHttpContext(); // Execute a cheap method first. This will trigger NTLM authentication HttpGet httpget = new HttpGet("http://portal.contoso.uat/sites/cockpit/_vti_bin/listdata.svc/自訂欄表"); //httpget.setHeader("accept", "application/json"); HttpResponse response1 = null; try { response1 = httpclient.execute(target, httpget, localContext); //System.out.print(response1.toString()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } HttpEntity entity1 = response1.getEntity(); try { delFile("c:/自訂欄表.xml"); saveFile("c:/自訂欄表.xml",EntityUtils.toString(entity1),false); SAXReader reader = new SAXReader(); try { Document document = reader.read(new File("c:/自訂欄表.xml")); Element rootElm = document.getRootElement(); // 枚舉根節點下所有子節點 for (Iterator ie = rootElm.elementIterator(); ie.hasNext();) { Element element = (Element) ie.next(); if(element.getName()=="entry") { for (Iterator ic = element.elementIterator(); ic.hasNext();) { Element Celement = (Element) ic.next(); if(Celement.getName()=="content") { for (Iterator ip = Celement.elementIterator(); ip.hasNext();) { Element Pelement = (Element) ip.next(); for (Iterator ix = Pelement.elementIterator(); ix.hasNext();) { Element Xelement = (Element) ix.next(); if(Xelement.getName()=="人員名稱" || Xelement.getName()=="應發工資") { System.out.println(Xelement.getName()+":"+Xelement.getData()); } } //System.out.println(Pelement.getName()); } //System.out.println(Celement.getName()); } } } } }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void saveFile(String file, String data, boolean append) throws IOException { BufferedWriter bw = null; OutputStreamWriter osw = null; File f = new File(file); FileOutputStream fos = new FileOutputStream(f, append); try { // write UTF8 BOM mark if file is empty if (f.length() < 1) { final byte[] bom = new byte[] { (byte)0xEF, (byte)0xBB, (byte)0xBF }; fos.write(bom); } osw = new OutputStreamWriter(fos, "UTF-8"); bw = new BufferedWriter(osw); if (data != null) bw.write(data); } catch (IOException ex) { throw ex; } finally { try { bw.close(); fos.close(); } catch (Exception ex) { } } } /** * 刪除檔案 * @param filePathAndName String 檔案路徑及名稱 如c:/file.xml * @param fileContent String * @return boolean */ public static void delFile(String filePathAndName) { try { String filePath = filePathAndName; filePath = filePath.toString(); java.io.File myDelFile = new java.io.File(filePath); myDelFile.delete(); } catch (Exception e) { System.out.println("刪除檔案操作出錯"); e.printStackTrace(); } } }
該代碼執行結果如:
通過以上步驟就可以正常訪問SharePoint的列表並可以進行正常解析資料,可以根據以上代碼進一步擴充和完善,以滿足實際需求。
本部落格為軟體人生原創,歡迎轉載,轉載請標明出處:http://www.cnblogs.com/nbpowerboy/archive/2013/05/19/3086579.html 。演繹或用於商業目的,但是必須保留本文的署名軟體人生(包含連結)。如您有任何疑問或者授權方面的協商,請給我留言。 |