如何在JavaServer Pages中使用Salesforce REST API

摘要:本教程提供了一个JSP示例以及如何将其与Salesforce REST API集成。 我们将逐步完成创建外部客户端以使用Force.com (同时使用HTTP(S)和JSON)管理您的数据的分步过程。

在此示例中,我将Mac OS X 10.9.2与Apache Tomcat 7服务器和Java 1.7一起使用。 Eclipse Java EE版是用于开发和测试的IDE。 本教程中给出的说明也应适用于其他平台的较小修改。

如果要访问本教程中的整个示例代码,则可以在以下位置访问它: github.com/seethaa/force_rest_example

所有代码已更新为可与httpclient 4.3库一起使用。

什么是REST?

REST代表表象小号泰特贸易交接,并且是无状态的客户端-服务器通信协议通过HTTP。

为什么以及何时在Java中为JSP使用REST API

REST API非常适合需要大量交互并使用同步通信来传输数据的浏览器应用程序。 Salesforce REST API为简单的Web服务提供了与Force.com进行交互的编程接口,并支持XML和JSON格式。 Salesforce REST API非常适合移动应用程序或动态网站,以在Web服务器上快速检索或更新记录。 虽然应为BulkAPI保留批量记录检索,但此轻量级的REST API可以用于常见服务器页面,这些页面涉及快速更新和频繁的用户交互,例如更新单个用户记录。

设置您的开发帐户和前提条件

您将需要以下内容:

  1. 转到https://developer.salesforce.com/signup并注册您的免费DE帐户。 就本示例而言,即使您已经有一个帐户,我也建议注册一个Developer Edition。 这样可以确保您在启用了最新功能的情况下获得干净的环境。
  2. Java应用程序服务器。 我在Mac OS X和Eclipse上使用Apache Tomcat 7作为IDE创建了我的数据库。 http://developer.salesforce.com/page/Force.com_IDE上还有一个免费的Eclipse插件,但本教程使用了原始的Eclipse设置。
  3. 使用http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html在Tomcat服务器上配置SSL。 如果您在Eclipse中进行开发,请确保在Eclipse环境中的server.xml文件中添加连接器部分,例如:
  4. 将所需的jar文件添加到WebContent / WEBINF / lib。 您将需要commons-codec-1.6.jar , httpclient4.3.3.jar , httpcore-4.3.2.jar , commons-logging-1.1.3.jar和java-json.jar 。 对于Eclipse,我还必须确保所有jar都已添加到构建路径(右键单击Project→Build Path→配置构建路径→选择Libraries选项卡→单击Add Jars→从WEBINF / lib文件夹中选择Jar文件。

创建一个连接的应用程序

  1. 返回Force.com DE,通过控制台创建一个新的Connected App。 单击设置→构建→创建→应用程序。 向下滚动到“已连接的应用程序”部分,然后单击“新建”按钮。
    • 确保回调URL为http:// localhost:8080 / / oauth / _callback

      (您可以通过返回Eclipse找到应用程序上下文路径:右键单击Project→Properties→Web Project Settings→Context root)

    • 选中“启用OAuth设置”复选框
    • 本教程所需的OAuth范围(请参见图1)是“访问和管理数据(api)”和“通过Web提供对数据的访问”(web),但是应根据您的要求更改这些范围。
    • 如何在JavaServer Pages中使用Salesforce REST API_第1张图片

      图1:创建新的连接的应用程序

  2. 复制ClientID和Client Secret(参见图2),因为这两个都将在下一步中使用。
    如何在JavaServer Pages中使用Salesforce REST API_第2张图片

    图2:具有用户密钥和机密的连接的应用程序示例

    认证方式

    需要将三个文件导入到您的JSP项目中,如下所示:

    index.html

    
    
    
    
    REST/OAuth Example
    
    
    	
    
    

    OAuthConnectedApp.java

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebInitParam;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.http.Consts; 
    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.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicNameValuePair;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    import org.json.JSONTokener;
    
    @WebServlet(name  = "oauth", urlPatterns = { "/oauth/*", "/oauth" }, initParams = {
    // clientId is 'Consumer Key' in the Remote Access UI
    //**Update with your own Client ID
    @WebInitParam(name  = "clientId", value = "3MVG9JZ_r.QzrS7jzujCYrebr8kajDEcjXQLXnV9nGU6PaxOjuOi_n8EcUf0Ix9qqk1lYCa4_Jaq7mpqxi2YT"),
    // clientSecret is 'Consumer Secret' in the Remote Access UI
    //**Update with your own Client Secret
    @WebInitParam(name  = "clientSecret", value = "2307033558641049067"),
    // This must be identical to 'Callback URL' in the Remote Access UI
    //**Update with your own URI
    @WebInitParam(name  = "redirectUri", value = "http://localhost:8080/force_rest_example/oauth/_callback"),
    @WebInitParam(name  = "environment", value = "https://login.salesforce.com"), })
    
    /**
    * Servlet parameters
    * @author  seetha
    *
    */
    public class OAuthConnectedApp  extends HttpServlet {
    
    	private static final long serialVersionUID = 1L;
    
    	private static final String ACCESS_TOKEN = "ACCESS_TOKEN";
    	private static final String INSTANCE_URL = "INSTANCE_URL";
    
    	private String clientId = null;
    	private String clientSecret = null;
    	private String redirectUri = null;
    	private String environment = null;
    	private String authUrl = null;
    	private String tokenUrl = null;
    	
    	public void init() throws ServletException {
    		
    		clientId = this.getInitParameter("clientId");
    		clientSecret = this.getInitParameter("clientSecret");
    		redirectUri = this.getInitParameter("redirectUri");
    		environment = this.getInitParameter("environment");
    
    		try {
    
    			authUrl = environment
    			+ "/services/oauth2/authorize?response_type=code&client_id="
    			+ clientId + "&redirect_uri="
    			+ URLEncoder.encode(redirectUri, "UTF­8");
    		}
    		catch (UnsupportedEncodingException e) {
    			throw new ServletException(e);
    		}
    
    		tokenUrl = environment + "/services/oauth2/token";
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse  response) throws ServletException, IOException {
    	
    		String accessToken = (String) request.getSession().getAttribute(ACCESS_TOKEN);
    
    		//System.out.println("calling doget");
    		if (accessToken == null) {
    			String instanceUrl = null;
    
    			if (request.getRequestURI().endsWith("oauth")) {
    				// we need to send the user to authorize
    				response.sendRedirect(authUrl);
    				return;
    			}
    			else {
    				System.out.println("Auth successful ­ got callback");
    				String code = request.getParameter("code");
    
    				// Create an instance of HttpClient.
    				CloseableHttpClient  httpclient = HttpClients.createDefault();
    
    				try{
    					// Create an instance of HttpPost.
    					HttpPost httpost = new HttpPost(tokenUrl);
    
    					// Adding all form parameters in a List of type NameValuePair
    					List  nvps = new ArrayList();
    					nvps.add(new BasicNameValuePair("code", code));
    					nvps.add(new BasicNameValuePair("grant_type","authorization_code"));
    					nvps.add(new BasicNameValuePair("client_id", clientId));
    					nvps.add(new BasicNameValuePair("client_secret", clientSecret));
    					nvps.add(new BasicNameValuePair("redirect_uri", redirectUri));
    
    					httpost.setEntity(new  UrlEncodedFormEntity(nvps, Consts.UTF_8));
    					
    					// Execute the request.
    					CloseableHttpResponse closeableresponse=httpclient.execute(httpost);
    					System.out.println("Response Statusline:"+closeableresponse.getStatusLine());
    
    					try {
    						// Do the needful with entity.
    						HttpEntity entity = closeableresponse.getEntity();
    						InputStream rstream = entity.getContent();
    						JSONObject authResponse = new JSONObject(new JSONTokener(rstream));
    
    						accessToken = authResponse.getString("access_token");
    						instanceUrl = authResponse.getString("instance_url");
    
    					} catch (JSONException e) {
    						// TODO Auto­generated catch block e.printStackTrace();
    						e.printStackTrace();
    					} finally {
    						// Closing the response
    						closeableresponse.close();
    					}
    				} finally {
    					httpclient.close();
    				}
    
    			}
    
    			// Set a session attribute so that other servlets can get the access token
    			request.getSession().setAttribute(ACCESS_TOKEN, accessToken);
    
    			// We also get the instance URL from the OAuth response, so set it in the session too
    			request.getSession().setAttribute(INSTANCE_URL, instanceUrl);
    		}
    
    		response.sendRedirect(request.getContextPath() + "/ConnectedAppREST");
    	}
    	
    }

    ConnectedAppREST.java

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.net.URISyntaxException;
    import java.util.Iterator;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpDelete;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    import org.json.JSONTokener;
    
    @WebServlet(urlPatterns = { "/ConnectedAppREST"  })
    /**
    * Demo for Connect App/REST API
    * @author  seetha
    *
    */
    public class ConnectedAppREST  extends HttpServlet {
    
    	private static final long serialVersionUID = 1L;
    	private static final String ACCESS_TOKEN = "ACCESS_TOKEN";
    	private static final String INSTANCE_URL = "INSTANCE_URL";
    	
    	private void showAccounts(String  instanceUrl, String accessToken,
    		PrintWriter writer) throws ServletException, IOException {
    		
    		CloseableHttpClient  httpclient = HttpClients.createDefault();
    
    		HttpGet httpGet = new HttpGet();
    
    		//add key and value
    		httpGet.addHeader("Authorization", "OAuth " + accessToken);
    
    		try {
    		
    			URIBuilder builder = new URIBuilder(instanceUrl+ "/services/data/v30.0/query");
    			builder.setParameter("q", "SELECT Name, Id from Account LIMIT 100");
    
    			httpGet.setURI(builder.build());
    
    			CloseableHttpResponse  closeableresponse = httpclient.execute(httpGet);
    			System.out.println("Response Status line :" + closeableresponse.getStatusLine());
    			
    			if (closeableresponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    				// Now lets use the standard java json classes to work with the results
    				try {
    					// Do the needful with entity.
    					HttpEntity entity = closeableresponse.getEntity();
    					InputStream rstream = entity.getContent();
    					JSONObject authResponse = new JSONObject(new JSONTokener(rstream));
    
    					System.out.println("Query response: " + authResponse.toString(2));
    
    					writer.write(authResponse.getInt("totalSize") + " record(s) returned\n\n");
    
    					JSONArray results = authResponse.getJSONArray("records");
    					
    					for (int i = 0; i < results.length(); i++) {
    					writer.write(results.getJSONObject(i).getString("Id")
    						+ ", "
    						+ results.getJSONObject(i).getString("Name")
    						+ "\n");
    					}
    					
    					writer.write("\n");
    				}
    				catch (JSONException e) {
    					e.printStackTrace();
    					throw new ServletException(e);
    				}
    			}
    			
    		} catch (URISyntaxException  e1) {
    			// TODO Auto­generated catch block
    			e1.printStackTrace();
    		} finally {
    			httpclient.close();
    		}
    	}
    	
    	private String createAccount(String  name, String instanceUrl,
    		String accessToken, PrintWriter writer) throws ServletException, IOException {
    		
    		String accountId = null;
    		CloseableHttpClient  httpclient = HttpClients.createDefault();
    		JSONObject account = new JSONObject();
    		
    		try {
    			account.put("Name",  name);
    		}
    		catch (JSONException e) {
    			e.printStackTrace();
    			throw new ServletException(e);
    		}
    		
    		HttpPost httpost = new HttpPost(instanceUrl+  "/services/data/v30.0/sobjects/Account/");
    
    		httpost.addHeader("Authorization", "OAuth " + accessToken);
    
    		StringEntity messageEntity = new StringEntity( account.toString(), ContentType.create("application/json"));
    
    		httpost.setEntity(messageEntity);
    
    		// Execute the request.
    		CloseableHttpResponse  closeableresponse = httpclient.execute(httpost);
    		System.out.println("Response Status line :" + closeableresponse.getStatusLine());
    		
    		try {
    		
    			writer.write("HTTP status " + closeableresponse.getStatusLine().getStatusCode() + " creating account\n\n");
    
    			if (closeableresponse.getStatusLine().getStatusCode()  == HttpStatus.SC_CREATED) {
    			
    				try {
    				
    					// Do the needful with entity.
    					HttpEntity entity = closeableresponse.getEntity();
    					InputStream rstream = entity.getContent();
    					JSONObject authResponse = new JSONObject(new JSONTokener(rstream));
    					
    					System.out.println("Create response: " + authResponse.toString(2));
    
    					if (authResponse.getBoolean("success")) {
    						accountId = authResponse.getString("id");
    						writer.write("New record id " + accountId + "\n\n");
    					}
    					
    				} catch (JSONException e) {
    					e.printStackTrace();
    					// throw new ServletException(e);
    				}
    			}
    		}
    		finally {
    			httpclient.close();
    		}
    
    		return accountId;
    	}
    	
    	private void showAccount(String  accountId, String instanceUrl,
    		String accessToken, PrintWriter writer) throws ServletException, IOException {
    
    		CloseableHttpClient  httpclient = HttpClients.createDefault();
    		HttpGet httpGet = new HttpGet();
    	
    		//add key and value
    		httpGet.addHeader("Authorization", "OAuth " + accessToken);
    		
    		try {
    		
    			URIBuilder builder = new URIBuilder(instanceUrl + "/services/data/v30.0/sobjects/Account/" + accountId);
    
    			httpGet.setURI(builder.build());
    
    			//httpclient.execute(httpGet);
    
    			CloseableHttpResponse  closeableresponse = httpclient.execute(httpGet);
    			System.out.println("Response Status line :" + closeableresponse.getStatusLine());
    			
    			if (closeableresponse.getStatusLine().getStatusCode()  == HttpStatus.SC_OK) {
    
    				try {
    				
    					// Do the needful with entity.
    					HttpEntity entity = closeableresponse.getEntity();
    					InputStream rstream = entity.getContent();
    					JSONObject authResponse = new JSONObject(new JSONTokener(rstream));
    					
    					System.out.println("Query response: " + authResponse.toString(2));
    					writer.write("Account  content\n\n");
    					
    					Iterator iterator = authResponse.keys();
    
    					while (iterator.hasNext()) {
    						String key = (String) iterator.next();
    
    						Object obj = authResponse.get(key);
    						String value = null;
    				
    						if (obj instanceof String) {
    							value = (String) obj;
    						}
    
    						writer.write(key + ":" + (value != null ? value : "") + "\n");
    					}
    
    					writer.write("\n");
    					
    				} catch (JSONException e) {
    					e.printStackTrace();
    					throw new ServletException(e);
    				}
    			}
    			
    		}
    		catch (URISyntaxException  e1) {
    			// TODO Auto­generated catch block
    			e1.printStackTrace();
    		} finally {
    			httpclient.close();
    		}
    	}
    	
    	private void updateAccount(String  accountId, String newName, String city, String instanceUrl, String accessToken, PrintWriter writer) throws ServletException, IOException {
    		
    		CloseableHttpClient  httpclient = HttpClients.createDefault();
    
    		JSONObject update = new JSONObject();
    		
    		try {
    			update.put("Name", newName);
    			update.put("BillingCity", city);
    		}
    		catch (JSONException e) {
    			e.printStackTrace();
    			throw new ServletException(e);
    		}
    		
    		HttpPost httpost = new HttpPost(instanceUrl + "/services/data/v30.0/sobjects/Account/" +accountId+"?_HttpMethod=PATCH");
    		httpost.addHeader("Authorization", "OAuth " + accessToken);
    		StringEntity messageEntity = new StringEntity( update.toString(), ContentType.create("application/json"));
    
    		httpost.setEntity(messageEntity);
    		
    		// Execute the request.
    		CloseableHttpResponse  closeableresponse = httpclient.execute(httpost); System.out.println("Response Status line :" + closeableresponse.getStatusLine());
    		
    		try {
    			writer.write("HTTP status " + closeableresponse.getStatusLine().getStatusCode() + " updating account " + accountId + "\n\n");
    		} finally {
    			httpclient.close();
    		}
    	}
    	
    	private void deleteAccount(String  accountId, String instanceUrl, String accessToken, PrintWriter writer) throws IOException {
    
    		CloseableHttpClient  httpclient = HttpClients.createDefault();
    
    		HttpDelete delete = new HttpDelete(instanceUrl + "/services/data/v30.0/sobjects/Account/" + accountId);
    
    		delete.setHeader("Authorization", "OAuth " + accessToken);
    
    		// Execute the request.
    		CloseableHttpResponse  closeableresponse = httpclient.execute(delete);
    		System.out.println("Response Status line :" + closeableresponse.getStatusLine());
    		
    		try {
    			writer.write("HTTP status " + closeableresponse.getStatusLine().getStatusCode() + " deleting account " + accountId + "\n\n");
    		} finally {
    			delete.releaseConnection();
    		}
    	}
    	
    	/**
    	* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    	*      response)
    	*/
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse  response) throws ServletException, IOException {
    	
    		PrintWriter writer = response.getWriter();
    
    		String accessToken = (String) request.getSession().getAttribute( ACCESS_TOKEN);
    
    		String instanceUrl = (String) request.getSession().getAttribute( INSTANCE_URL);
    
    		if (accessToken == null) {
    			writer.write("Error ­ no access token");
    			return;
    		}
    		
    		writer.write("We have an access token: " + accessToken + "\n" + "Using instance " + instanceUrl + "\n\n");
    
    		showAccounts(instanceUrl, accessToken, writer);
    
    		String accountId = createAccount("My New Org", instanceUrl, accessToken, writer);
    
    		if (accountId == null) {
    			System.out.println("Account ID null");
    		}
    
    		showAccount(accountId,  instanceUrl, accessToken, writer);
    		showAccounts(instanceUrl, accessToken, writer);
    		
    		updateAccount(accountId, "My New Org, Inc", "San Francisco", instanceUrl, accessToken, writer);
    
    		showAccount(accountId,  instanceUrl, accessToken, writer);
    
    		deleteAccount(accountId, instanceUrl, accessToken, writer);
    
    		showAccounts(instanceUrl, accessToken, writer);
    		
    	}
    	
    }
  3. 更改OAuthConnectedApp.java以基于Connected App配置替换Client ID,Client Secret和Callback URI字段。
  4. 在Eclipse(请参见图3)中或从外部启动Tomcat服务器,并导航到https:// localhost:8443 / /
    如何在JavaServer Pages中使用Salesforce REST API_第3张图片

    图3:在Eclipse中运行Tomcat服务器


    如何在JavaServer Pages中使用Salesforce REST API_第4张图片

    图4:检索对象屏幕

  5. 除非通过HTTPS,否则单击上面的链接(请参见图4)将不起作用,并且必须将SSL配置为Tomcat的端点。

    如果所有配置都正确完成,您应该会看到一个salesforce.com登录屏幕(请参见图5)。 继续并使用salesforce.com凭据登录以授权Web应用程序访问资源。

    如何在JavaServer Pages中使用Salesforce REST API_第5张图片

    图5:OAuth的Salesforce.com登录屏幕

  6. 登录将允许ConnectedAppREST演示执行创建,显示,更新和删除记录的方法(请参见图6)。
    如何在JavaServer Pages中使用Salesforce REST API_第6张图片

    图6:Connected App REST演示的输出

*提示和警告

  1. 确保您拥有一个Developer Edition(DE)帐户,因为Professional,Enterprise,Developer等之间存在细微差别。Developer版本是免费的,并且不会过期(除非一年后未使用)。
  2. OAuthConnectedApp.java中的回调URL必须与添加到连接的应用程序的URL相同。
  3. 如果收到HTTP 403错误,则表示正在访问您请求的资源“被禁止”。 检查您用来访问的用户名/帐户是否具有适当的权限。
  4. 确保index.html直接在WebContent目录下。

资源资源

有关全面的设置或资源,请访问: http : //developer.salesforce.com/en/mobile/resources

参考文献

  1. Force.com REST API开发人员指南 (PDF)
  2. 使用Force.com REST API

翻译自: https://www.javacodegeeks.com/2014/06/how-to-use-salesforce-rest-api-with-your-javaserver-pages.html

你可能感兴趣的:(如何在JavaServer Pages中使用Salesforce REST API)