获取salesforce access_token
前面文章中我们已经简单的对salesforce的rest接口做了简单的介绍,如果对java的servlet比较了解的话,理解起来应该很简单。
我们这篇文章主要是介绍如何通过java程序获取到salesforce的access_Token,怎么理解这里的access_token,通俗的讲,就是通过一系列既定的参数,来换取一个token认证,根据这个token才有权限去调用接口。
获取access_token我们需要哪些参数:
- 连接程序的appid
- 连接程序的appsecret
- userName
- password
1.如上图中所示:我们一次点击 设置 —> 创建 —> 应用程序 —> 连接的应用程序,如果初次使用创建一个即可。类似图中所示的那样
2.userName 和 password 这两个参数,是系统内要为我们准备一个用于接口使用的license,此user设置成使用api登录即可。
获取access_token
package cn.lnc.course.util;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
public class GetTokenUtil {
public static Log log=LogFactory.getLog(GetTokenUtil.class);
public static void main(String[] args) throws Exception {
OperateProperties properties = new OperateProperties();
Map<String,String> weChatMap = properties.getProperties("/SFDC.properties");
System.out.println(getAccesToken(weChatMap.get("clientId"),weChatMap.get("clientSecret"),weChatMap.get("username"),weChatMap.get("password")));
}
public static String getAccesToken(String clientId,String clientSecret,String userName,String password){
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("grant_type","password"));
formparams.add(new BasicNameValuePair("client_id",clientId));
formparams.add(new BasicNameValuePair("client_secret",clientSecret));
formparams.add(new BasicNameValuePair("username",userName));
formparams.add(new BasicNameValuePair("password",password));
UrlEncodedFormEntity uefEntity;
try {
OperateProperties properties = new OperateProperties();
Map<String,String> oauthMap = properties.getProperties("/SFDCInterface.properties");
System.out.println("===获取Token===");
String oauthUrl = oauthMap.get("oauthAction");
uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
Map<String, String> resMaps = post(oauthUrl, uefEntity, null);
String resString = resMaps.get("body");
Pattern pattern = Pattern.compile("\\{\\\"access_token\\\":\\\"(.*?)\\\"");
Matcher matche = pattern.matcher(resString);
while(matche.find()) {
log.debug("===获取Token===");
System.out.println("===成功返回==="+matche.group(1));
return matche.group(1);
}
return null;
} catch (Exception e) {
System.out.println("===异常返回==="+e.getMessage());
}
return null;
}
private static CloseableHttpClient buildSSLCloseableHttpClient() throws Exception {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
//信任所有
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory factory=new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1","TLSv1.1"},sslContext.getDefaultSSLParameters().getCipherSuites(),
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
return HttpClients.custom().setSSLSocketFactory(factory).build();
}
public static Map<String, String> post(String url, HttpEntity uefEntity, Map<String, String> headerMaps) throws Exception{
CloseableHttpClient httpclient = buildSSLCloseableHttpClient();
HttpPost httppost = new HttpPost(url);
if(headerMaps != null){
for (String key : headerMaps.keySet()) {
httppost.addHeader(key, headerMaps.get(key));
}
}
httppost.setEntity(uefEntity);
try {
CloseableHttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
String body = (resEntity != null ? EntityUtils.toString(resEntity, "UTF-8") : "");
System.out.println("---------body-----------" + body);
Map<String, String> resMaps = new HashMap<String, String>();
resMaps.put("status", response.getStatusLine().toString());
resMaps.put("body", body);
return resMaps;
} catch (IOException e) {
throw e;
} finally {
try {
httpclient.close();
} catch (IOException e) {
System.out.println("捕获到异常");
}
}
}
}
SFDC.properties
clientId=3MVG9YDQS5WtC1xxxxxxrsvzbZunFqfcxl3NR4mM5tieQ0vmPxHyCOlEKJFhmqj8FJuH.51dK7
clientSecret=5780xxxxxx44475
username=[email protected]
password=xxxxxx
token=00D0k0000000crc!ARMAQOvF4whWOxxxxxxxOyXBb0cBLQ_xxxxxxx8c_pLK0PFmpVGxVldUXuITo3cYKP1
使用获取的access_token 调用接口
package cn.lnc.course.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class SFDCSendUtil {
/**
* 向SFDC推送数据工具类
*
* @author ningchao.li
* @date 2018-07-31
* @param action 这个是放到SFDCInterface.properties维护使用的,通过配置文件维护接口名称
*/
public static String sendReq(String action,String jsonStr) throws Exception {
System.out.println("发送数据1");
String result = "";
//获取token,不再每次获取Token,使用定时任务,每隔两个小时自动进行获取。
//String token = getAccesToken();
OperateProperties properties = new OperateProperties();
Map<String,String> weChatMap = properties.getProperties("/SFDC.properties");
String token = weChatMap.get("token");
// String s = "{\"requestPara\":{\"Request_Id\":\"DJ001\"}}";
StringEntity emtity = new StringEntity(jsonStr,"utf-8");
Map<String,String> map= new HashMap<String, String>();
map.put("Authorization", "Bearer " + token);
map.put("Content-Type", "application/json;charset=utf-8 ");
System.out.println("发送数据2");
try {
// 根据配置文件读取需要调用的接口地址
Map<String,String> urlMap = properties.getProperties("/SFDCInterface.properties");
// 配置文件中写明接口地址,通过此处获取URL
String oauthUrl = urlMap.get(action);
Map<String,String> resultMap = GetTokenUtil.post(oauthUrl,emtity,map);
result = resultMap.get("body");
System.out.println("接口调用结果"+resultMap);
} catch (Exception e) {
System.out.println("Exception"+e);
}
return result;
}
}
SFDCInterface.properties
CreateAccount=https://ap4.salesforce.com/services/apexrest/Rest_CreateAccount
oauthAction=https://liningchao-dev-ed.my.salesforce.com/services/oauth2/token
CreateWeChatUser=https\://ap4.salesforce.com/services/apexrest/Rest_CreateWeChatUser
如上代码中我们实现了获取salesforce 的 token,并且实现了根据token调用SFDC接口的功能。事实上,我们还可以将获取token的代码不放到调用接口前,而是做一个定时的程序。当然如果是一个web应用的话,直接放到监听器中就可以。目的就是每隔两个小时就自动的去刷新配置文件中的token的值,这样就能够保证api的完全利用价值。 (token的时效性是两个小时。)