post data using Sharepoint 2010 REST API using Java http client - java

I am trying to post a SharePoint list item to a SharePoint 2010 list using Java client.
I am able to read the SP list items using below code but I am not sure how to write to the SharePoint.
For the post operation, I am getting http 401 error.
Any guidance will be greatly appreciated.
GET Operation:
String url = "https://organization.company.com/sites/Ateam/_vti_bin/ListData.svc/TableLoadInfo"; DefaultHttpClient client = new DefaultHttpClient();
NTCredentials credentials = new NTCredentials(username, password, hostname, domain);
AuthScope scope = new AuthScope(hostname, 443);
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { trustmanager }, null);
SSLSocketFactory sf = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", 443, sf);
client.getConnectionManager().getSchemeRegistry().register(https);
client.getCredentialsProvider().setCredentials(scope, credentials);
HttpGet request = new HttpGet(url);
//request.addHeader("Accept", "application/xml");
request.addHeader("Accept", "application/json;odata=verbose");
HttpResponse response = client.execute(request);
POST Operation:
String url = "https://organization.company.com/sites/Ateam/_vti_bin/ListData.svc/TableLoadInfo";
DefaultHttpClient client = new DefaultHttpClient();
NTCredentials credentials = new NTCredentials(username, password, hostname, domain);
AuthScope scope = new AuthScope(hostname, 443);
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { trustmanager }, null);
SSLSocketFactory sf = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", 443, sf);
client.getConnectionManager().getSchemeRegistry().register(https);
client.getCredentialsProvider().setCredentials(scope, credentials);
// POST a data
HttpPost request = new HttpPost(url);
request.addHeader("Accept", "application/json;odata=verbose");
request.addHeader("Content-type", "application/json;odata=verbose");
// request.addHeader("X-RequestDigest", FormDigestValue);
request.addHeader("X-HTTP-Method", "POST");
request.addHeader("If-Match", "*");
JSONStringer json = (JSONStringer) new JSONStringer().object().key("Table_Name").value("TableName 1")
.key("Load_Frequency").value("Weekly").key("Cycle").value("CURRENT").endObject();
StringEntity se = new StringEntity(json.toString());
request.setEntity(se);
HttpResponse response = client.execute(request);

When you post data to SharePoint you have to add "FormDigestValue" inside the header.
Please Note you have commented the line "request.addHeader("X-RequestDigest", FormDigestValue);".
That is the reason you get 401 Error.
First you have to get the "FormDigestValue" value form your current site.
Then add that value inside the header.
Following Code shows the way to get the FormDigestValue.
String digestqueryURL = serverurl + subsite + "/" + "_api/contextinfo";
HttpPost httpPost = new HttpPost(digestquery);
httpPost.addHeader("Accept", "application/json;odata=verbose");
httpPost.addHeader("X-ClientService-ClientTag", "SDK-JAVA");
HttpResponse response = httpClient.execute(httpPost);
byte[] content = EntityUtils.toByteArray(response.getEntity());
String jsonString = new String(content, "UTF-8");
JSONObject json = new JSONObject(jsonString);
String FormDigestValue = json.getJSONObject("d")
.getJSONObject("GetContextWebInformation")
.getString("FormDigestValue");
Then add the FormDigestValue to the header when you do the post operations.
request.addHeader("X-RequestDigest", FormDigestValue);

Related

Java URIBuilder are in unnamed module of loader 'app'

I woudlike to execute GET request :
HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
URIBuilder uriBuilder = new URIBuilder(request.getURI())
.addParameter("code", "001")
.addParameter("name", "AAA")
String auth = user + ":" + mdp;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(StandardCharsets.ISO_8859_1));
String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute((HttpUriRequest) uriBuilder);
int statusCode = response.getStatusLine().getStatusCode();
When I try to catch my HTTPResponse client.execute((HttpUriRequest) uriBuilder);
I have this error :
java.lang.ClassCastException: class org.apache.http.client.utils.URIBuilder cannot be cast to class org.apache.http.client.methods.HttpUriRequest (org.apache.http.client.utils.URIBuilder and org.apache.http.client.methods.HttpUriRequest are in unnamed module of loader 'app')
You are facing the error because you are trying to cast an instance of URIBuilder to HttpUriRequest.
You need to create an appropriate HttpUriRequest implementation in order to execute your HTTP request.
In your use case I suppose it should looks like this:
URIBuilder uriBuilder = new URIBuilder(URL_SECURED_BY_BASIC_AUTHENTICATION)
.addParameter("code", "001")
.addParameter("name", "AAA");
URI uri = uriBuilder.build();
HttpGet request = new HttpGet(uri);
String auth = user + ":" + mdp;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(StandardCharsets.ISO_8859_1));
String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
It seems for your comment that you are trying to connect to a site using SSL: the problem is that your Java code does not trust the server.
You need to configure a valid certificate chain and instruct your code to use it in order to solve the problem.
Apache Client does not rely on the standard JSSE mechanism for this purpose. Instead, you need to configure a SSLContext with an appropriate TrustManager. Please, see the following code (the first part is derived from this extraordinary documentation fragment in the Android developer site):
// Load your server certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream input = new BufferedInputStream(
new FileInputStream("server.crt")
);
Certificate certificate;
try {
certificate = cf.generateCertificate(input);
} finally {
input.close();
}
// Create an in-memory KeyStore containing the server certificate
// It is required in order to configure the TrustManager
String keyStoreType = KeyStore.getDefaultType(); // JKS
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("cert", certificate);
// Create a TrustManager that trusts the server certificates in the KeyStore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
);
trustManagerFactory.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManagerFactory.getTrustManagers(), null);
// Now, the actual Apache Client part
//Create a SSLConnectionSocketFactory and pass it the above created SSLContext
SSLConnectionSocketFactory factory =
new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier()
);
//Create the actual HttpClient
CloseableHttpClient client = HttpClients
.custom()
.setSSLSocketFactory(factory)
.build()
;
// Use this client to perform your HTTP invocation
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
You can obtain the server certificate from your browser or with tools like openssl. Please, see this great SO question.

REST webservice call for HTTPS link - 400 Bad Request error

Using SOAP UI, I am able to successfully invoke the REST GET call with basic authentication
GET https://app.test.com/testing/rest/authentication-point/authentication HTTP/1.1
Accept-Encoding: gzip,deflate
Authorization: Basic aPOjYVclOmIzABFhZjVpJES=
Host: app.test.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
I received response code as 200.
Similar request, When I tried to invoke via java client, it is giving 400 status code.
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
int statusCode = response.getStatusLine().getStatusCode();
This code worked properly when the host was HTTP. Recently a VIP is added and made as HTTPS, after which it is not working. Please suggest a fix for this.
You need to use ssl with http client:
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLSocketFactory sf = new SSLSocketFactory(
acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 8443, sf));
ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
DefaultHttpClient httpClient = new DefaultHttpClient(ccm);
HttpGet getMethod = new HttpGet(new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),context);
HttpResponse response = httpClient.execute(getMethod);
int statusCode = response.getStatusLine().getStatusCode();
After trying out so many options, below code worked for me.
HttpHost targetHost = new HttpHost("app.test.com", 443, "https");
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
After defining a HTTP host with scheme as https, and setting them to context using AuthCache, the call went through successfully.

HttpClient java.net.UnknownHostException exception when the CURL command passes

I am trying to use httpclient to make make a call to Jenkins to get a list of jobs.
When I run my code, I get an UnknownHostException.
I tried to make the same request using curl and I was able to get the result. I am not sure how to interpret this.
void nwe() throws ClientProtocolException, IOException {
HttpHost target = new HttpHost("https://<JENKINS_URL>/api");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials("username", "password"));
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpGet httpGet = new HttpGet("/json");
httpGet.setHeader("Content-type", "application/json");
BasicScheme basicAuth = new BasicScheme();
HttpClientContext localContext = HttpClientContext.create();
CloseableHttpResponse response1 = httpclient.execute(target, httpGet, localContext);
System.out.println(response1.getStatusLine());
}
The CURL command on the same URL gives me the expected output
Thanks,
Amar
Read the JavaDoc for HttpHost:
Parameters: hostname - the hostname (IP or DNS name)
So you should use just (omit the protocol and context):
HttpHost target = new HttpHost( "<JENKINS_URL>" );
and then HttpGet the /api/json part.
Cheers,

NTLM authentication java via HttpClient

My problem is i'm trying to get into scopus using a crawler but it requires my crawler to enter the site through my school proxy server. I tried authenticating but it keep responding with 401 status.
public void testConnection() throws ClientProtocolException, IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
List<String> authpref = new ArrayList<String>();
authpref.add(AuthPolicy.NTLM);
httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
NTCredentials creds = new NTCredentials("username","password","ezlibproxy1.ntu.edu.sg","ntu.edu.sg");//this is correct
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpHost target = new HttpHost("ezlibproxy1.ntu.edu.sg", 443, "https");//this is correct
// 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://www-scopus-com.ezlibproxy1.ntu.edu.sg/authid/detail.url?authorId=14831850700");
HttpResponse response = httpclient.execute(target, httpget, localContext);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("Status Code:" + statusCode);
}
The status code respond is 401 (unauthorised).
Any suggestion on this?

java- unknown host exception when using apache http client

I am trying to make a simple GET request for a website, but I am getting unknown host exception.
Given below is my code--
DefaultHttpClient client = new DefaultHttpClient();
HttpHost targetHost=null;
targetHost= new HttpHost("google.com/", 80, "http");
HttpGet httpget = new HttpGet("about-us.html");
BasicHttpContext localcontext = new BasicHttpContext();
try {
HttpResponse response = client.execute(targetHost, httpget, localcontext);
It looks like you have a simple problem here.
The URL for your 'HttpHost' object is malformed. You need to drop the '/' from "google.com/".
It should work after that. I used your code with that single modification & it worked.
DefaultHttpClient client = new DefaultHttpClient();
HttpHost targetHost = new HttpHost("google.com", 80, "http");
HttpGet httpget = new HttpGet("about-us.html");
BasicHttpContext localContext = new BasicHttpContext();
HttpResponse response = null;
try { response = client.execute(targetHost, httpget, localContext);
System.out.println(response.getStatusLine()
}
catch(Exception e){
// Enter error-handling code here.
}

Categories