Multi client Development with Spring

1,972 views

Published on

This talk introduces the role that Spring MVC and REST can play as a service-side endpoint model that can be connected to from mobile, rich, and desktop applications.

Published in: Technology, Education
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,972
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
51
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Hello, thank you or having me. Im pleased to have the opportunity to introduce you today to Spring and the SpringSource Tool Suite \n\nMy anem is Josh Long. I serve as the developer advocate for the Spring framework. I’ve used it in earnest and advocated it for many years now. i’m an author on 3 books on the technology, as well as a comitter to many of the Spring projects. Additionally, I take community activism very seriously and do my best to participate in the community. Sometimes this means answering question on Twitter, or in the forums, or helping contribute to the InfoQ.com and Artima.com communities\n
  • \n
  • \n\n
  • \n
  • highlight that yu shouldnt be required to write the muck. highlight that the framework buils on the soulders of giants and benefits from almost a decafe of community feedback\n\nat its heart spring addresses these problems by delivery DI, AOP, ESA \n
  • these different framerworks let u tackle any problem youre likely to want to solve today \n- we support javee1.4 + 1.5 + 1.6; \n\nsits above target platform \nruns in cloud \n\n
  • there are lots of frameworks to solve lots of problems\nthey all use the same pojo metaphor\nlets review some ofthem ... \nnaturally, the best part is that you can pick and choose - architecture a la carte! these are just lbiraris you can add to your applications, after all \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • Familiar to somebody who’s used Struts:\n Models (like Struts ActionForms)\n Views (like Struts views: tiles, .jsp(x)s, velocity, PDF, Excel, etc.) \n Controllers (like Struts Actions)\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pieces are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • another example of the fact that often the client side model won’t represent the server side model \n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Multi client Development with Spring

    1. 1. Spring and the Many Faces of the Web (or, Thin, Thick, Web, Mobile and Rich Clients with Spring)Josh Long@starbuxmanSpring Developer AdvocateSpringSource, a division of VMware © 2009 VMware Inc. All rights reserved
    2. 2. About Josh LongSpringSource Developer Advocatetwitter: @starbuxmanjosh.long@springsource.com NOT CONFIDENTIAL -- TELL EVERYONE 2
    3. 3. Agenda Introduction to Spring Web Applications • Spring MVC, JSF, Others REST • the final frontier: TV, tablets, operating systems Mobile Clients • Android, iPhone RIA / SOFEA • Flex, GWT, Vaadin OAuth • Spring Social, Spring Security OAuth NOT CONFIDENTIAL -- TELL EVERYONE 3
    4. 4. About SpringSource is the organization that develops the Spring framework, the leading enterprise Java framework SpringSource was acquired by VMware in 2009 VMware and SpringSource bring you to the cloud and deliver on the mission of “build, run, manage” • established partnerships with the major players in the business, including Adobe, SalesForce, and Google to help deliver the best experience for Spring users across multiple platforms Leading contributor to projects like Apache HTTPD and Apache Tomcat NOT CONFIDENTIAL -- TELL EVERYONE 4
    5. 5. Introduction to Spring NOT CONFIDENTIAL -- TELL EVERYONE 5
    6. 6. At its core, the Spring Framework... Provide comprehensive infrastructural support for developing enterprise Java™ applications • Spring deals with the plumbing • So you can focus on solving the domain problem NOT CONFIDENTIAL -- TELL EVERYONE 6
    7. 7. Spring’s aim: bring simplicity to java development data web tier integration batch access & service tier & mobile processing / NoSQL / RIA messaging Big Data The Spring frameworkthe cloud: lightweight traditional CloudFoundry WebSphere tc Server VMForce JBoss AS Tomcat Google App Engine WebLogic Jetty Amazon Web Services (on legacy versions, too!) NOT CONFIDENTIAL -- TELL EVERYONE 7
    8. 8. The Spring Framework Framework Description Spring Core The foundation Spring @MVC the web leading framework (comes with the core framework) Spring Security Extensible framework providing authentication, authorization Spring Webflow An excellent web framework for building multi-page flows Spring Web Services Contract-first, document–centric SOAP and XML web services Spring Batch Powerful batch processing framework Spring Integration Implements enterprise integration patterns Spring BlazeDS Support for Adobe BlazeDS Spring AMQP interface with AMQP message brokers, like RabbitMQ Spring Data NoSQL options: HBase, MongoDB, Redis, Riak, CouchDB, Neo4J, etc. Spring Social integrate Twitter, Facebook, Tripit, MySpace, LinkedIn, etc. Spring Hadoop Provides a POJO-centric approach to building Hadoop applications provides first-class support for serviceSpring Mobile, Spring Android creation and consumption for iPhone, Android Spring GemFire Provides the easiest interface for the GemFire enterprise data grid technology NOT CONFIDENTIAL -- TELL EVERYONE 8
    9. 9. Web Applications with Spring NOT CONFIDENTIAL -- TELL EVERYONE 9
    10. 10. The Spring ApplicationContext Spring Beans are Managed by An ApplicationContext • whether you’re in an application server, a web server, in regular Java SE application, in the cloud, Spring is initialized through an ApplicationContext • In a Java SE application: ApplicationContext ctx = new GenericAnnotationApplicationContext( “com.foo.bar.my.package”); • In a web application, you will configure an application context in your web.xml <servlet> <servlet-name>Spring Dispatcher Servlet</servlet-name> <servlet- class>org.springframework.web.servlet.DispatcherServlet</servlet- class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/myAppContext*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> NOT CONFIDENTIAL -- TELL EVERYONE 10
    11. 11. Thin, Thick, Web, Mobile and Rich Clients: Web Core Spring Dispatcher Servlet • Objects don’t have to be web-specific. • Spring web supports lower-level web machinery: ‘ • HttpRequestHandler (supports remoting: Caucho, Resin, JAX RPC) • DelegatingFilterProxy. • HandlerInterceptor wraps requests to HttpRequestHandlers • ServletWrappingController lets you force requests to a servlet through the Spring Handler chain • OncePerRequestFilter ensures that an action only occurs once, no matter how many filters are applied. Provides a nice way to avoid duplicate filters • Spring provides access to the Spring application context using WebApplicationContextUtils, which has a static method to look up the context, even in environments where Spring isn’t managing the web components NOT CONFIDENTIAL -- TELL EVERYONE
    12. 12. Thin, Thick, Web, Mobile and Rich Clients: Web Core Spring provides the easiest way to integrate with your web framework of choice • Spring Faces for JSF 1 and 2 • Struts support for Struts 1 • Tapestry, Struts 2, Stripes, GWT, Wicket, Vaadin, Play framework, etc. NOT CONFIDENTIAL -- TELL EVERYONE
    13. 13. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC NOT CONFIDENTIAL -- TELL EVERYONE 13
    14. 14. Thin, Thick, Web, Mobile and Rich Clients: Spring MVCSpring MVC configuration - config @Configuration @EnableWebMvc @Import(Config.class) public class WebConfig extends WebMvcConfigurerAdapter{ @Bean public UrlBasedViewResolver resolver() { UrlBasedViewResolver url = new UrlBasedViewResolver(); url.setPrefix("views/"); url.setViewClass(JstlView.class); url.setSuffix(".jsp"); return url; } public void configureViewControllers(ViewControllerConfigurer configurer) { configurer.mapViewName("/", "welcome") ; } } A Controller - config @Controller public class CustomerController { @Autowired private CustomerService customerService; @ModelAttribute public Customer customer() { return new Customer(); } @RequestMapping(value = "/display", method = RequestMethod.GET) public Map<String, Object> customer(@RequestParam("id") Long id) { Map<String, Object> out = new HashMap<String, Object>(); out.put("customer", customerService.getCustomerById(id) ); return out; } NOT CONFIDENTIAL -- TELL EVERYONE 14
    15. 15. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC Demos • Spring MVC and associated configuration NOT CONFIDENTIAL -- TELL EVERYONE
    16. 16. REST NOT CONFIDENTIAL -- TELL EVERYONE 16
    17. 17. Thin, Thick, Web, Mobile and Rich Clients: REST Spring MVC is basis for REST support • Spring’s server side REST support is based on the standard controller model • RestTemplate • provides dead simple, idiomatic RESTful services consumption • can use Spring OXM, too. • Spring Integration and Spring Social both build on the RestTemplate where possible. • JavaScript and HTML5 can consume JSON-data payloads • REST is the ultimate connectivity mechanism: everything can speak HTTP. NOT CONFIDENTIAL -- TELL EVERYONE
    18. 18. Thin, Thick, Web, Mobile and Rich Clients: RESTRestCustomerController - server@Controller @RequestMapping(headers = "Accept=application/json, application/xml")public class RestCustomerController { @Autowired private CustomerService cs; @RequestMapping(value = "/customer/{cid}", method = RequestMethod.POST) @ResponseBody public Customer updateCustomer(@RequestBody Customer c) { return cs.updateCustomer( c.getId(), c.getFirstName(), c.getLastName()); } WebConfig - server @EnableWebMvc @Import(Config.class) @Configuration public class WebConfig extends WebMvcConfigurerAdapter {} client Customer customer1 = restTemplate.getForEntity( url + "customer/{customerId}", Customer.class, c.getId()).getBody(); log.info("fetched customer " + customer1.toString()); NOT CONFIDENTIAL -- TELL EVERYONE 18
    19. 19. Thin, Thick, Web, Mobile and Rich Clients: REST Demos:• Spring REST service• Spring REST client NOT CONFIDENTIAL -- TELL EVERYONE
    20. 20. Mobile (pt 1.) NOT CONFIDENTIAL -- TELL EVERYONE 20
    21. 21. Thin, Thick, Web, Mobile and Rich Clients: Mobile Best strategy? Develop Native • Fallback to client-optimized web applications Spring MVC 3.1 mobile client-specific content negotiation and rendering • for other devices • (there are other devices besides Android??) NOT CONFIDENTIAL -- TELL EVERYONE 21
    22. 22. Thin, Thick, Web, Mobile and Rich Clients: Mobile WebConfig - server! @Bean public ViewResolver viewResolver() { UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); viewResolver.setViewClass(TilesView.class); return viewResolver; } @Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer configurer = new TilesConfigurer(); configurer.setDefinitions(new String[]{ "/WEB-INF/layouts/tiles.xml", "/WEB-INF/views/**/tiles.xml" }); configurer.setCheckRefresh(true); return configurer; } @Override public void configureInterceptors(InterceptorConfigurer configurer) { configurer.addInterceptor(new DeviceResolverHandlerInterceptor()); } NOT CONFIDENTIAL -- TELL EVERYONE 22
    23. 23. Thin, Thick, Web, Mobile and Rich Clients: REST Demos:• Mobile clients using client specific rendering NOT CONFIDENTIAL -- TELL EVERYONE
    24. 24. Mobile (pt 2.) NOT CONFIDENTIAL -- TELL EVERYONE 24
    25. 25. Thin, Thick, Web, Mobile and Rich Clients: Mobile  Spring REST is ideal for mobile devices  Spring MVC 3.1 mobile client-specific content negotiation and rendering • for other devices  Spring Android • RestTemplate NOT CONFIDENTIAL -- TELL EVERYONE 25
    26. 26. Thin, Thick, Web, Mobile and Rich Clients: Mobile CustomerServiceClient - client! private <T> T extractResponse( ResponseEntity<T> response) {! ! if (response != null && response().value() == 200) {! ! ! return response.getBody();! ! }! ! throw new RuntimeException("couldnt extract response.");! }! @Override! public Customer updateCustomer(long id, String fn, String ln) {! ! String urlForPath = urlForPath("customer/{customerId}");! !! ! return extractResponse(this.restTemplate.postForEntity( urlForPath, new Customer(id, fn, ln), Customer.class, id));! } NOT CONFIDENTIAL -- TELL EVERYONE 26
    27. 27. Thin, Thick, Web, Mobile and Rich Clients: Mobile Demos:• consuming the Spring REST service from Android NOT CONFIDENTIAL -- TELL EVERYONE
    28. 28. Rich Internet Applications NOT CONFIDENTIAL -- TELL EVERYONE 28
    29. 29. Thin, Thick, Web, Mobile and Rich Clients: Flex  Spring Flex • Dead-simple to expose Spring beans as Flex services • Developed with support from Adobe • But it still has strengths: • form driven apps • video, 2D and 3D graphics, sound • Adobe AIR • blazing fast communication • server side push • Spring ActionScript is a cool framework “sponsored” by SpringSource NOT CONFIDENTIAL -- TELL EVERYONE
    30. 30. Thin, Thick, Web, Mobile and Rich Clients: Flex crm-flex-servlet.xml - server<?xml version="1.0" encoding="UTF-8"?><beans ...> <context:component-scan base-package="org.springsource.examples.sawt.web.flex"/> <mvc:default-servlet-handler/> <flex:message-broker mapping-order="1"> <flex:mapping pattern="/messagebroker/*"/> <flex:message-service default-channels="my-streaming-amf,my-longpolling-amf,my-polling-amf"/> </flex:message-broker> <flex:remoting-destination ref="jdbcCustomerService" destination-id="customerService"/></beans> CustomerForm.mxml - client<fx:Declarations><s:RemoteObject id="cs" destination="customerService"endpoint="{serviceUrl}"> <s:method name="createCustomer" result="create_resultHandler(event)"/> <s:method name="updateCustomer" result="update_resultHandler(event)"/> </s:RemoteObject> </fx:Declarations><fx:Script><![CDATA[ cs.updateCustomer( c.id, c.firstName, c.lastName); ]]></fx:Script> NOT CONFIDENTIAL -- TELL EVERYONE 30
    31. 31. Thin, Thick, Web, Mobile and Rich Clients: RIA with Flex Demos:• exposing Spring services through BlazeDS• consuming it from a Flex client NOT CONFIDENTIAL -- TELL EVERYONE
    32. 32. Thin, Thick, Web, Mobile and Rich Clients: GWT  Google Web Toolkit • Lots of popular options • We’ll look at building a simple example by simple delegating as appropriate • Server-side: standard DispatcherServlet NOT CONFIDENTIAL -- TELL EVERYONE
    33. 33. Thin, Thick, Web, Mobile and Rich Clients: GWT GwtCustomerService - clientimport com.google.gwt.user.client.rpc.*;@RemoteServiceRelativePath("crm")public interface GwtCustomerService extends RemoteService { void updateCustomer(long cid, String f, String l); CustomerDto getCustomerById(long customerId); CustomerDto createCustomer(String f, String ln);}GwtCustomerServiceImpl - server private <T> T beanOfType(Class t) { ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext( getServletContext()); return (T) ac.getBean(t); } public void updateCustomer(long cid, String f, String l) { try { CustomerService customerService = beanOfType(CustomerService.class); customerService.updateCustomer(cid, f, l); } catch (Exception ex) { throw new RuntimeException(ex); } } NOT CONFIDENTIAL -- TELL EVERYONE 33
    34. 34. Thin, Thick, Web, Mobile and Rich Clients: GWT Demos:• building a simple GWT client that consumes services in Spring NOT CONFIDENTIAL -- TELL EVERYONE
    35. 35. Social Communication NOT CONFIDENTIAL -- TELL EVERYONE 35
    36. 36. Spring Social Extension to Spring Framework to enable connectivity with Software-as-a-Service providers Features... • An extensible connection framework • A connect controller • Java API bindings • A sign-in controller http://www.springsource.org/spring-social 36
    37. 37. Spring Social Projects Spring Social Core Spring Social Facebook Spring Social Twitter Spring Social LinkedIn Spring Social TripIt Spring Social GitHub Spring Social Gowalla Spring Social Samples • Includes Showcase, Quickstart, Movies, Canvas, Twitter4J, Popup 37
    38. 38. Key Steps to Socializing an Application Configure Spring Social beans • Connection Factory Locator and Connection Factories • Connection Repository • Connect Controller • API Bindings Create connection status views Inject/use API bindings 38
    39. 39. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 39
    40. 40. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 39
    41. 41. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 39
    42. 42. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 39
    43. 43. Configuration: Connection Repository@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public ConnectionRepository connectionRepository() { Authentication authentication = SecurityContextHolder.getContext(). getAuthentication(); if (authentication == null) { throw new IllegalStateException( "Unable to get a ConnectionRepository: no user signed in"); } return usersConnectionRepository().createConnectionRepository( authentication.getName());} 40
    44. 44. Configuration: Connection Repository@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public ConnectionRepository connectionRepository() { Authentication authentication = SecurityContextHolder.getContext(). getAuthentication(); if (authentication == null) { throw new IllegalStateException( "Unable to get a ConnectionRepository: no user signed in"); } return usersConnectionRepository().createConnectionRepository( authentication.getName());}@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public UsersConnectionRepository usersConnectionRepository() { return new JdbcUsersConnectionRepository( dataSource, connectionFactoryLocator(), Encryptors.noOpText());} 40
    45. 45. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 41
    46. 46. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 41
    47. 47. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 41
    48. 48. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 42
    49. 49. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 42
    50. 50. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 42
    51. 51. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 42
    52. 52. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 43
    53. 53. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 43
    54. 54. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 43
    55. 55. ConnectController Endpoints GET /connect • Displays connection status for all providers GET /connect/{provider} • Displays connection status for a given provider POST /connect/{provider} • Initiates the authorization flow, redirecting to the provider GET /connect/{provider}?oauth_token={token} • Handles an OAuth 1 callback GET /connect/{provider}?code={authorization code} • Handles an OAuth 2 callback DELETE /connect/{provider} • Removes all connections for a user to the given provider DELETE /connect/{provider}/{provider user ID} • Removes a specific connection for the user to the given provider 44
    56. 56. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) 45
    57. 57. ConnectController Flow Your Application GET /connect/{provider ID} ConnectController Service Provider (Twitter, Facebook, etc) Display connection status page 45
    58. 58. ConnectController Flow Your Application POST /connect/{provider ID} ConnectController Service Provider (Twitter, Facebook, etc) Initiate connection flow 45
    59. 59. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Fetch request token (OAuth 1.0/1.0a only) 45
    60. 60. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 45
    61. 61. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 45
    62. 62. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 45
    63. 63. ConnectController Flow Your Application GET /connect/{provider ID}?oauth_token={token} GET /connect/{provider ID}?code={code} ConnectController Service Provider (Twitter, Facebook, etc) Provider redirects to callback URL 45
    64. 64. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Exchange request token and/or code for access token 45
    65. 65. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) ConnectController stores connection details in connection repository 45
    66. 66. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Application can make API calls via API binding 45
    67. 67. Connection Status Page View<form action="<c:url value="/connect/twitter" />" method="POST"> <div class="formInfo"> <p> You havent created any connections with Twitter yet. Click the button to connect with your Twitter account. </p> </div> <p> <button type="submit"> <img src="<c:url value="/resources/social/twitter/connect-with-twitter.png" />"/> </button> </p></form> 46
    68. 68. Provider Sign In A convenience for users Enables authentication to an app using their connection as credentials Implemented with ProviderSignInController Works consistently with any provider 47
    69. 69. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 48
    70. 70. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 48
    71. 71. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 48
    72. 72. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 48
    73. 73. ProviderSignInController Endpoints POST /signin/{provider} • Initiates the authorization flow, redirecting to the provider GET /signin/{provider}?oauth_token={token} • Handles an OAuth 1 callback GET /signin/{provider}?code={authorization code} • Handles an OAuth 2 callback GET /signin • Handles a callback when no oauth token or code is sent • Likely indicates that the user declined authorization 49
    74. 74. Social Security OAuth NOT CONFIDENTIAL -- TELL EVERYONE 50
    75. 75. Spring Security OAuth Extension to Spring Security • originally a community contribution (now officially part of the project) Features... • endpoint management for OAuth service types • (along with corresponding client management) • token management (persistence, authentication) • integrations for the web, as well as through standard Spring Security springsource.org/spring-security/oauth 51
    76. 76. Setup Spring Security with Spring MVC...<http access-denied-page="/login.jsp" xmlns="http://www.springframework.org/schema/security"> <form-login authentication-failure-url="/login.jsp" default-target-url="/index.jsp" login-page="/login.jsp" login-processing-url="/login.do" /> <logout logout-success-url="/index.jsp" logout-url="/logout.do" /> <anonymous /> <intercept-url pattern="/sparklr/**" access="ROLE_USER" /> <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" /></http> 52
    77. 77. Then Tell Spring Security About Our OAuth Endpoints<authentication-manager xmlns="http://www.springframework.org/schema/security"> <authentication-provider> <user-service> <user name="marissa" password="wombat" authorities="ROLE_USER" /> <user name="sam" password="kangaroo" authorities="ROLE_USER" /> </user-service> </authentication-provider></authentication-manager><oauth:client id="oauth2ClientFilter" redirect-on-error="${redirectOnError:false}" /><oauth:resource id="sparklr" type="authorization_code" client-id="tonr" client-secret="secret" access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read" /> 53
    78. 78. Then get an Instance of a RestTemplate for the client...<bean class="org.springframework.security.oauth2.client.OAuth2RestTemplate"> <constructor-arg ref = “sparklr”/></bean> 54
    79. 79. Questions?Josh Long | josh.long@springsource.com | @starbuxman NOT CONFIDENTIAL -- TELL EVERYONE

    ×