About Sezin Karli

Mathematics Engineer & Computer Scientist with a passion for software development. Avid learner for new technologies. Currently working as senior software engineer at Sony Eurasia.

Spring social example on spring boot or how I stopped worrying and loved autoconfiguration

As for Spring Boot 1.1.0.RC1, autoconfiguration and the starter pom of Spring Social is added, which means that I won’t have to add a hundred dependency to my pom and lots of meaningless Spring configuration will be handled for me. Let’s see how it works with an example.

I will implement a web application of two pages. One will show the given user’s Twitter timeline and the other, user’s profile information. Here’s my pom:

 
 
 

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>

    <groupid>nr.co.caught</groupid>
    <artifactid>BootTwitterJoy</artifactid>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>1.1.0.RC1</version>
    </parent>

    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-social-twitter</artifactid>
        </dependency>

        <!-- Both are needed for jsp support-->
        <dependency>
            <groupid>org.apache.tomcat.embed</groupid>
            <artifactid>tomcat-embed-jasper</artifactid>
        </dependency>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>jstl</artifactid>
        </dependency>

    </dependencies>

    <!-- Needed for fat jar -->
    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

    <!-- Add Spring repositories -->
    <!-- (you don't need this if you are using a .RELEASE version) -->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </repository>
    </repositories>
    <pluginrepositories>
        <pluginrepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
        </pluginrepository>
        <pluginrepository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </pluginrepository>
    </pluginrepositories>

</project>

As you can see, I have my starter-social-twitter dependency which gives me Spring Social and Web capabilities. I’ll add jasper and jstl for my jsp pages to work. My repositories part is quite populated due to the milestone repositories.

Now we will add our Service to do Twitter method calls and a Controller for handling the requests. Our Controller is plain and simple:

@Controller
public class TwitterController {

    @Autowired
    private TwitterService twitterService;

 @RequestMapping(value = "/timeline/{twitterUser}")
 public String getUserTimeline(@PathVariable String twitterUser, Model model) {
        model.addAttribute("tweets", twitterService.getUserTimeline(twitterUser));
        model.addAttribute("user", twitterUser);

  return "timeline";
 }

    @RequestMapping(value = "/profile/{twitterUser}")
    public String getUserProfile(@PathVariable String twitterUser, Model model) {
        model.addAttribute("userProfile", twitterService.getUserProfile(twitterUser));

        return "profile";
    }
}

If the request comes with “/timeline/username”, our controller will get the user timeline and if it comes with “/profile/username” it will get the user profile from TwitterService. Here’s our TwitterService:

@Service
public class TwitterService {

   @Autowired
    private Twitter twitter;

    public List < Tweet > getUserTimeline(String twitterUser) {
        TimelineOperations timelineOps = twitter.timelineOperations();
        List tweets = timelineOps.getUserTimeline("@" + twitterUser);

        return tweets;
    }

    public TwitterProfile getUserProfile(String twitterUser) {
        UserOperations userOperations = twitter.userOperations();
        TwitterProfile userProfile = userOperations.getUserProfile(twitterUser);

        return userProfile;
    }
}

We have a Twitter object that’ll be created thanks to Spring Boot’s autoconfiguration. We just have to provide an app id and app secret key (a.k.a. consumer key and consumer secret) in our application properties and Boot will do the rest. I’m quoting Twitter object explanation from Spring javadoc:

“This instance of TwitterTemplate is limited to only performing operations requiring client authorization. For instance, you can use it to search Twitter, but you cannot use it to post a status update. The client credentials given here are used to obtain a client access token via OAuth 2 Client Credentials Grant”.

If you try to do a status update, you’ll get “org.springframework.social.MissingAuthorizationException: Authorization is required for the operation, but the API binding was created without authorization”. For further Twitter functionality, we would need to provide access token and access token secret keys as well but as far as I know autoconfiguration would not handle these cases yet.
My JSPs:
profile.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
<img src="${userProfile.profileImageUrl}"/>  

Screen name: ${userProfile.screenName} 

Name: ${userProfile.name}      

Description: ${userProfile.description}   

Location:  ${userProfile.location}  

Followers: ${userProfile.followersCount}  

</body>
</html>

As you can see, profile takes the userProfile provided by our Controller and shows the basic profile properties. timeline.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Time Line for <c:out value="${twitterUser}" /> TimeLine</title>
</head>
<body>
<ul>
    <c:forEach items="${tweets}" var="tweet">
        <li>${tweet.text}
 at <c:out value="${tweet.createdAt}"/></li>
        

    </c:forEach>
</ul>
</body>
</html>

Tweets are shown with their text and creation date. My application.properties content:

# Config for JSPs
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp

# SPRING SOCIAL TWITTER (TwitterAutoConfiguration)
spring.social.twitter.appId= someAppId
spring.social.twitter.appSecret= someSecretId

spring.view properties are for the jsp handling. spring.social.twitter properties and can be obtained from http://dev.twitter.com. Just login there with your twitter account, create your app and get your api keys. Here’s the result:

profile

timeline

  • You can check the code at github.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


four × 8 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books