最近发现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 。演绎或用于商业目的,但是必须保留本文的署名软件人生(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。 |