IBM Bluemix 是构建应用程序来以全新方式融合各种服务的理想平台。本教程介绍如何构建一个应用程序,结合各种服务来查找给定位置附近的高评价企业的优惠券。
主要应用程序是一个 Java™ 应用程序,在拥有 MongoLab 数据库服务的 Liberty 上运行。数据从外部 API 收集而来,包括 Yelp、Google、Twitter 和 Klout。该应用程序收集数据,合并,然后使用聚合排序和基于评论的排序来优化结果。
“ 在 Bluemix 平台上,您可以新方式组合多样性的服务来构建新应用程序功能。 ”
运行应用程序
获取代码
我们使用 Eclipse 来开发该应用程序,所以这里提供的是使用 Eclipse 导入、部署和修改该应用程序的分步说明。
要结合使用 Bluemix 和 Eclipse,需要安装 IBM Eclipse Tools for Bluemix 插件,它支持部署和集成应用程序与 IBM Bluemix 或其他 Cloud Foundry 云。Bluemix 基于 Cloud Foundry 且支持 Cloud Foundry API。
要将来自 Eclipse 的应用程序部署到 Bluemix,需要在 Eclipse 中配置您的 Bluemix 帐户信息。
您的 Eclipse 环境现在已设置好,您可以将自己的应用程序副本部署到 Bluemix。
您的应用程序已部署在 Bluemix 上。但是,该应用程序需要一个 MongoLab 数据库才能正确运行。所以,在初始部署之后,您需要创建该服务并绑定到它,如下所述。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
要执行 Yelp API,需要使用来自 yelp.com 站点的一些属性: yelpConsumerKey
、 yelpConsumerSecret
、 yelpToken
和 yelpTokenSecret
。
要获得 Yelp 返回的任何企业的 Twitter 名称,需要访问 twitter.com 并获取以下属性: t4jAccessToken
、 t4jAccessTokenSecret
、 t4jConsumerKey
和 t4jConsumerSecret
。
要获取该 Twitter 名称的 Klout 评分,可以访问 klout.com 并获取 kloutkey
。
无需将所有密钥都包含在源代码中,可以使用此命令创建一个用户定义的服务 TravelSavingsService
:
cf create-user-provided-service TravelSavingsService -p "yelpConsumerKey,yelpConsumerSecret,yelpToken,yelpTokenSecret,kloutKey,t4jAccessToken, t4jAccessTokenSecret,t4jConsumerKey,t4jConsumerSecret"
这会提示用户提供每个值。
接下来,将 TravelSavingsService
绑定到 TravelSavingsApp
:
cf bind-service TravelSavingsApp TravelSavingsService
点击查看大图
关闭 [x]
现在该应用程序已部署,数据库服务也已绑定,我们看看这个正在运行的应用程序。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
该代码是一个 Java 应用程序,Web UI 使用了 HTML 和 JavaServer Pages (JSP)。要使用 Yelp API,需要使用来自 Yelp 的您自己的密钥、令牌和密钥。
src/Yelp.properties
文件中。将此文件中的信息替换为您自己的帐户信息。在授予访问权后,就可以在 Manage API 页面上根据需要而生成或更改密钥。 // Execute a signed call to the Yelp service. OAuthService service = new ServiceBuilder() .provider(YelpV2API.class) .apiKey("CONSUMER_KEY") .apiSecret("CONSUMER_SECRET") .build(); Token accessToken = new Token("TOKEN", "TOKEN_SECRET");
YelpCalc
是主要类,我们在其中传递 4 个必要的参数,它们是: consumerKey、consumerSecret、token
和 tokenSecret
。 YelpCalc yelp = new YelpCalc(consumerKey, consumerSecret, token, tokenSecret); ArrayList<String> yelp_result = null; String yelp_response=""; ….
yelp_response = yelp.yelp_query(search_term, search_location); yelp_result = yelp.yelp_result_list(yelp_response);
…. center = yelp.yelp_center(yelp_response); request.setAttribute("center_latitude", center[0]); request.setAttribute("center_longitude", center[1]); ….
yelpresult.jsp
来显示结果: request.getRequestDispatcher("/yelpresult.jsp").forward(request, response);
result.jsp
中的这段代码实现了该算法: geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { console.debug('Debug information: ' + results[0].geometry.location); mapOptions = { zoom: 3, center: results[0].geometry.location , mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); <%@ page import="twitter4j.*, java.io.*, java.util.List" %> <% twitter4j.QueryResult result1 = (twitter4j.QueryResult) request.getAttribute("result1"); for(twitter4j.Status status : result1.getTweets() ) { String text = status.getText().replace("/"", "'").replace("/n", " "). replace("/'", ""); text = " "+text+" "; String location = status.getUser().getLocation(); String screenName = status.getUser().getScreenName(); String prof_img = status.getUser().getProfileImageURL(); %> var loc1 = "<%= location %>"; geocoder.geocode({'address':loc1}, function (new_result) { // console.debug("Check here: ", new_result) var loc = "<%= location %>"; var txt = '<%= text %>'; var scrName = '<%= screenName %>'; var profile_img = '<%= prof_img %>'; var contentString = '<div id="content">'+ '<div id="siteNotice">'+ '</div>'+ '<h3 id="firstHeading" class="firstHeading"><img src='+profile_img+' class="img-rounded">'+ scrName+'</h3>'+ '<div id="bodyContent">'+ txt + '</div>'+ '</div>'; var infowindow = new google.maps.InfoWindow({ content: contentString }); var marker = new google.maps.Marker({ position: new_result[0].geometry.location, map: map, title: 'Tweet' }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); }); <% } %> } else { alert('Geocode was not successful for the following reason: ' + status); } }); }
现在扩展该代码,使用每个企业的 Twitter 名称来检索它们的 Klout id。该扩展是在 GetKloutScore.java
类中实现的。 DevOps 项目 包含 GetKloutScore.java
类,以及 Klout.properties
、 twitter4j.properties
和 yelpresult_klout.jsp。首先:
GetKloutScore.java
是否在您 Eclipse 项目中的 Java Resources 下。如果不在,可以从 DevOps Services 项目导入它。 YelpCalc
类以调用 Klout。在 YelpCalc
类中的 doPost()
方法中,在以下两段注释之间添加以下代码: /* Insert code to collect Klout scores for the list of businesses returned by Yelp. */和
/* Code insertion ends here */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // "search_term" is the parameter used in the index.html String search_term = request.getParameter("search_term"); String search_location = request.getParameter("location"); YelpCalc yelp = new YelpCalc(consumerKey, consumerSecret, token, tokenSecret); ArrayList<String> yelp_result = null; String yelp_response=""; try { yelp_response = yelp.yelp_query(search_term, search_location); yelp_result = yelp.yelp_result_list(yelp_response); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } String[] center; try { center = yelp.yelp_center(yelp_response); request.setAttribute("center_latitude", center[0]); request.setAttribute("center_longitude", center[1]); System.out.println("The Latitude of center is" + center[0]); System.out.println("The Longitude of center is" + center[1]); } catch (JSONException e) { System.out.println("Unable to get Lat Long info /n"); e.printStackTrace(); } request.setAttribute("query_term", search_term); request.setAttribute("query_location", search_location); request.setAttribute("query_responses", yelp_result); /* Insert code to collect Klout scores for the list of businesses returned by Yelp. */ String klout_result[]=new String [yelp_result.size()]; String name,id; int i=0; for ( String yelp_item : yelp_result) { StringTokenizer stk = new StringTokenizer(yelp_item,"#"); name=stk.nextToken(); String score = GetKloutScore.getScore(name); klout_result[i++]= name + "," + score; System.out.println(klout_result[i-1]); } request.setAttribute("klout_responses", klout_result); /* Code insertion ends here */ request.getRequestDispatcher("/yelpresult.jsp").forward(request, response); }
StringTokenizer
错误。要解决它,可以将这个导入语句添加到 YelpCalc.java 中: import java.util.StringTokenizer;
klout.properties
和 twitter4j.properties
是否在您的 Eclipse 项目中。(这些文件包含在 DevOps 项目中。) 点击查看大图
关闭 [x]
可以扩展该代码,根据该企业的 twitterName 的 followerCount
、 retweetCount
和 mentionCount
以及 GoogleMaps 上的推文数来显示评分。此扩展已在 YelpCac.java
类中实现。 DevOps project 包含 YelpCalc.java:
String twitterUsername = request.getParameter("twitter_name"); // The factory instance is re-useable and thread safe. Twitter twitter = new TwitterFactory().getInstance(); try { User a_name = twitter.showUser(twitterUsername); int followerCount = a_name.getFollowersCount(); List<Status> retweets = twitter.getUserTimeline(twitterUsername, new Paging(1, 20)); // get the first twenty tweets int retweetCount = 0; for (Status tweet : retweets) { retweetCount += (int) tweet.getRetweetCount(); } System.out.println("The rtcount is: " + retweetCount); int mentionCount = 0; int retweetScore = 0; int followerScore = 0; if (retweetCount >= 100000) retweetScore = 60; elseif (retweetCount >= 20000) retweetScore = 50; elseif (retweetCount >= 10000) retweetScore = 40; elseif (retweetCount >= 5000) retweetScore = 30; elseif (retweetCount >= 1000) retweetScore = 20; elseif (retweetCount >= 500) retweetScore = 10; elseif (retweetCount >= 100) retweetScore = 5; elseif (retweetCount >= 10) retweetScore = 1; if (followerCount >= 10000000) followerScore = 40; elseif (followerCount >= 1000000) followerScore = 35; elseif (followerCount >= 500000) followerScore = 30; elseif (followerCount >= 100000) followerScore = 25; elseif (followerCount >= 1000) followerScore = 20; elseif (followerCount >= 500) followerScore = 15; elseif (followerCount >= 100) followerScore = 10; elseif (followerCount >= 10) followerScore = 5; // Search API call to calculate the mentions out of 100 Query query = new Query("@" + twitterUsername); query.setCount(100); query.setResultType(Query.RECENT); QueryResult result = twitter.search(query); mentionCount += result.getTweets().size(); System.out.println("the mcount is: " + mentionCount); // Calculate the total score of the user. int totalscore = retweetScore + followerScore + mentionCount; System.out.println("The total score is: " + totalscore); // tweets to be displayed on the google maps Query query1 = new Query("@" + twitterUsername); query.setCount(20); query.setResultType(Query.RECENT); QueryResult result1 = twitter.search(query1);
本教程介绍了如何使用 Eclipse 设置、更新一个 Java 应用程序并将其部署到 Bluemix,该应用程序将会查找您所在位置附近的高评分企业。您看到了如何组合来自多个服务的数据,其中包括 Yelp、Google、Twitter 和 Klout 及其他可编程的 Web API,以便检索、排序和分析数据。您可以针对其他数据源和用途来自由修改 Java 代码、MongoDB、搜索和分析代码。
相关主题: Yelp Google Maps Twitter Klout
BLUEMIX SERVICES USED IN THIS TUTORIAL: