stackexchange_通过Spring Social发推StackExchange问​​题

stackexchange

1.简介

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

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

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

2. Tweet Stackexchange服务

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

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

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

找到该问题后,将通过与该帐户相对应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

stackexchange

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

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

相关文章

使用JCache缓存方法结果

在JCache中&#xff0c;有一个方便的功能可以透明地缓存方法的结果。 您可以使用CacheResult注释托管bean的方法&#xff0c;并且将再次返回第一次调用的结果&#xff0c;而无需再次调用实际方法。 import javax.cache.annotation.CacheResult; // ...public class Calculator…

开源项目GoodView点赞效果

点赞1效果&#xff1a; GoodView方法&#xff1a; 使用GoodView的Demo: public class MainActivity extends Activity { Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main)final Good…

开源RefreshListView下拉刷新效果

1、AnimationDrawable java.lang.Object ↳android.graphics.drawable.Drawable ↳android.graphics.drawable.DrawableContainer ↳android.graphics.drawable.AnimationDrawable 文档概述&#xff1a;An object used to create frame-by-frame animations, defined …

Neo4j:遍历查询超时

在过去的几周中&#xff0c;我一直在花一些业余时间来创建一个应用程序&#xff0c;该应用程序从Open Roads数据生成运行路线-当然已转换并导入到Neo4j中&#xff01; 我创建了一个用户定义的过程&#xff0c;该过程结合了几个最短路径查询&#xff0c;但是如果它们花费的时间…

View的三大流程之View的测量

1、public class View extends Objectimplements Drawable.Callback KeyEvent.Callback AccessibilityEventSourcejava.lang.Object ↳android.view.View Class Overview This class represents the basic building block for user interface components. A View occupies a …

使用LayoutParams设置布局

1、public static class ViewGroup.LayoutParams extends Objectjava.lang.Object ↳android.view.ViewGroup.LayoutParams Class Overview LayoutParams are used by views to tell their parents how they want to be laid out. LayoutParams是ViewGroup的一个内部类, 每个…

记录意外的开关选项

Java开发人员可以做很多事情来使自己的生活以及维护该代码的其他人的生活更加轻松。 在本文中&#xff0c;我将探讨开发人员可以采用的一种非常简单的方法&#xff0c;以使每个人都更轻松。 这篇文章的要点对于每个阅读它的人来说似乎都是显而易见的&#xff0c;但是我发现这样…

View的绘制

1、当测量好一个View后就可以重写onDraw()方法&#xff0c;并在Canvas对象上绘制所需的图形。 public class Canvas extends Objectjava.lang.Object ↳android.graphics.Canvas Public ConstructorsCanvas()Construct an empty raster canvas.Canvas(Bitmap bitmap)Construc…

ViewGroup的测量及绘制

1、ViewGroup的测量public abstract class ViewGroup extends Viewimplements ViewManager ViewParent java.lang.Object ↳android.view.View ↳android.view.ViewGroup Class Overview A ViewGroup is a special view that can contain other views (called children.)…

ejb 2.0 3.0_定义EJB 3.1视图(本地,远程,无接口)

ejb 2.0 3.0这篇文章将讨论使用批注定义EJB视图的可能方法&#xff08;最后我将只提到使用EJB部署描述符&#xff09;。我将重点介绍最新的EJB 3.1视图&#xff0c;这些视图将省略旧的本地&#xff0c;远程和本地接口。 因此&#xff0c;我们可以选择&#xff1a; 远程业务界面…

View的事件分发机制简述

要分析的对象就是MotionEvent&#xff0c;点击事件的事件分发其实就是对MotionEvent事件的分发过程&#xff0c;当MotionEvent产生后&#xff0c;系统需要把这个事件传递给一个具体的View&#xff0c;这个传递过程就是分发过程。这个过程由三个很重要的方法共同完成&#xff1a…

ListView的使用用ViewHolder提升效率

public class ListView extends AbsListViewjava.lang.Object ↳android.view.View ↳android.view.ViewGroup ↳android.widget.AdapterView<T extends android.widget.Adapter> ↳android.widget.AbsListView ↳android.widget.ListView Class Ove…

通过投影增强数据模型

介绍 数据模型可能很棘手。 建模可能会更加困难。 有时候&#xff0c;应该放入数据库表中的信息不一定是我们要在每段代码中使用的信息。 和其他许多次一样&#xff0c;Spring来了。 一个称为投影的小功能可以帮助我们在普通界面中仅用几行数据映射数据。 在本文中&#xff0…

ListView常用属性、方法

1、设置item间分割线&#xff0c;分割线高度 android:divider"android:color/darker_gray" android:dividerHeight"10dp" 分割线不仅仅可以设置为一个颜色&#xff0c;也可以设置为一个图片资源。 分割线设置为透明&#xff1a; android:divider"…

具有弹性效果的ListView

Android默认的ListView在滚动到顶端或底端&#xff0c;没有很好的提示&#xff0c;下面通过源码来实现弹性效果。 ListView中有一个控制滑动到边缘的处理方法&#xff1a; protected boolean overScrollBy(int deltaX, int deltaY,int scrollX, int scrollY,int scrollRangeX,…

rememberme多久_使用Spring Security添加RememberMe身份验证

rememberme多久我在“ 向Jiwhiz博客添加社交登录”一文中提到&#xff0c;RememberMe功能不适用于Spring Social Security。 好吧&#xff0c;这是因为该应用程序现在不通过用户名和密码对用户进行身份验证&#xff0c;并且完全依靠社交网站&#xff08;例如Google&#xff0c;…

Java 9:对可选的增强

之前 &#xff0c;我写过Java 8中引入的Optional类&#xff0c;该类用于对可能不存在的值进行建模并减少可能引发NullPointerException的位置的数量。 Java 9向Optional添加了三个新方法&#xff1a; 1. ifPresentOrElse 新ifPresentOrElse方法允许你执行一个动作&#xff0c…

电脑还原Mac地址

之前修改过电脑Mac&#xff0c;现在与手机Mac冲突&#xff0c;导致手机无法连接校园网。 控制面板——》打开网络和共享中心——》选择更改适配器设置 本地连接——》右键选择属性 上图选择配置 高级——》在下拉菜单中选择网络地址——》右边选为“不存在” 之后本地连接会自…

聊天ListView使用ViewHolder

聊天界面会展示至少两种布局&#xff0c;即收到消息和发送消息。这样一个ListView与平时使用的ListView的最大不同&#xff0c;在于它有两个不同的布局&#xff1a;收到的布局和发送的布局。需要利用Adapter实现这样的效果。即需要在获取布局的时候判断该获取哪个布局。 public…

动态改变ListView布局

在getView()时&#xff0c;通过判断选择加载不同的布局。 点击某个item的时候&#xff0c;变为foucus状态&#xff0c;其他的items还原。 下面用两个方法给item设置两个不同的布局。 //foucus状态&#xff0c;显示一个ImageViewprivate View addFocusView(int i) {ImageView…