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.
2. About Josh Long
SpringSource Developer Advocate
twitter: @starbuxman
josh.long@springsource.com
NOT CONFIDENTIAL -- TELL EVERYONE 2
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. 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
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. 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 framework
the 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. 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 service
Spring 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
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. 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. 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. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC
NOT CONFIDENTIAL -- TELL EVERYONE 13
14. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC
Spring 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. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC
Demos
• Spring MVC and associated configuration
NOT CONFIDENTIAL -- TELL EVERYONE
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. Thin, Thick, Web, Mobile and Rich Clients: REST
RestCustomerController - 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. Thin, Thick, Web, Mobile and Rich Clients: REST
Demos:
• Spring REST service
• Spring REST client
NOT CONFIDENTIAL -- TELL EVERYONE
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. 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. Thin, Thick, Web, Mobile and Rich Clients: REST
Demos:
• Mobile clients using client specific rendering
NOT CONFIDENTIAL -- TELL EVERYONE
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. 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("couldn't 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. Thin, Thick, Web, Mobile and Rich Clients: Mobile
Demos:
• consuming the Spring REST service from Android
NOT CONFIDENTIAL -- TELL EVERYONE
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
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. 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. Thin, Thick, Web, Mobile and Rich Clients: GWT
GwtCustomerService - client
import 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. Thin, Thick, Web, Mobile and Rich Clients: GWT
Demos:
• building a simple GWT client that consumes services in Spring
NOT CONFIDENTIAL -- TELL EVERYONE
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. 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. 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. 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. 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. 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. 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. 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. 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. Configuration: ConnectController
@Bean
public ConnectController connectController() {
return new ConnectController(connectionFactoryLocator(),
connectionRepository());
}
41
46. Configuration: ConnectController
@Bean
public ConnectController connectController() {
return new ConnectController(connectionFactoryLocator(),
connectionRepository());
}
41
47. Configuration: ConnectController
@Bean
public ConnectController connectController() {
return new ConnectController(connectionFactoryLocator(),
connectionRepository());
}
41
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. 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. 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. 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. 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. 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. 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. 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. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
45
57. ConnectController Flow
Your Application
GET /connect/{provider ID}
ConnectController
Service Provider
(Twitter, Facebook, etc)
Display connection status page
45
58. ConnectController Flow
Your Application
POST /connect/{provider ID}
ConnectController
Service Provider
(Twitter, Facebook, etc)
Initiate connection flow
45
59. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Fetch request token (OAuth 1.0/1.0a only)
45
60. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Redirect browser to provider’s authorization page
45
61. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Redirect browser to provider’s authorization page
45
62. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Redirect browser to provider’s authorization page
45
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. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Exchange request token and/or code for access token
45
65. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
ConnectController stores connection details in connection repository
45
66. ConnectController Flow
Your Application
ConnectController
Service Provider
(Twitter, Facebook, etc)
Application can make API calls via API binding
45
67. Connection Status Page View
<form action="<c:url value="/connect/twitter" />" method="POST">
<div class="formInfo">
<p>
You haven't 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. 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. 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
@Bean
public ProviderSignInController providerSignInController(
RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(),
usersConnectionRepository(),
new SimpleSignInAdapter(requestCache));
}
48
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
@Bean
public ProviderSignInController providerSignInController(
RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(),
usersConnectionRepository(),
new SimpleSignInAdapter(requestCache));
}
48
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
@Bean
public ProviderSignInController providerSignInController(
RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(),
usersConnectionRepository(),
new SimpleSignInAdapter(requestCache));
}
48
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
@Bean
public ProviderSignInController providerSignInController(
RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(),
usersConnectionRepository(),
new SimpleSignInAdapter(requestCache));
}
48
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
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
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. Questions?
Josh Long | josh.long@springsource.com | @starbuxman
NOT CONFIDENTIAL -- TELL EVERYONE
Notas do Editor
\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&#x2019;ve used it in earnest and advocated it for many years now. i&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;s happened on the file system\n\n
another example of the fact that often the client side model won&#x2019;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&#x2019;re going to build ourselves a file system poller to notify us of when something&#x2019;s happened on the file system\n\n