通过Spring Social发推StackExchange问​​题

1.简介

这是有关小型附属项目的第三篇也是最后一篇文章-该机器人自动在专用帐户上鸣叫来自各个Q&A StackExchange网站上的问题(文章末尾的完整列表)。

第一篇文章讨论了为StackExchange REST API构建一个简单的客户端 。 在第二篇文章中,我们使用Spring Social建立了与Twitter的交互。

本文将描述实现的最后一部分-负责Stackexchange客户端与TwitterTemplate之间的交互的部分。

2. Tweet Stackexchange服务

Stackexchange Client(公开原始问题)与TwitterTemplate (完全设置并可以鸣叫)之间的交互是一个非常简单的服务TweetStackexchangeService 。 由此发布的API是:

public void tweetTopQuestionBySite(String site, String twitterAccount){ ... }
public void tweetTopQuestionBySiteAndTag(String site, String twitterAccount, String tag){ ... }

功能很简单–这些API将继续(通过客户端)从Stackexchange REST API中读取“问题”,直到在该特定帐户上找到之前从未发过任何推文的为止。

找到该问题后,将通过与该帐户相对应TwitterTemplateTwitter上发布该消息,并将一个非常简单的Question实体保存在本地。 该实体仅存储问题的ID和已在其上发布的Twitter帐户。

例如以下问题: 在@RequestParam中绑定列表 已在SpringAtSO帐户上发布。

Question实体仅包含:

  • 问题的编号 –在这种情况下为4596351
  • 问题已在其上发布的Twitter帐户 – SpringAtSO
  • 问题源自的Stackexcange网站 – stackoverflow

我们需要跟踪此信息,以便我们知道哪些问题已被发布,哪些问题尚未被发布。

3.调度程序

调度程序利用了Spring的调度任务功能-通过Java配置启用了这些功能:

@Configuration
@EnableScheduling
public class ContextConfig {//
}

实际的调度程序相对简单:

@Component
@Profile(SpringProfileUtil.DEPLOYED)
public class TweetStackexchangeScheduler {@Autowiredprivate TweetStackexchangeService service;// API@Scheduled(cron = "0 0 1,5 * * *")public void tweetStackExchangeTopQuestion() throws JsonProcessingException, IOException {service.tweetTopQuestionBySiteAndTag("StackOverflow", Tag.clojure.name(), "BestClojure", 1);String randomSite = StackexchangeUtil.pickOne("SuperUser", "StackOverflow");service.tweetTopQuestionBySiteAndTag(randomSite, Tag.bash.name(), "BestBash", 1);}
}

上面配置了两个推文操作–来自StackOverflow问题的一个推文,在Best Of Clojure Twitter帐户上标有“ clojure”。

其他操作将推文标记为“ bash”的问题–由于这类问题实际上出现在Stackexchange网络上的多个站点上: StackOverflow , SuperUser和AskUbuntu ,因此首先有一个快速选择过程来选择这些站点之一,然后问题已发布。

最后, 计划cron作业每天在凌晨1点和凌晨5点运行

4.设定

这是一个宠物项目,它以一个非常简单的数据库结构开始 -现在仍然很简单,但情况更是如此。 因此,主要目标之一是能够轻松地更改数据库结构-当然,有几种用于数据库迁移的工具 ,但是对于这样一个简单的项目,它们全都过时了。

因此,我决定将设置数据保留为简单的文本格式 -将自动进行半自动更新。

安装程序有两个主要步骤:

  • 检索每个Twitter帐户上的推文问题的ID,并将其存储在文本文件中
  • 删除数据库架构并重新启动应用程序–这将再次创建架构,并将所有数据从文本文件设置回新数据库

4.1。 原始设置数据

使用JDBC检索现有数据库中数据的过程非常简单; 首先我们定义一个RowMapper:

class TweetRowMapper implements RowMapper<String> {private Map<String, List<Long>> accountToQuestions;public TweetRowMapper(Map<String, List<Long>> accountToQuestions) {super();this.accountToQuestions = accountToQuestions;}public String mapRow(ResultSet rs, int line) throws SQLException {String questionIdAsString = rs.getString("question_id");long questionId = Long.parseLong(questionIdAsString);String account = rs.getString("account");if (accountToQuestions.get(account) == null) {accountToQuestions.put(account, Lists.<Long> newArrayList());}accountToQuestions.get(account).add(questionId);return "";}
}

这将为每个Twitter帐户建立一个问题列表。

接下来,我们将在一个简单的测试中使用它:

@Test
public void whenQuestionsAreRetrievedFromTheDB_thenNoExceptions() {Map<String, List<Long>> accountToQuestionsMap = Maps.newHashMap();jdbcTemplate.query("SELECT * FROM question_tweet;", new TweetRowMapper(accountToQuestionsMap));for (String accountName : accountToQuestionsMap.keySet()) {System.out.println(accountName + "=" + valuesAsCsv(accountToQuestionsMap.get(accountName)));}
}

检索帐户问题后,测试将简单地列出问题; 例如:

SpringAtSO=3652090,1079114,5908466,...

4.2。 恢复设置数据

上一步生成的数据行存储在setup.properties文件中 ,该文件可用于Spring:

@Configuration
@PropertySource({ "classpath:setup.properties" })
public class PersistenceJPAConfig {//
}

当应用程序启动时,将执行设置过程。 这个简单的过程使用Spring ApplicationListener,监听ContextRefreshedEvent

@Component
public class StackexchangeSetup implements ApplicationListener<ContextRefreshedEvent> {private boolean setupDone;public void onApplicationEvent(ContextRefreshedEvent event) {if (!setupDone) {recreateAllQuestionsOnAllTwitterAccounts();setupDone = true;}}
}

最后,从setup.properties文件中检索问题并重新创建:

private void recreateAllQuestionsOnTwitterAccount(String twitterAccount) {String tweetedQuestions = env.getProperty(twitterAccount.name();String[] questionIds = tweetedQuestions.split(",");recreateQuestions(questionIds, twitterAccount);
}
void recreateQuestions(String[] questionIds, String twitterAccount) {List<String> stackSitesForTwitterAccount = twitterAccountToStackSites(twitterAccount);String site = stackSitesForTwitterAccount.get(0);for (String questionId : questionIds) {QuestionTweet questionTweet = new QuestionTweet(questionId, twitterAccount, site);questionTweetDao.save(questionTweet);}
}

这个简单的过程可以轻松地更新数据库结构-由于已完全擦除数据并完全重新创建了数据,因此无需进行任何实际的迁移

5.帐户完整清单

Twitter帐户完整列表是:

  • SpringAtSO –来自StackOverflow的Spring问题
  • JavaTopSO –来自StackOverflow的Java问题
  • RESTDaily –来自StackOverflow的REST问题
  • BestJPA –来自StackOverflow的JPA问题
  • BestMaven –来自StackOverflow的Maven问题
  • BestGit –来自StackOverflow的Git问题
  • AskUbuntuBest – AskUbuntu最佳总体问题(所有主题)
  • ServerFaultBest – ServerFault最佳问题(所有主题)
  • BestBash-来自StackOverflow,ServerFault和AskUbuntu的最佳Bash问题
  • BestClojure –来自StackOverflow的Clojure问题
  • BestScala –来自StackOverflow的Scala问题
  • BestEclipse –来自StackOverflow的Eclipse问题
  • jQueryDaily –来自StackOverflow的jQuery问题
  • BestAlgorithms –来自StackOverflow的算法问题

这些帐户中的每个帐户每天都会创建2条推文,其特定主题的问题评分最高。

六,结论

第三篇文章完成了有关与StackOverflow和其他StackExchange网站集成以通过其REST API检索问题,以及与Twitter和Spring Social集成以发布这些问题的系列文章。 可能值得探索的潜在方向与Google Plus相同(可能使用Pages,而不是帐户)。

14这个项目的结果是Twitter帐户已启动并正在运行-专注于各种主题,并产生少量且希望高质量的内容(在评论中欢迎其他标记自己Twitter帐户的标记的想法)。

参考:在baeldung博客上,我们的JCG合作伙伴 Eugen Paraschiv 与Spring Social一起发布了StackExchange Questions 。

翻译自: https://www.javacodegeeks.com/2013/05/tweeting-stackexchange-questions-with-spring-social.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML语义化的理解

1、什么是HTML语义化&#xff1f; “语义化”指的是在需要更少的人类干预的情况下&#xff0c;能够研究和手机信息&#xff0c;让网页能够被机器理解&#xff0c;最终让人类受益。 语义化的目的就是让大家直观的认识标签&#xff08;markup&#xff09;和属性&#xff08;att…

乒乓球比赛赛程_10月5日至10月11日中央电视台直播录播乒乓球比赛安排

10月5日至10月11日这一周中央电视台居然没有播乒乓球比赛?全国乒乓球锦标赛从5日开始进行各单项比赛&#xff0c;7日进行混双决赛&#xff0c;9日进行男双决赛和女单决赛&#xff0c;10日进行女双决赛和男单决赛。场场都是精彩好看的比赛&#xff0c;中央电视台体育频道一场都…

集合实例(集合覆盖)

集合覆盖是一种优化求解问题&#xff0c;对很多组合数学和资源选择问题给出了很好的抽象模型。 问题如下&#xff1a;给定一个集合S&#xff0c;集合P由集合S的子集A1到An组成&#xff0c;集合C由集合P中的一个或多个子集组成。如果S中的每个成员都包含在C的至少一个子集中则称…

Drawwhile计算机软件,计算机程序设计、小女纸又怒编一程序、求鉴定、

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼srand(time(NULL));while (1){while (!kbhit()) //在没有按键的情况下,蛇自己移动身体{if (food.addFood 1) //需要出现新食物{food.x rand() % 400 60;food.y rand() % 350 60;//食物出现后必须在整格内才能让蛇吃到while (f…

python eval 用法

eval 功能&#xff1a;将字符串str当成有效的表达式来求值并返回计算结果。 语法&#xff1a; eval(source[, globals[, locals]]) -> value 参数&#xff1a; source&#xff1a;一个Python表达式或函数compile()返回的代码对象 globals&#xff1a;可选。 变量作用域&…

带有正则表达式模式的Google Guava Cache

最近我看到了一个关于Google Guava的精彩演讲 &#xff0c;我们在我们的项目中得出结论&#xff0c;使用它的缓存功能真的很有趣。 让我们看一下regexp Pattern类及其编译功能 。 在代码中经常可以看到&#xff0c;每次使用正则表达式时&#xff0c;程序员都会使用相同的参数重…

关闭运动轨迹_网球初学者如何正确入门网球运动,有哪些学习细节

网球是一个非常有趣的球类运动。 当您开始入门时&#xff0c;您会越来越喜欢它。 那么网球初学者应该如何正确入门呢&#xff1f; 有什么独特的入门经验&#xff1f;即使没有网球经验&#xff0c;只要您能正确正确地进行定期训练&#xff0c;仍然可以取得很大的进步。首先&…

input长度随输入内容动态变化 input光标定位在最右侧

<input type"text" οnkeydοwn"this.onkeyup();" οnkeyup"this.size(this.value.length>4?this.value.length:4);" size"4"> <input type"text">的默认size就是20 如果你在style里定义了width属性,又…

phpstorm+wamp+xdebug配置php调试环境

本篇文章主要是&#xff1a;教大家如果搭建一套phpstormwampxdebug调试php的环境现在大多数的程序员使用的调试方式一般都是echo, var_dump, file_put_contents等其他方式&#xff0c;效率比较低下&#xff0c;因此我们有必要学习用工具调试&#xff0c;工具调试主要可以用来解…

计算机专用英语1500词带音标,带音标的计算机英语1500词

带音标的计算机英语1500词 (46页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;29.9 积分&#xfeff;计算机专用英语词汇1500词《电脑专业英语》1. file [fail] n. 文件&#xff1b;v. 保存文件 2. …

需求改进与系统设计

第一部分 需求与原型改进 1.1改进的原型 1.1.1 改进说明 相较上一次的原型&#xff0c;这一次我们确定了主题颜色&#xff0c;并且使功能一眼就能看懂&#xff0c;让新用户能很快上手。 并且进一步完善了前期的调查问卷分析。得出结论同学们不去食堂吃饭的大部分原因是排队…

了解ADF Faces clientComponent属性

我相信大多数ADF开发人员都知道ADF Faces属性clientComponent 。 在这篇文章中&#xff0c;我将展示此属性实际上如何影响组件渲染以及它如何改变其行为。 让我们开始考虑一个非常简单的示例&#xff1a; <af:inputText label"Label 1" id"it1" /> …

谈谈一些有趣的CSS题目(十五)-- 谈谈 CSS 关键字 initial、inherit 和 unset

开本系列&#xff0c;谈谈一些有趣的 CSS 题目&#xff0c;题目类型天马行空&#xff0c;想到什么说什么&#xff0c;不仅为了拓宽一下解决问题的思路&#xff0c;更涉及一些容易忽视的 CSS 细节。解题不考虑兼容性&#xff0c;题目天马行空&#xff0c;想到什么说什么&#x…

小程序沉浸式_企业开发小程序:客户裂变式增长

最近几年&#xff0c;各行各业中都有不少企业、商家获客难窘境。因此&#xff0c;很多企业、商家想知道&#xff1a;"怎么做&#xff0c;才能获取到大量流量&#xff1f;"小编给大家推荐一种方式&#xff1a;开发一个微信小程序&#xff0c;然后利用小程序来获取大量…

单点拖拽和多点多拽

demo见github:https://github.com/fei1314/drag/tree/master 一、拖拽原理手指所处的位置到一个div顶部的距离L一直不变。 二、单点拖拽1.touchstart:单指按下2.touchmove&#xff1a;单指移动3.touchend&#xff1a;单指抬起a.在touchstart事件中&#xff0c;利用拖拽原理&…

伪代码是计算机语言,伪代码书写格式

《伪代码书写格式》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《伪代码书写格式(3页珍藏版)》请在人人文库网上搜索。1、精品文档伪代码伪代码是用介于自然语言和计算机语言之间的文字和符号来描述算法。每一行(或几行)表示一个基本操作。它不用图形符号&#xff0…

JDBC连接Mysql数据库

注释&#xff1a;&#xff08;以下代码会抛出多个异常&#xff0c;仅表达出JDBC连接Mysql数据库的过程步骤&#xff09;加载数据库驱动(即 实例化驱动类对象)Class.forName("com.mysql.cj.jdbc.Driver"); 获取数据库的连接Connection conn null; conn DriverManage…

Elasticsearch:用于内容丰富的文本分析

每个文本搜索解决方案都与其提供的文本分析功能一样强大。 Lucene是这样的开源信息检索库&#xff0c;提供了许多文本分析的可能性。 在本文中&#xff0c;我们将介绍ElasticSearch提供的一些主要文本分析功能&#xff0c;这些功能可用来丰富您的搜索内容。 内容丰富 以一个典…

[CSS] Scale on Hover with Transition

效果 源码 <!doctype html><html class"outline color"><head><meta charset"utf-8"><title>图片scale动画</title><style>.img-box {position: relative;width: 740px;height: 420px;overflow: hidden;}/* 彩色…

热敏电阻温度特性曲线_热敏电阻与体温计的应用关系

相信体温计大家都熟悉&#xff0c;热敏电阻与体温计的应用关系大家都知道吗&#xff1f;热敏电阻热敏电阻探头测量体温的原理又是什么呢&#xff0c;小编跟大家分析一下&#xff0c;希望以下详细的介绍能帮助到大家&#xff01;热敏电阻探头测量体温的原理分析如下&#xff1a;…