{"id":85152,"date":"2018-12-26T13:00:24","date_gmt":"2018-12-26T11:00:24","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=85152"},"modified":"2018-12-24T10:12:58","modified_gmt":"2018-12-24T08:12:58","slug":"streaming-api-spring-integration","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html","title":{"rendered":"Consuming Twitter Streaming API with Spring Integration"},"content":{"rendered":"<h2>1. Overview<\/h2>\n<p><a href=\"https:\/\/spring.io\/projects\/spring-integration\" target=\"_blank\" rel=\"noopener\">Spring Integration<\/a> has been known to have a myriad of connectors for interacting with external systems. Twitter was no exception and for a long time, as <a href=\"https:\/\/projects.spring.io\/spring-social\/\" target=\"_blank\" rel=\"noopener\">Spring Social<\/a> had been an out-of-the-box solution which Spring Integration leveraged in order to connect to social networks.<\/p>\n<h3>1.1 Spring Social EOL<\/h3>\n<p>Unfortunately, <strong><a href=\"https:\/\/spring.io\/blog\/2018\/07\/03\/spring-social-end-of-life-announcement\" target=\"_blank\" rel=\"noopener\">Spring Social has reached its end of life<\/a>, the project is now in maintenance mode.<\/strong> The reason why the Spring Team decided that they wouldn\u2019t develop Spring Social further was that it became tedious to keep the API bindings in sync with the APIs of social networks.<\/p>\n<p>Other than that, after Spring Framework 5 had been released, developers wished to leverage its reactive programming model and that would have required the team to re-implement a reactive Spring Social bindings next to the existing one.<\/p>\n<p><strong>Developers are now advised to either implement their own binding or use one of the purpose built libraries to connect to social networks.<\/strong><\/p>\n<h3>1.2 Spring Integration\u2019s Twitter module moved to extensions<\/h3>\n<p>The fact the Spring Social is now in maintenance mode forced the Spring Integration team to move the Twitter support module from the main project to the extensions. As Spring Social isn\u2019t going to receive updates, it\u2019s going to be built upon an earlier Spring Framework version. That would lead to class path conflict and would also hamper the development of Spring Integration.<\/p>\n<p><strong>Therefore, <a href=\"https:\/\/jira.spring.io\/browse\/INT-4453\">as of Spring Integration 5.1, the Twitter module is available as an extension<\/a>.<\/strong><\/p>\n<h3>1.3 What are the alternatives?<\/h3>\n<p><a href=\"http:\/\/twitter4j.org\/en\/\" target=\"_blank\" rel=\"noopener\"><strong>Twitter4J<\/strong><\/a> is an unofficial Java libary for Twitter\u2019s API developed and maintained by&nbsp;<a href=\"https:\/\/twitter.com\/yusuke\" target=\"_blank\" rel=\"noopener\">Yusuke Yamamoto<\/a>. <strong>The official <a href=\"https:\/\/github.com\/twitter\/hbc\" target=\"_blank\" rel=\"noopener\">HBC<\/a> library (built by Twitter)<\/strong> is a Java HTTP Client for consuming Twitter\u2019s Streaming API. The latter hasn\u2019t seen major updates since 2016, while Twitter4J is receiving regular updates.<\/p>\n<p><strong>Implementing your own API binding is also an option.<\/strong> In Spring based projects using <a href=\"https:\/\/docs.spring.io\/spring\/docs\/current\/javadoc-api\/org\/springframework\/web\/client\/RestTemplate.html\" target=\"_blank\" rel=\"noopener\">RestTemplate<\/a> and is definitely an option and it\u2019s an easy way to make REST calls.<\/p>\n<p><strong>This guide uses Twitter4J in streaming mode in a way that can be integrated into a Spring Integration message flow.<\/strong><\/p>\n<h3>1.4 How does Twitter Streaming work?<\/h3>\n<p>In a nutshell, <strong>your app opens a single connection to to Twitter\u2019s API and&nbsp;new results are sent through that connection whenever new matches occur<\/strong>. In contrast, the other way around is delivering data in batches through repeated requests to a REST API.<\/p>\n<p><strong>Streaming provides&nbsp;a low-latency delivery mechanism<\/strong> that can support very high throughput without having to deal with rate limiting.<\/p>\n<h2>2. Example project<\/h2>\n<p>The example project, which demonstrates the integration of Twitter\u2019s Streaming API into a Spring Integration message flow, is available on <strong>GitHub<\/strong>:&nbsp;<a href=\"https:\/\/github.com\/springuni\/springuni-examples\/tree\/master\/spring-integration\/twitter-streaming\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/springuni\/springuni-examples\/tree\/master\/spring-integration\/twitter-streaming<\/a>.<\/p>\n<h3>2.1. Maven Dependencies<\/h3>\n<p>As Spring Social is EOL now, we won\u2019t build upon it. All we pull in are <a href=\"https:\/\/mvnrepository.com\/artifact\/org.springframework.integration\/spring-integration-core\" target=\"_blank\" rel=\"noopener\">spring-integration-core<\/a> and <a href=\"https:\/\/mvnrepository.com\/artifact\/org.twitter4j\/twitter4j-stream\" target=\"_blank\" rel=\"noopener\">twitter4j-stream<\/a>.<\/p>\n<pre class=\"brush:xml\">&lt;dependencies&gt;\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.springframework.integration&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-integration-core&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;dependency&gt;\n      &lt;groupId&gt;org.twitter4j&lt;\/groupId&gt;\n      &lt;artifactId&gt;twitter4j-stream&lt;\/artifactId&gt;\n      &lt;version&gt;4.0.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n  &lt;\/dependencies&gt;<\/pre>\n<p>This project also uses <a href=\"https:\/\/projectlombok.org\/\" target=\"_blank\" rel=\"noopener\">Lombok<\/a> and <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/boot-features-testing.html\" target=\"_blank\" rel=\"noopener\">Spring Boot testing<\/a> support, but these are optional.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h3>2.3. Listenable message source with Spring Integration<\/h3>\n<p>Spring Integration provides support for implementing <strong>inbound message components<\/strong>. They\u2019re <strong>divided into polling and listening behaviors<\/strong>.<\/p>\n<p><strong>The original Inbound Twitter Channel Adapter<\/strong>, that one which relies builds upon Spring Social and is now moved to the extensions, <strong>is a polling consumer<\/strong>. That is, you have to provide a poller configuration to use it. On the other hand, Twitter enforces Rate Limits in order to manage how often application can fetch updates.&nbsp;You should have taken Rate Limiting into consideration when the old Twitter Channel adapter was used, so that your configured poller intervals have been in compliance with the Twitter policies.<\/p>\n<p>On the other hand, the <strong>listening inbound components are simpler and typically require only <a href=\"https:\/\/docs.spring.io\/spring-integration\/api\/org\/springframework\/integration\/endpoint\/MessageProducerSupport.html\" target=\"_blank\" rel=\"noopener\">MessageProducerSupport<\/a> to be implemented.<\/strong> Such a listening component looks like this.<\/p>\n<pre class=\"brush:java\">public class MyMessageProducer extends MessageProducerSupport {\n\n  public MyMessageProducer(MessageChannel outputChannel) {\n    \/\/ Defining an output channel is required\n    setOutputChannel(outputChannel);\n  }\n\n  @Override\n  protected void onInit() {\n    super.onInit();\n    \/\/ Custom initialization - if applicable - comes here\n  }\n\n  @Override\n  public void doStart() {\n    \/\/ Lifecycle method for starting receiving messages\n  }\n\n  @Override\n  public void doStop() {\n    \/\/ Lifecycle method for stopping receiving messages\n  }\n\n  private void receiveMessage() {\n    \/\/ Receive data from upstream service\n    SomeData data = ...;\n\n    \/\/ Convert it to a message as appropriate and send it out\n    this.sendMessage(MessageBuilder.withPayload(data).build());\n  }\n\n}<\/pre>\n<p><strong>There are only two required elements:<\/strong><\/p>\n<ul>\n<li>Output message channel has to be defined<\/li>\n<li><code>sendMessage<\/code> has to be called whenever the component receives a message<\/li>\n<\/ul>\n<p>Optionally you might want to take control over the component\u2019s initialization and manage its lifecycle.<\/p>\n<p><strong>As Twitter\u2019s Streaming API is inherently message-driven, the listening behavior is a natural fit.<\/strong> Let\u2019s see how Twitter4J can be incorporated in such a context.<\/p>\n<h3>2.4. Connect to Twitter Streaming API with Twitter4J<\/h3>\n<p>Twitter4J manages the nuances of connection handing and receiving updates from Twitter\u2019s Streaming API. All we need to do is acquire a <code>TwitterStream<\/code> instance, attach a listener and define filtering.<\/p>\n<h2>2.4.1. Instantiate <code>TwitterStream<\/code><\/h2>\n<p>Streaming examples on Twitter4J\u2019s website suggest that a <a href=\"http:\/\/twitter4j.org\/javadoc\/twitter4j\/TwitterStream.html\" target=\"_blank\" rel=\"noopener\"><code>TwitterStream<\/code><\/a> instance should be created through <a href=\"http:\/\/twitter4j.org\/javadoc\/twitter4j\/TwitterStreamFactory.html\" target=\"_blank\" rel=\"noopener\"><code>TwitterStreamFactory<\/code><\/a>. That makes perfectly sense, however in a Spring application context we want it to be a managed bean.<\/p>\n<p><strong>Spring\u2019s <a href=\"https:\/\/spring.io\/blog\/2011\/08\/09\/what-s-a-factorybean\" target=\"_blank\" rel=\"noopener\"><code>FactoryBean<\/code><\/a> facility is clean and easy way to contain the details of making a singleton <code>TwitterStream<\/code> instance.<\/strong><\/p>\n<pre class=\"brush:java\">public class TwitterStreamFactory extends AbstractFactoryBean&lt;TwitterStream&gt; {\n\n  @Override\n  public Class&lt;?&gt; getObjectType() {\n    return TwitterStream.class;\n  }\n\n  @Override\n  protected TwitterStream createInstance() {\n    return new twitter4j.TwitterStreamFactory().getInstance();\n  }\n\n  @Override\n  protected void destroyInstance(TwitterStream twitterStream) {\n    twitterStream.shutdown();\n  }\n\n}<\/pre>\n<p>Although we could also expose it as a regular bean without being created by a <code>FactoryBean<\/code>, that wouldn\u2019t take care of properly shutting it down.<\/p>\n<h2>2.4.2. Attaching a listener and defining filtering<\/h2>\n<p>That\u2019s going to be the responsibility of our custom <a href=\"https:\/\/docs.spring.io\/spring-integration\/api\/org\/springframework\/integration\/core\/MessageProducer.html\" target=\"_blank\" rel=\"noopener\"><code>MessageProducer<\/code><\/a> implementation.<\/p>\n<pre class=\"brush:java\">@Slf4j\npublic class TwitterMessageProducer extends MessageProducerSupport {\n\n  private final TwitterStream twitterStream;\n\n  private List&lt;Long&gt; follows;\n  private List&lt;String&gt; terms;\n\n  private StatusListener statusListener;\n  private FilterQuery filterQuery;\n\n  public TwitterMessageProducer(TwitterStream twitterStream, MessageChannel outputChannel) {\n    this.twitterStream = twitterStream;\n    setOutputChannel(outputChannel);\n  }\n\n  @Override\n  protected void onInit() {\n    super.onInit();\n\n    statusListener = new StatusListener();\n\n    long[] followsArray = null;\n\n    if (!CollectionUtils.isEmpty(follows)) {\n      followsArray = new long[follows.size()];\n      for (int i = 0; i &lt; follows.size(); i++) {\n        followsArray[i] = follows.get(i);\n      }\n    }\n\n    String[] termsArray = null;\n    if (!CollectionUtils.isEmpty(terms)) {\n      termsArray = terms.toArray(new String[0]);\n    }\n\n    filterQuery = new FilterQuery(0, followsArray, termsArray);\n  }\n\n  @Override\n  public void doStart() {\n    twitterStream.addListener(statusListener);\n    twitterStream.filter(filterQuery);\n  }\n\n  @Override\n  public void doStop() {\n    twitterStream.cleanUp();\n    twitterStream.clearListeners();\n  }\n\n  public void setFollows(List&lt;Long&gt; follows) {\n    this.follows = follows;\n  }\n\n  public void setTerms(List&lt;String&gt; terms) {\n    this.terms = terms;\n  }\n\n  StatusListener getStatusListener() {\n    return statusListener;\n  }\n\n  FilterQuery getFilterQuery() {\n    return filterQuery;\n  }\n\n  class StatusListener extends StatusAdapter {\n\n    @Override\n    public void onStatus(Status status) {\n      sendMessage(MessageBuilder.withPayload(status).build());\n    }\n\n    @Override\n    public void onException(Exception ex) {\n      log.error(ex.getMessage(), ex);\n    }\n\n    @Override\n    public void onStallWarning(StallWarning warning) {\n      log.warn(warning.toString());\n    }\n\n  }\n}<\/pre>\n<p>Lifecycle methods provided by <code>MessageProducerSupport<\/code> and <code>TwitterStream<\/code>\u2018s management interface play nicely together. That\u2019s also going to enable us to stop and start the component at runtime when needed.<\/p>\n<h2>2.4.3. Java Configuration<\/h2>\n<p>Although Spring could auto-wire components, I still prefer controlling dependencies with manual configuration.<\/p>\n<pre class=\"brush:java\">@Slf4j\n@Configuration\npublic class TwitterConfig {\n\n  @Bean\n  TwitterStreamFactory twitterStreamFactory() {\n    return new TwitterStreamFactory();\n  }\n\n  @Bean\n  TwitterStream twitterStream(TwitterStreamFactory twitterStreamFactory) {\n    return twitterStreamFactory.getInstance();\n  }\n\n  @Bean\n  MessageChannel outputChannel() {\n    return MessageChannels.direct().get();\n  }\n\n  @Bean\n  TwitterMessageProducer twitterMessageProducer(\n      TwitterStream twitterStream, MessageChannel outputChannel) {\n\n    TwitterMessageProducer twitterMessageProducer =\n        new TwitterMessageProducer(twitterStream, outputChannel);\n\n    twitterMessageProducer.setTerms(Arrays.asList(\"java\", \"microservices\", \"spring\"));\n\n    return twitterMessageProducer;\n  }\n\n  @Bean\n  IntegrationFlow twitterFlow(MessageChannel outputChannel) {\n    return IntegrationFlows.from(outputChannel)\n        .transform(Status::getText)\n        .handle(m -&gt; log.info(m.getPayload().toString()))\n        .get();\n  }\n\n}<\/pre>\n<p>Important part here is that how our custom message producer integrates with a message flow. Basically, we don\u2019t need to do anything, other than listing to messages at the producer\u2019s output channel.<\/p>\n<h3>2.5. Testing<\/h3>\n<p>Only Chuck Norris tests code in production. However, ordinary mortal folks like you and me, we do write test cases.<\/p>\n<pre class=\"brush:java\">@RunWith(SpringRunner.class)\n@ContextConfiguration(classes = TestConfig.class)\npublic class TwitterMessageProducerTest {\n\n  @MockBean\n  private TwitterStream twitterStream;\n\n  @Autowired\n  private PollableChannel outputChannel;\n\n  @Autowired\n  private TwitterMessageProducer twitterMessageProducer;\n\n  @Test\n  public void shouldBeInitialized() {\n    StatusListener statusListener = twitterMessageProducer.getStatusListener();\n    verify(twitterStream).addListener(statusListener);\n\n    FilterQuery filterQuery = twitterMessageProducer.getFilterQuery();\n    verify(twitterStream).filter(filterQuery);\n  }\n\n  @Test\n  public void shouldReceiveStatus() {\n    StatusListener statusListener = twitterMessageProducer.getStatusListener();\n\n    Status status = mock(Status.class);\n    statusListener.onStatus(status);\n\n    Message&lt;?&gt; statusMessage = outputChannel.receive();\n    assertSame(status, statusMessage.getPayload());\n  }\n\n  @Import(TwitterConfig.class)\n  static class TestConfig {\n\n    @Bean\n    MessageChannel outputChannel() {\n      return MessageChannels.queue(1).get();\n    }\n\n  }\n\n}<\/pre>\n<p><strong>I like Twitter4J\u2019s design, because it leverages interfaces.<\/strong> Most of the important parts of the library are exposed as ordinary interfaces. <strong><code>TwitterStream<\/code> is no exception to that. That is, it can be mocked out easily in test cases.<\/strong><\/p>\n<h2>&nbsp;6. Conclusion<\/h2>\n<ul>\n<li><strong>Spring Social is EoL now<\/strong> \u2013 it\u2019s not going to receive new features<\/li>\n<li><strong>Spring Integration\u2019s Twitter module is available as an extension<\/strong>&nbsp;\u2013 it\u2019s been moved out from the main project.<\/li>\n<li><strong>Twitter Inbound Channel adapter is a polling consumer<\/strong> \u2013 you have to deal with rate limiting when choosing your poll interval<\/li>\n<li><strong>Twitter\u2019s Streaming API fits with the listening behavior of an inbound channel adapter<\/strong><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Java Code Geeks with permission by Laszlo Csontos, partner at our <a href=\"\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener\">JCG program<\/a>. See the original article here: <a href=\"https:\/\/craftingjava.com\/tutorials\/twitter4j-streaming-spring-integration\/\" target=\"_blank\" rel=\"noopener\">Consuming Twitter Streaming API with Spring Integration<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>1. Overview Spring Integration has been known to have a myriad of connectors for interacting with external systems. Twitter was no exception and for a long time, as Spring Social had been an out-of-the-box solution which Spring Integration leveraged in order to connect to social networks. 1.1 Spring Social EOL Unfortunately, Spring Social has reached &hellip;<\/p>\n","protected":false},"author":67581,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[1839,30,410],"class_list":["post-85152","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-integration","tag-spring","tag-spring-integration"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Consuming Twitter Streaming API with Spring Integration - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Spring Integration? Check our article explaining how we can stream api&#039;s with Spring Integration.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Consuming Twitter Streaming API with Spring Integration - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Spring Integration? Check our article explaining how we can stream api&#039;s with Spring Integration.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/craftingjava\" \/>\n<meta property=\"article:published_time\" content=\"2018-12-26T11:00:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Laszlo Csontos\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@craftingjava\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laszlo Csontos\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html\"},\"author\":{\"name\":\"Laszlo Csontos\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9b7371241503cd9c8efc7290d6df28ff\"},\"headline\":\"Consuming Twitter Streaming API with Spring Integration\",\"datePublished\":\"2018-12-26T11:00:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html\"},\"wordCount\":1072,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Integration\",\"Spring\",\"Spring Integration\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html\",\"name\":\"Consuming Twitter Streaming API with Spring Integration - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2018-12-26T11:00:24+00:00\",\"description\":\"Interested to learn about Spring Integration? Check our article explaining how we can stream api's with Spring Integration.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/streaming-api-spring-integration.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Consuming Twitter Streaming API with Spring Integration\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9b7371241503cd9c8efc7290d6df28ff\",\"name\":\"Laszlo Csontos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"caption\":\"Laszlo Csontos\"},\"description\":\"Laszlo has been coding since the age of 9. Now he'S been coding for 25 years, with Java for 18 years and professionally for 13 years. During past projects he worked in various roles as a consultant, developer, mentor, team leader and architect. His focus areas have been database-oriented back-end applications, performance tuning techniques and distributed systems. In the last 3 years, he specialized in building microservices with the Spring Ecosystem.\",\"sameAs\":[\"https:\\\/\\\/craftingjava.com\\\/\",\"https:\\\/\\\/www.facebook.com\\\/craftingjava\",\" https:\\\/\\\/www.linkedin.com\\\/in\\\/lcsontos\\\/\",\"https:\\\/\\\/x.com\\\/craftingjava\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC4v5ZYpefzOQu3iMP4NPgXw\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/laszlo-csontos\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Consuming Twitter Streaming API with Spring Integration - Java Code Geeks","description":"Interested to learn about Spring Integration? Check our article explaining how we can stream api's with Spring Integration.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html","og_locale":"en_US","og_type":"article","og_title":"Consuming Twitter Streaming API with Spring Integration - Java Code Geeks","og_description":"Interested to learn about Spring Integration? Check our article explaining how we can stream api's with Spring Integration.","og_url":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"https:\/\/www.facebook.com\/craftingjava","article_published_time":"2018-12-26T11:00:24+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Laszlo Csontos","twitter_card":"summary_large_image","twitter_creator":"@craftingjava","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Laszlo Csontos","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html"},"author":{"name":"Laszlo Csontos","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9b7371241503cd9c8efc7290d6df28ff"},"headline":"Consuming Twitter Streaming API with Spring Integration","datePublished":"2018-12-26T11:00:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html"},"wordCount":1072,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Integration","Spring","Spring Integration"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html","url":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html","name":"Consuming Twitter Streaming API with Spring Integration - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2018-12-26T11:00:24+00:00","description":"Interested to learn about Spring Integration? Check our article explaining how we can stream api's with Spring Integration.","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/streaming-api-spring-integration.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Consuming Twitter Streaming API with Spring Integration"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9b7371241503cd9c8efc7290d6df28ff","name":"Laszlo Csontos","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","caption":"Laszlo Csontos"},"description":"Laszlo has been coding since the age of 9. Now he'S been coding for 25 years, with Java for 18 years and professionally for 13 years. During past projects he worked in various roles as a consultant, developer, mentor, team leader and architect. His focus areas have been database-oriented back-end applications, performance tuning techniques and distributed systems. In the last 3 years, he specialized in building microservices with the Spring Ecosystem.","sameAs":["https:\/\/craftingjava.com\/","https:\/\/www.facebook.com\/craftingjava"," https:\/\/www.linkedin.com\/in\/lcsontos\/","https:\/\/x.com\/craftingjava","https:\/\/www.youtube.com\/channel\/UC4v5ZYpefzOQu3iMP4NPgXw"],"url":"https:\/\/www.javacodegeeks.com\/author\/laszlo-csontos"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/85152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/67581"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=85152"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/85152\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=85152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=85152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=85152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}