- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用小型 Java Web 应用程序访问我们公司的 SharePoint 2013 实例,该实例托管在 ourinstance.sharepoint.com。
我通过 _layouts/15/AppRegNew.aspx 以这种方式注册了应用程序:
https://ourdomain:8443/our-redirect-processing
我使用 _layouts/15/appinv.aspx 编辑了应用程序权限,我在其中通过客户端 ID 查找并编辑了其权限请求 XML 以包含:
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://insideidc.sharepoint.com/oursite/web" Right="FullControl"/>
</AppPermissionRequests>
https://ourdomain:8443/our-redirect-processing
背后的处理程序正在执行此操作:
JsonWebSignature jws = JsonWebSignature.parse(new JacksonFactory(), request.getParameter("SPAppToken"));
JsonParser jsonParser = new JacksonFactory().createJsonParser(jws.getPayload().get("appctx").toString());
AppCtx appCtx = jsonParser.parse(AppCtx.class, new CustomizeJsonParser());
String appctxsender=jws.getPayload().get("appctxsender").toString();
String[] splitApptxSender = appctxsender.split("@");
String sharepointServerHostName = new URL(request.getParameter("SPSiteUrl")).getHost();
String resource = splitApptxSender[0] + "/" + sharepointServerHostName + "@" + splitApptxSender[1];
AuthorizationCodeTokenRequest tokenRequest = new AuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(),
new GenericUrl(appCtx.getSecurityTokenServiceUri()), jws.getPayload().get("refreshtoken").toString());
tokenRequest.setRedirectUri(request.getRequestURL().toString());
String aud = (String) jws.getPayload().getAudience();
tokenRequest.setClientAuthentication(new ClientParametersAuthentication(aud, secrets.get(aud)));
tokenRequest.setGrantType("refresh_token");
tokenRequest.set("resource", resource);
tokenRequest.set("refresh_token", jws.getPayload().get("refreshtoken").toString());
TokenResponse response = tokenRequest.execute();
token = response.getAccessToken();
它使用 com.google.api.client。 auth、http 和 json 类。
我在对此 URL 的 REST 调用中使用的 token :
https://ourinstance.sharepoint.com/oursite/_api/web/getFolderByServerRelativeUrl('/thefolderIwant')/Files
使用这些 header :
Accept: application/json;odata=verbose
Authorization: Bearer theToken
响应要求我登录,而响应 header 设置了 WWW-Authenticate: NTLM。
第一个问题:如此复杂的获取 OAuth token 的过程是否应该以另一个凭据请求结束?
第二个也是主要问题:当 SharePoint 为我们托管时,我如何为 NTLM Authenticator 构建域\用户名?
最佳答案
我在尝试访问 Microsoft 的 Project Online 时也有过类似的经历。我从 AllThatJS 中找到了一些有用的信息这给我指明了正确的方向。他建议使用 Fiddler 嗅探数据包。一旦我这样做了,我就看到了实际发生的事情。这是我用来解决这个问题的一些 Java 代码,使用 Apache 的 HttpClient、Apache 的 common-io 和 log4j 来解决这个问题:
/**
This is for using Java to connect with Microsoft's Project Online
If you go into your Project Online, go to 'Server Settings' -> 'Manage Users', and look under the column 'User Logon Account'
If it looks like :
i:0#.w|domain\\username
then you can just scroll down to where I call
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM, AuthScope.ANY_SCHEME),
new NTCredentials(
USERNAME,
PASSWORD,
url.getHost(),
DOMAIN));
However, if it looks more like :
i:0#.f|membership|username@yourcompany.com
then you'll need to use OAuth, which is what this file demonstrates.
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.UUID;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.io.IOUtils;// from commons-io-2.4.jar
import org.apache.http.Header;// from httpcore-4.2.4.jar
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;// from log4j.jar
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class ProjectOnline {
private static final Logger logger = Logger.getLogger(ProjectOnline.class);
private static final String USERNAME = "your user's email address";
private static final String PASSWORD = "password";
private static final String DOMAIN = "YOURDOMAIN";
private static final String PROJECT_SERVER = "https://your.project.online.sharepoint.com";
private static final String EMAIL_DOMAIN = "@your.company.com";
public static void main(String[] args) {
ProjectOnline dao = new ProjectOnline();
System.out.println(dao.getOAuthCookie());
}
private boolean needToUseOAuth(String username) {
if (username == null) return false;
return username.toLowerCase().endsWith(EMAIL_DOMAIN.toLowerCase());
}
public String getOAuthCookie() {
if (needToUseOAuth(USERNAME)) {
String samlSecurityToken = postLoginCredentialsToOurOAuthService();
if (samlSecurityToken != null && samlSecurityToken.isEmpty() == false) {
String binarySecurityToken = postSamlSecurityTokenToSecondSite(samlSecurityToken);
if (binarySecurityToken != null && binarySecurityToken.isEmpty() == false) {
String spoidcrlCookie = getSpoidcrlCookie(binarySecurityToken);
return spoidcrlCookie;
} else {
//System.out.println("getXMLDocument - OAuth authentication / authorization failed : Binary Security Token was not found");
logger.error("getOAuthCookie - OAuth authentication / authorization failed : Binary Security Token was not found");
}
} else {
//System.out.println("getXMLDocument - OAuth authentication / authorization failed : SAML Security Token was not found");
logger.error("getOAuthCookie - OAuth authentication / authorization failed : SAML Security Token was not found");
}
}
return "";
}
// Step 1 - Find the URL to your company's OAuth site
private String getOurOAuthServerURL(String emailAddress) {
DefaultHttpClient httpclient = new DefaultHttpClient();
// Go to this site, passing in email address. Should tell the URL for your company's OAuth site
HttpPost httppost = new HttpPost("https://login.microsoftonline.com/GetUserRealm.srf?xml=1&login=" + emailAddress);
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String status = response.getStatusLine().toString();
//System.out.println("getOurOAuthServerURL - status = " + status);
logger.info("getOurOAuthServerURL - status = " + status);
// If response status doesn't equal 'OK' then it didn't work.
if (entity != null && "HTTP/1.1 200 OK".equals(status)) {
StringWriter writer = new StringWriter();
IOUtils.copy(entity.getContent(), writer, "utf-8");
String xml = writer.toString();
//System.out.println(xml);
//logger.debug(xml);
String ourAuthURL = getSTSAuthURL(xml);
//System.out.println("ourAuthURL = " + ourAuthURL);
return ourAuthURL;
}
} catch (UnsupportedEncodingException e) {
logger.error("getOurOAuthServerURL ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (ClientProtocolException e) {
logger.error("getOurOAuthServerURL ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IllegalStateException e) {
logger.error("getOurOAuthServerURL ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IOException e) {
logger.error("getOurOAuthServerURL ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
return "";
}
private String getBinarySecurityToken(String xml) {
return getValuesBetweenTags(xml, "<wsse:BinarySecurityToken Id=\"Compact0\">", "</wsse:BinarySecurityToken>");
}
private String getSTSAuthURL(String xml) {
return getValuesBetweenTags(xml, "<STSAuthURL>", "</STSAuthURL>");
}
private String getSamlSecurityToken(String xml) {
return getValuesBetweenTags(xml, "<t:RequestedSecurityToken>", "</t:RequestedSecurityToken>");
}
private String getValuesBetweenTags(String xml, String tagToLeft, String tagToRight) {
if (xml == null || xml.isEmpty()) return "";
int startToken = xml.indexOf(tagToLeft);
if (startToken > -1) {
return xml.substring(startToken + tagToLeft.length(), xml.indexOf(tagToRight, startToken));
} else {
return "";
}
}
private String getTimeString(int minutesInFuture) {
Calendar rightNow = Calendar.getInstance();
rightNow.add(Calendar.SECOND, (((rightNow.get(Calendar.ZONE_OFFSET) + (rightNow.get(Calendar.DST_OFFSET)))/-1000)));
rightNow.add(Calendar.MINUTE, minutesInFuture);
String timeString = String.format("%d-%02d-%02dT%02d:%02d:%02d.0000000Z",
rightNow.get(Calendar.YEAR),
(rightNow.get(Calendar.MONTH) + 1),
rightNow.get(Calendar.DATE),
rightNow.get(Calendar.HOUR_OF_DAY),
rightNow.get(Calendar.MINUTE),
rightNow.get(Calendar.SECOND));
return timeString;
}
// Step 2 - POST an XML message, with a few key fields filled in (rest can be left as-is)
// This should be sent to your company's OAuth site
private String postLoginCredentialsToOurOAuthService() {
String ourOAuthService = getOurOAuthServerURL(USERNAME);
DefaultHttpClient httpclient = new DefaultHttpClient();
StringBuilder xmlString = new StringBuilder();
xmlString.append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" ");
xmlString.append("xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" ");
xmlString.append("xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" ");
xmlString.append("xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\" ");
xmlString.append("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" ");
xmlString.append("xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" ");
xmlString.append("xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2005/02/sc\" ");
xmlString.append("xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\"> ");
xmlString.append("<s:Header> ");
xmlString.append("<wsa:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action> ");
xmlString.append("<wsa:To s:mustUnderstand=\"1\">" + ourOAuthService + "</wsa:To> ");
xmlString.append("<wsa:MessageID>").append(UUID.randomUUID().toString()).append("</wsa:MessageID> ");
xmlString.append("<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\"> ");
xmlString.append("<ps:HostingApp>Managed IDCRL</ps:HostingApp> ");
xmlString.append("<ps:BinaryVersion>6</ps:BinaryVersion> ");
xmlString.append("<ps:UIVersion>1</ps:UIVersion> ");
xmlString.append("<ps:Cookies></ps:Cookies> ");
xmlString.append("<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams> ");
xmlString.append("</ps:AuthInfo> ");
xmlString.append("<wsse:Security> ");
xmlString.append("<wsse:UsernameToken wsu:Id=\"user\"> ");
xmlString.append("<wsse:Username>").append(USERNAME).append("</wsse:Username> ");
xmlString.append("<wsse:Password>").append(PASSWORD).append("</wsse:Password> ");
xmlString.append("</wsse:UsernameToken> ");
xmlString.append("<wsu:Timestamp Id=\"Timestamp\"> ");
xmlString.append("<wsu:Created>" + getTimeString(0) + "</wsu:Created> ");
xmlString.append("<wsu:Expires>" + getTimeString(10) + "</wsu:Expires> ");
xmlString.append("</wsu:Timestamp> ");
xmlString.append("</wsse:Security> ");
xmlString.append("</s:Header> ");
xmlString.append("<s:Body> ");
xmlString.append("<wst:RequestSecurityToken Id=\"RST0\"> ");
xmlString.append("<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType> ");
xmlString.append("<wsp:AppliesTo> ");
xmlString.append("<wsa:EndpointReference> ");
xmlString.append("<wsa:Address>urn:federation:MicrosoftOnline</wsa:Address> ");
xmlString.append("</wsa:EndpointReference> ");
xmlString.append("</wsp:AppliesTo> ");
xmlString.append("<wst:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</wst:KeyType> ");
xmlString.append("</wst:RequestSecurityToken> ");
xmlString.append("</s:Body> ");
xmlString.append("</s:Envelope> ");
HttpPost httppost = new HttpPost(ourOAuthService);
try {
httppost.addHeader("Content-Type", "application/soap+xml; charset=utf-8");
httppost.setEntity(new StringEntity(xmlString.toString()));// Set this in the body
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String status = response.getStatusLine().toString();
//System.out.println("postLoginCredentialsToOurOAuthService - status = " + status);
logger.info("postLoginCredentialsToOurOAuthService - status = " + status);
// If response status doesn't equal 'OK' then it didn't work.
if (entity != null && "HTTP/1.1 200 OK".equals(status)) {
StringWriter writer = new StringWriter();
IOUtils.copy(entity.getContent(), writer, "utf-8");
String xml = writer.toString();
//System.out.println(xml);
//logger.debug(xml);
// Now, extract out the SAML Security Token. It is several lines (~49, if you parse it out).
String samlSecurityToken = getSamlSecurityToken(xml);
//System.out.println("samlSecurityToken = " + samlSecurityToken);
return samlSecurityToken;
}
} catch (UnsupportedEncodingException e) {
logger.error("postLoginCredentialsToOurOAuthService ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (ClientProtocolException e) {
logger.error("postLoginCredentialsToOurOAuthService ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IllegalStateException e) {
logger.error("postLoginCredentialsToOurOAuthService ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IOException e) {
logger.error("postLoginCredentialsToOurOAuthService ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
return "";
}
// Step 3 - Now that you have the SAML Security Token, you embed it within some other generic XML, and send back to Microsoft server
private String postSamlSecurityTokenToSecondSite(String samlSecurityToken) {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost("https://login.microsoftonline.com/rst2.srf");
httppost.addHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)");
StringBuilder xmlString = new StringBuilder();
xmlString.append("<S:Envelope xmlns:S=\"http://www.w3.org/2003/05/soap-envelope\" ");
xmlString.append("xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" ");
xmlString.append("xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\" ");
xmlString.append("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" ");
xmlString.append("xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" ");
xmlString.append("xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\">");
xmlString.append("<S:Header>");
xmlString.append("<wsa:Action S:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>");
xmlString.append("<wsa:To S:mustUnderstand=\"1\">https://login.microsoftonline.com/rst2.srf</wsa:To>");
xmlString.append("<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/LiveID/SoapServices/v1\" Id=\"PPAuthInfo\">");
xmlString.append("<ps:BinaryVersion>5</ps:BinaryVersion>");
xmlString.append("<ps:HostingApp>Managed IDCRL</ps:HostingApp>");
xmlString.append("</ps:AuthInfo>");
xmlString.append("<wsse:Security>");
xmlString.append(samlSecurityToken);
xmlString.append("</wsse:Security>");
xmlString.append("</S:Header>");
xmlString.append("<S:Body>");
xmlString.append("<wst:RequestSecurityToken xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\" Id=\"RST0\">");
xmlString.append("<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>");
xmlString.append("<wsp:AppliesTo>");
xmlString.append("<wsa:EndpointReference>");
xmlString.append("<wsa:Address>sharepoint.com</wsa:Address>");
xmlString.append("</wsa:EndpointReference>");
xmlString.append("</wsp:AppliesTo>");
xmlString.append("<wsp:PolicyReference URI=\"MBI\"></wsp:PolicyReference>");
xmlString.append("</wst:RequestSecurityToken>");
xmlString.append("</S:Body>");
xmlString.append("</S:Envelope>");
httppost.addHeader("Content-Type", "application/soap+xml; charset=utf-8");
httppost.setEntity(new StringEntity(xmlString.toString()));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String status = response.getStatusLine().toString();
//System.out.println("postSamlSecurityTokenToSecondSite - status = " + status);
logger.info("postSamlSecurityTokenToSecondSite - status = " + status);
// If response status doesn't equal 'OK' then it didn't work.
if (entity != null && "HTTP/1.1 200 OK".equals(status)) {
StringWriter writer = new StringWriter();
IOUtils.copy(entity.getContent(), writer, "utf-8");
String xml = writer.toString();
//System.out.println(xml);
//logger.debug(xml);
// Extract out the value from just one, single line of this returned XML file
String binarySecurityToken = getBinarySecurityToken(xml);
//System.out.println("binarySecurityToken = " + binarySecurityToken);
return binarySecurityToken;
}
} catch (UnsupportedEncodingException e) {
logger.error("postSamlSecurityTokenToSecondSite ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (ClientProtocolException e) {
logger.error("postSamlSecurityTokenToSecondSite ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IllegalStateException e) {
logger.error("postSamlSecurityTokenToSecondSite ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IOException e) {
logger.error("postSamlSecurityTokenToSecondSite ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
return "";
}
// Step 4 - Using the extracted value, the Binary Security Token, build a header, and add it to the next request
// This will go to your own Project Online server, which should return back a reply message, containing a 'Set-Cookie' cookie with 'SPOIDCRL' in the value
private String getSpoidcrlCookie(String binarySecurityToken) {
try {
HttpGet httpget = new HttpGet(PROJECT_SERVER + "/_vti_bin/idcrl.svc/");
httpget.addHeader("Authorization", "BPOSIDCRL " + binarySecurityToken);
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpget);
String status = response.getStatusLine().toString();
//System.out.println("getSpoidcrlCookie - status = " + status);
logger.info("getSpoidcrlCookie - status = " + status);
// If response status doesn't equal 'OK' then it didn't work.
if ("HTTP/1.1 200 OK".equals(status)) {
Header[] headers = response.getHeaders("Set-Cookie");
for (Header header : headers) {
if (header.getValue().contains("SPOIDCRL")) {
String spoidcrlCookie = header.getValue();
//System.out.println("Found SPOIDCRL cookie : " + spoidcrlCookie);
return spoidcrlCookie;
}
}
}
} catch (ClientProtocolException e) {
logger.error("getSpoidcrlCookie ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IOException e) {
logger.error("getSpoidcrlCookie ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (Exception e) {
logger.error("getSpoidcrlCookie ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
}
return null;
}
public Document getXMLDocument(String strURL) {
String spoidcrlCookie = getOAuthCookie();
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(strURL);
try {
URL url = new URL(strURL);
if (needToUseOAuth(USERNAME)) {
httpget.addHeader("Cookie", spoidcrlCookie);
} else {
// Otherwise, can just use this simple way of logging in, using the Domain
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM, AuthScope.ANY_SCHEME),
new NTCredentials(
USERNAME,
PASSWORD,
url.getHost(),
DOMAIN));
}
//System.out.println("getXMLDocument - strURL " + strURL);
//logger.info("getXMLDocument - strURL " + strURL);
//logger.info("getXMLDocument - executing request " + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);//httppost
HttpEntity entity = response.getEntity();
//logger.info("getXMLDocument - ----------------------------------------");
//for (Header header : response.getAllHeaders()) {
// System.out.println("getXMLDocument - header = " + header.toString());
//}
String status = response.getStatusLine().toString();
//System.out.println("getXMLDocument - status = " + status);
//logger.info("getXMLDocument - status = " + status);
// If response status doesn't equal 'OK' then it didn't work.
if (entity != null && "HTTP/1.1 200 OK".equals(status)) {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
StringWriter writer = new StringWriter();
IOUtils.copy(entity.getContent(), writer, "utf-8");
String xml = writer.toString();
//System.out.println(xml);
//logger.debug(xml);
if (xml.endsWith("</feed>") == false) {
//logger.warn("The XML did not end with </feed>");
xml = xml + "</feed>";
}
InputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
Document doc = docBuilder.parse(inputStream);
return doc;
} else {
logger.error("getXMLDocument - status = " + status);
}
} catch (ClientProtocolException e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IOException e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (ParserConfigurationException e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (IllegalStateException e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (SAXException e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} catch (Exception e) {
logger.error("getXMLDocument ERROR | SHORT ERROR MESSAGE: " + e.getMessage() + " FULL ERROR MESSAGE: " + e.toString());
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
logger.warn("Exiting from getXMLDocument but returning null");
return null;
}
}
关于java - 尽管我使用正确的 OAuth token ,但尝试从 Java 应用程序访问托管的 SharePoint 2013 会给我 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25323613/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!