SlideShare a Scribd company logo
1 of 78
© 2013 SpringSource, by VMware
Multi Client Development with Spring
Josh Long (⻰龙之春)
@starbuxman
joshlong.com
josh.long@springsource.com
slideshare.net/joshlong
Wednesday, June 5, 13
Spring’s Servlet support
Wednesday, June 5, 13
Servlet 3.0 Initializer Classes
public class SampleWebApplicationInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.setServletContext(sc);
ac.scan( “a.package.full.of.services”, “a.package.full.of.controllers” );
sc.addServlet("spring", new DispatcherServlet(ac));
}
}
Wednesday, June 5, 13
Servlet Support in Spring
§ Spring Dispatcher Servlet provides a lot of powerful support
§ lots of convenient utility objects
HttpRequestHandlers supports remoting: Caucho, Resin, JAX RPC, etc.
DelegatingFilterProxy javax.filter.Filter that delegates to a Spring-managed lifecycle
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
WebApplicationContextUtils has a static method to look up the current ApplicationContext given a ServletContext
Wednesday, June 5, 13
Spring Web Framework Support
•Spring Faces for JSF 1 and 2
•Struts support for Struts 1
•Tapestry, Struts 2, Stripes, Wicket, Vaadin, Play framework, etc.
•GWT, Flex
Wednesday, June 5, 13
introducing Spring MVC
Wednesday, June 5, 13
classic Spring MVC application architecture
DispatcherServlet controller
view
template
delegate
request
delegate
rendering of
response
render
response
return
control
model
model
incoming
requests
return
response
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
// ...
}
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value= “/url/of/my/resource”)
public String processTheRequest() {
// ...
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/resource
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value= “/url/of/my/resource”, method = RequestMethod.GET)
public String processTheRequest() {
// ...
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/resource
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET)
public String processTheRequest( HttpServletRequest request) {
String contextPath = request.getContextPath();
// ...
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/resource
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET)
public String processTheRequest( @RequestParam(“search”) String searchQuery){
// ...
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/resource?search=searchQuery
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)
public String processTheRequest( @PathVariable(“id”) Long id){
// ...
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/12345
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@Inject private CustomerService service ;
@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)
public String processTheRequest(Model model, @PathVariable(“id”) Long id){
model.addAttribute(“customer”, service.getCustomerById( id ) );
return “home”;
}
}
GET http://127.0.0.1:8080/url/of/my/12345
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)
public String processTheRequest( ... ){
return “home”;
}
}
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)
public View processTheRequest( ... ){
return new XsltView(...);
}
}
Wednesday, June 5, 13
the anatomy of a Spring MVC controller
@Controller
public class CustomerController {
@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.PUT)
public ResponseEntity<byte[]> processTheRequest(UriComponentsBuilder componentsBuilder){
byte[] bytesToReturn = ...
HttpHeaders headers = new HttpHeaders();
headers.setLocation( componentsBuilder.toUri() );
return new ResponseEntity<byte[]>(
bytesToReturn, headers, HttpStatus.CREATED
);
}
}
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
when dumb clients
roamed the earth...
Wednesday, June 5, 13
title
Wednesday, June 5, 13
Wednesday, June 5, 13
22
Wednesday, June 5, 13
Wednesday, June 5, 13
REST
Wednesday, June 5, 13
Roy Fielding’s “REST”
• The term Representational State Transfer was introduced and
defined in 2000 by Roy Fielding in his doctoral dissertation.
§ Takeaways:
• Use HTTP methods explicitly.
• Be stateless
• an HTTP resource is uniquely described by its URL
Wednesday, June 5, 13
RestTemplate
•DELETE delete(...)
•GET getForObject(...)
•HEAD headForHeaders(...)
•OPTIONS optionsForAllow(...)
•POST postForLocation(...)
•PUT put(...)
•any HTTP operation - exchange(...) and execute(...)
Wednesday, June 5, 13
RestTemplate
§ Google search example
§ Multiple parameters
RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/hotels/{hotel}/bookings/{booking}";
String result = restTemplate.getForObject(url, String.class, "42", “21”);
RestTemplate restTemplate = new RestTemplate();
String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";
String result = restTemplate.getForObject(url, String.class, "SpringSource");
Wednesday, June 5, 13
the anatomy of a Spring MVC REST controller
@Controller
public class CustomerController {
@Inject private CustomerService service ;
@RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.GET)
public @ResponseBody Customer processTheRequest( ... ) {
Customer c = service.getCustomerById( id) ;
return c;
}
}
GET http://127.0.0.1:8080/url/of/my/resource
Wednesday, June 5, 13
the anatomy of a Spring MVC REST controller
@Controller
public class CustomerController {
@RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.POST)
public void processTheRequest( @RequestBody Customer customer ) {
// ...
}
}
POST http://127.0.0.1:8080/url/of/my/resource
Wednesday, June 5, 13
A Fly in the Ointment
•modern browsers only speak GET and POST
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/</url-pattern>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
build mobile
friendly web applications
Wednesday, June 5, 13
Be Where Your Users Are
§ Best strategy? Develop Native
• Fallback to client-optimized web applications
§ Spring MVC mobile client-specific content
negotiation and rendering
• for other devices
Wednesday, June 5, 13
Registering Spring Android
@EnableWebMvc
@Configuration
public class MobileConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List< HandlerMethodArgumentResolver > argumentResolvers) {
argumentResolvers.add(new DeviceHandlerMethodArgumentResolver());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DeviceResolverHandlerInterceptor());
}
}
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
build native Android applications
Wednesday, June 5, 13
What is Spring for Android?
§ does not prescribe a dependency injection solution
§ provides an implementation of RestTemplate
Wednesday, June 5, 13
Some Native Android Code
	 public Customer updateCustomer(long id, String firstName, String lastName) {
	 	 RestTemplate restTemplate = new RestTemplate();

 
 String url = “http://...8080/url/of/my/{id}”;
	 	 Customer input = new Customer(id, firstName, lastName);
	 	 ResponseEntity<Customer> re = restTemplate.postForEntity( url, input, Customer.class, id);
	 	 HttpStatus statusOfRequest = re.getStatusCode();
	 	 if(statusOfRequest.equals( HttpStatus.OK )){
Customer payloadOfResponse = re.getBody();
return payloadOfResponse;
	 	 }
	 	 ...
	 }
Wednesday, June 5, 13
Make Work with
§ install android development kit http://developer.android.com/sdk/index.html
§ set up m2e-android http://rgladwell.github.io/m2e-android/
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
NOT CONFIDENTIAL -- TELL EVERYONE
@SpringSource @Starbuxman
Questions?
Wednesday, June 5, 13
a more sociable Spring
Wednesday, June 5, 13
A Web of APIs
Wednesday, June 5, 13
What Problems Does OAuth Solve?
• new world of many, cooperating web services
• some web services may have a user context
• this user context can refer to a centrally managed identity (single sign-on)
• user passwords should be decoupled from the permissions a client is given
Wednesday, June 5, 13
What Problems Does OAuth Solve?
Wednesday, June 5, 13
What Problems Does OAuth Solve?
Wednesday, June 5, 13
What Problems Does OAuth Solve?
Wednesday, June 5, 13
Key Components of Spring Social
§ Connection Factories
• Creates connections; Handles back-end of authorization flow
§ Connection Repository
• Persists connections for long-term use
§ Connection Factory Locator
• Used by connect controller and connection repository to find connection factories
§ API Bindings
• Perform requests to APIs, binding to domain objects, error-handling (Facebook, Twitter, etc.)
§ ConnectController
• Orchestrates the web-based connection flow
§ ProviderSignInController
• Signs a user into an application based on an existing connection and links it to the local system
Wednesday, June 5, 13
Bindings...
Wednesday, June 5, 13
...LOTS of Third Party Bindings
Wednesday, June 5, 13
Installing Spring Social
@Configuration
@PropertySource("classpath:social.properties")
@EnableJdbcConnectionRepository
@EnableFacebook(appId = "${facebook.clientId}", appSecret = "${facebook.clientSecret}")
public class SocialConfiguration {
@Bean
public UserIdSource userIdSource() {
return new AuthenticationNameUserIdSource();
}
...
Wednesday, June 5, 13
The ConnectController
@Bean
public ConnectController connectController(
ConnectionFactoryLocator connectionFactoryLocator,
ConnectionRepository connectionRepository) {
return new ConnectController(
connectionFactoryLocator,
connectionRepository);
}
establishes an OAuth-secured connection with the service
provider and returns an access token
Wednesday, June 5, 13
The ProviderSignInController
@Bean
public ProviderSignInController providerSignInController(
final UsersConnectionRepository usersConnectionRepository,
final ConnectionFactoryLocator connectionFactoryLocator) {
SignInAdapter signInAdapter = ...
ProviderSignInController psic = new ProviderSignInController(
connectionFactoryLocator, usersConnectionRepository, signInAdapter);
psic.setSignInUrl("/crm/signin.html");
psic.setPostSignInUrl("/crm/customers.html");
psic.setSignUpUrl("/crm/signup.html");
return psic;
}
}
establishes an OAuth-secured connection with the service
provider and links it to a local account
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
secure web applications with
Spring Security
Wednesday, June 5, 13
Security is Hard, Spring Security is Easy
§ Spring Security provides security services for the Spring framework
§ integrates with backend identity provider services like LDAP, JAAS, OAuth, etc.
§ API Bindings
• there are lots of implementations of the Spring Security API that can be used in terms of a particular backend
identity provider service.
§ can be used to secure web applications
• form submissions, XSS-protection, resource protection
§ can be used to secure method invocations
§ authentication and authorization API
§ cryptography implementations
Wednesday, June 5, 13
Install Spring Security in your web.xml or Application Initializer
public class CrmWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
String name = "springSecurityFilterChain";
Filter filter = new DelegatingFilterProxy();
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter(name, filter);
filterRegistration.addMappingForUrlPatterns(null, true, "/");
filterRegistration.addMappingForServletNames(null, true, "spring");
filterRegistration.setAsyncSupported(true);
}
Wednesday, June 5, 13
Tell Spring About Your Identities: Inline
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="jlong" authorities="read" />
<sec:user name="mchang" authorities="read,write" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
Wednesday, June 5, 13
Tell Spring About Your Identities With a Custom Implementation
<sec:authentication-manager>
<sec:authentication-provider user-service-ref = “customUserService” />
</sec:authentication-manager>
Wednesday, June 5, 13
Tell Spring About Your Identities with LDAP
<sec:authentication-manager>
<sec:ldap-authentication-provider ... />
</sec:authentication-manager>
Wednesday, June 5, 13
Secure Access to Certain Web Resources
<sec:http auto-config="true" use-expressions="true">
<sec:intercept-url pattern="/secured/**" access="hasRole('ROLE_USER')" />
<sec:intercept-url pattern="/**" access="isAnonymous()" />
<sec:anonymous />
</sec:http>
Wednesday, June 5, 13
Install a Sign-In Form
<sec:http auto-config="true" use-expressions="true">
<sec:intercept-url pattern="/secured/**" access="hasRole('ROLE_USER')" />
<sec:intercept-url pattern="/**" access="isAnonymous()" />
<sec:anonymous />
<sec:form-login
login-page="/crm/signin.html"
default-target-url="/crm/profile.html"
authentication-failure-url="/crm/signin.html?error=true" />
</sec:http>
Wednesday, June 5, 13
Install a Sign-In Form
<form method="POST" action="j_spring_security_check">
Username:
<input name="j_username" type="text" />
<br/>
Password:
<input name="j_password" type="password" />
<br/>
<button type="submit" name="action" value="signin" > Sign In</button>
</form>
Wednesday, June 5, 13
Programmatically Authenticate
SecurityContext securityContext = SecurityContextHolder.getContext();
// read the current context authentication
Authentication authentication = securityContext.getAuthentication();
Object credentials = authentication.getCredentials(); // might be a password String
Object details = authentication.getDetails(); // might be a UserDetails object
// set the current context authentication
Authentication toAuthenticate = ...
securityContext.setAuthentication( toAuthenticate );
thread local
Wednesday, June 5, 13
Restrict Method Invocations
@PreAuthorize(" hasRole('ROLE_USER') ")
public void updateProfileInformation(String firstName, String lastName) {
// ...
}
<sec:global-method-security
pre-post-annotations="enabled"
proxy-target-class="true"/>
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
secure web services
with Spring Security OAuth
Wednesday, June 5, 13
What Problems Does OAuth Solve?
• new world of many, cooperating web services
• some web services may have a user context
• this user context can refer to a centrally managed identity (single sign-on)
• user passwords should be decoupled from the permissions a client is given
Wednesday, June 5, 13
When Should I Use Spring Security OAuth?
§ when you want to build an OAuth authentication server
§ when your REST API has a user context that needs to be managed
Wednesday, June 5, 13
Spring Security OAuth
§ Extension to Spring Security
• originally a community contribution (now officially part of the project)
§ Features...
• endpoint management for OAuth service types
• token management (persistence, authentication)
• integrations for the web, as well as through standard Spring Security
Wednesday, June 5, 13
Tell Spring About the Clients That Might Connect
<oauth:client-details-service id="clientDetailsService">
<oauth:client
client-id="html5-crm"
scope="read,write"
authorities="ROLE_USER"
authorized-grant-types="authorization_code,implicit"
resource-ids="crm"/>
<oauth:client
client-id="android-crm"
scope="read,write"
authorities="ROLE_USER"
authorized-grant-types="authorization_code,implicit"
resource-ids="crm"/>
</oauth:client-details-service>
Wednesday, June 5, 13
Tell Spring About the Clients That Might Connect
<oauth:authorization-server
client-details-service-ref="clientDetailsService"
token-services-ref="tokenServices">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials/>
<oauth:password/>
</oauth:authorization-server>
@Bean
public InMemoryTokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
public DefaultTokenServices tokenServices(
InMemoryTokenStore tokenStore,
ClientDetailsService clientDetailsService) {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setClientDetailsService(clientDetailsService);
return defaultTokenServices;
}
Wednesday, June 5, 13
Tell Spring About Which Resources It’s Protecting
<oauth:resource-server id="resourceServerFilter"
resource-id="crm" token-services-ref="tokenServices"/>
<sec:http pattern="/api/**"
create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager">
<sec:anonymous enabled="true"/>
<sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
...
Wednesday, June 5, 13
Tell Spring About Which Resources It’s Protecting
<oauth:resource-server id="resourceServerFilter"
resource-id="crm" token-services-ref="tokenServices"/>
<sec:http pattern="/api/**"
create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager">
<sec:anonymous enabled="true"/>
<sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<sec:intercept-url pattern="/api/users/**/photo" method="GET"
access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/api/users" method="GET" access="IS_AUTHENTI
CATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/api/**"
access="ROLE_USER,SCOPE_READ"/>
Wednesday, June 5, 13
Optional: Set Up an OAuth-Aware RestTemplate
<oauth:rest-template id="crmRestTemplate" resource="crm" />
Wednesday, June 5, 13
Enable Access to Certain OAuth-Context Objects in SpEL
<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler"/>
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler"/>
<oauth:web-expression-handler id="oauthWebExpressionHandler"/>
Wednesday, June 5, 13
Demonstration
Wednesday, June 5, 13
NOT CONFIDENTIAL -- TELL EVERYONE
@SpringSource @Starbuxman
Questions?
Wednesday, June 5, 13

More Related Content

What's hot

Tomcat连接池配置方法V2.1
Tomcat连接池配置方法V2.1Tomcat连接池配置方法V2.1
Tomcat连接池配置方法V2.1Zianed Hou
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recapfurusin
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Ryosuke Uchitate
 
Introduction to Angular js
Introduction to Angular jsIntroduction to Angular js
Introduction to Angular jsMustafa Gamal
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentationmrmean
 
Building High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsBuilding High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsMichele Capra
 
Taking a Test Drive
Taking a Test DriveTaking a Test Drive
Taking a Test DriveGraham Lee
 
Jsp/Servlet
Jsp/ServletJsp/Servlet
Jsp/ServletSunil OS
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance DjangoDjangoCon2008
 
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Implicit and Explicit waits in Selenium WebDriwer, how to.
Implicit and Explicit waits in Selenium WebDriwer, how to.Implicit and Explicit waits in Selenium WebDriwer, how to.
Implicit and Explicit waits in Selenium WebDriwer, how to.Yaroslav Pernerovsky
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & HibernateJiayun Zhou
 

What's hot (20)

Tomcat连接池配置方法V2.1
Tomcat连接池配置方法V2.1Tomcat连接池配置方法V2.1
Tomcat连接池配置方法V2.1
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recap
 
Physical web
Physical webPhysical web
Physical web
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
 
Nancy + rest mow2012
Nancy + rest   mow2012Nancy + rest   mow2012
Nancy + rest mow2012
 
Introduction to Angular js
Introduction to Angular jsIntroduction to Angular js
Introduction to Angular js
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentation
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Building High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsBuilding High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 Apps
 
Taking a Test Drive
Taking a Test DriveTaking a Test Drive
Taking a Test Drive
 
Jsp/Servlet
Jsp/ServletJsp/Servlet
Jsp/Servlet
 
KISS Automation.py
KISS Automation.pyKISS Automation.py
KISS Automation.py
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance Django
 
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
Implicit and Explicit waits in Selenium WebDriwer, how to.
Implicit and Explicit waits in Selenium WebDriwer, how to.Implicit and Explicit waits in Selenium WebDriwer, how to.
Implicit and Explicit waits in Selenium WebDriwer, how to.
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
WebDriver Waits
WebDriver WaitsWebDriver Waits
WebDriver Waits
 

Viewers also liked

The economies of scaling software - Abdel Remani
The economies of scaling software - Abdel RemaniThe economies of scaling software - Abdel Remani
The economies of scaling software - Abdel Remanijaxconf
 
What you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie AllenWhat you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie Allenjaxconf
 
Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta jaxconf
 
Building an Impenetrable ZooKeeper - Kathleen Ting
Building an Impenetrable ZooKeeper - Kathleen TingBuilding an Impenetrable ZooKeeper - Kathleen Ting
Building an Impenetrable ZooKeeper - Kathleen Tingjaxconf
 
Future of the Web - Yehuda Katz
Future of the Web - Yehuda KatzFuture of the Web - Yehuda Katz
Future of the Web - Yehuda Katzjaxconf
 
The New Reality: the Role of PaaS in Technology Innovation - Franklin Herbas
The New Reality: the Role of PaaS in Technology Innovation - Franklin HerbasThe New Reality: the Role of PaaS in Technology Innovation - Franklin Herbas
The New Reality: the Role of PaaS in Technology Innovation - Franklin Herbasjaxconf
 
The Spring 4 Update - Josh Long
The Spring 4 Update - Josh LongThe Spring 4 Update - Josh Long
The Spring 4 Update - Josh Longjaxconf
 
Java PaaS Comparisons - Khanderao Kand
Java PaaS Comparisons - Khanderao KandJava PaaS Comparisons - Khanderao Kand
Java PaaS Comparisons - Khanderao Kandjaxconf
 
Apache Hadoop and its role in Big Data architecture - Himanshu Bari
Apache Hadoop and its role in Big Data architecture - Himanshu BariApache Hadoop and its role in Big Data architecture - Himanshu Bari
Apache Hadoop and its role in Big Data architecture - Himanshu Barijaxconf
 
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...jaxconf
 
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...jaxconf
 
Architecting Android Apps: Marko Gargenta
Architecting Android Apps: Marko GargentaArchitecting Android Apps: Marko Gargenta
Architecting Android Apps: Marko Gargentajaxconf
 
The Evolution of Java Persistence in EclipseLink: Shaun Smith
The Evolution of Java Persistence in EclipseLink: Shaun SmithThe Evolution of Java Persistence in EclipseLink: Shaun Smith
The Evolution of Java Persistence in EclipseLink: Shaun Smithjaxconf
 
JSF2 Composite Components - Ian Hlavats
JSF2 Composite Components - Ian HlavatsJSF2 Composite Components - Ian Hlavats
JSF2 Composite Components - Ian Hlavatsjaxconf
 
From Tomcat to Java EE, making the transition with TomEE
From Tomcat to Java EE, making the transition with TomEEFrom Tomcat to Java EE, making the transition with TomEE
From Tomcat to Java EE, making the transition with TomEEjaxconf
 
Tugas akhir tik imaniar fitriani
Tugas akhir tik imaniar fitrianiTugas akhir tik imaniar fitriani
Tugas akhir tik imaniar fitrianiPaarief Udin
 
Tugas xii ips 3 amalia ihsana dan jannatun nisa
Tugas xii ips 3 amalia ihsana dan jannatun nisaTugas xii ips 3 amalia ihsana dan jannatun nisa
Tugas xii ips 3 amalia ihsana dan jannatun nisaPaarief Udin
 

Viewers also liked (20)

The economies of scaling software - Abdel Remani
The economies of scaling software - Abdel RemaniThe economies of scaling software - Abdel Remani
The economies of scaling software - Abdel Remani
 
What you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie AllenWhat you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie Allen
 
Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta Getting started with Websocket and Server-sent Events using Java - Arun Gupta
Getting started with Websocket and Server-sent Events using Java - Arun Gupta
 
Building an Impenetrable ZooKeeper - Kathleen Ting
Building an Impenetrable ZooKeeper - Kathleen TingBuilding an Impenetrable ZooKeeper - Kathleen Ting
Building an Impenetrable ZooKeeper - Kathleen Ting
 
Future of the Web - Yehuda Katz
Future of the Web - Yehuda KatzFuture of the Web - Yehuda Katz
Future of the Web - Yehuda Katz
 
The New Reality: the Role of PaaS in Technology Innovation - Franklin Herbas
The New Reality: the Role of PaaS in Technology Innovation - Franklin HerbasThe New Reality: the Role of PaaS in Technology Innovation - Franklin Herbas
The New Reality: the Role of PaaS in Technology Innovation - Franklin Herbas
 
The Spring 4 Update - Josh Long
The Spring 4 Update - Josh LongThe Spring 4 Update - Josh Long
The Spring 4 Update - Josh Long
 
Java PaaS Comparisons - Khanderao Kand
Java PaaS Comparisons - Khanderao KandJava PaaS Comparisons - Khanderao Kand
Java PaaS Comparisons - Khanderao Kand
 
Apache Hadoop and its role in Big Data architecture - Himanshu Bari
Apache Hadoop and its role in Big Data architecture - Himanshu BariApache Hadoop and its role in Big Data architecture - Himanshu Bari
Apache Hadoop and its role in Big Data architecture - Himanshu Bari
 
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...
Vaadin, Rich Web Apps in Server-Side Java without Plug-ins or JavaScript: Joo...
 
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
 
Architecting Android Apps: Marko Gargenta
Architecting Android Apps: Marko GargentaArchitecting Android Apps: Marko Gargenta
Architecting Android Apps: Marko Gargenta
 
The Evolution of Java Persistence in EclipseLink: Shaun Smith
The Evolution of Java Persistence in EclipseLink: Shaun SmithThe Evolution of Java Persistence in EclipseLink: Shaun Smith
The Evolution of Java Persistence in EclipseLink: Shaun Smith
 
JSF2 Composite Components - Ian Hlavats
JSF2 Composite Components - Ian HlavatsJSF2 Composite Components - Ian Hlavats
JSF2 Composite Components - Ian Hlavats
 
From Tomcat to Java EE, making the transition with TomEE
From Tomcat to Java EE, making the transition with TomEEFrom Tomcat to Java EE, making the transition with TomEE
From Tomcat to Java EE, making the transition with TomEE
 
τα αγγεία
τα αγγείατα αγγεία
τα αγγεία
 
Tugas akhir tik imaniar fitriani
Tugas akhir tik imaniar fitrianiTugas akhir tik imaniar fitriani
Tugas akhir tik imaniar fitriani
 
Tugas xii ips 3 amalia ihsana dan jannatun nisa
Tugas xii ips 3 amalia ihsana dan jannatun nisaTugas xii ips 3 amalia ihsana dan jannatun nisa
Tugas xii ips 3 amalia ihsana dan jannatun nisa
 
Esite Norton Vitrium3
Esite Norton Vitrium3Esite Norton Vitrium3
Esite Norton Vitrium3
 
Data visualization tools
Data visualization tools Data visualization tools
Data visualization tools
 

Similar to Multi Client Development with Spring - Josh Long

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Jersey framework
Jersey frameworkJersey framework
Jersey frameworkknight1128
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsSimo Ahava
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jerseyb_kathir
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3mihirio
 
03 form-data
03 form-data03 form-data
03 form-datasnopteck
 
Spring MVC 3 Restful
Spring MVC 3 RestfulSpring MVC 3 Restful
Spring MVC 3 Restfulknight1128
 
Unit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterUnit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterWayan Wira
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC AnnotationsJordan Silva
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTruls Jørgensen
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013Michelangelo van Dam
 

Similar to Multi Client Development with Spring - Josh Long (20)

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Jersey framework
Jersey frameworkJersey framework
Jersey framework
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
 
Ajax - a quick introduction
Ajax - a quick introductionAjax - a quick introduction
Ajax - a quick introduction
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
 
servlets
servletsservlets
servlets
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
03 form-data
03 form-data03 form-data
03 form-data
 
Spring MVC 3 Restful
Spring MVC 3 RestfulSpring MVC 3 Restful
Spring MVC 3 Restful
 
Unit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterUnit testing CourseSites Apache Filter
Unit testing CourseSites Apache Filter
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
 
SPARQLing cocktails
SPARQLing cocktailsSPARQLing cocktails
SPARQLing cocktails
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinner
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
 

Recently uploaded

How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxKaustubhBhavsar6
 
Patch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updatePatch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updateadam112203
 
IT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingIT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingMAGNIntelligence
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox
 
3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud DataEric D. Schabell
 
LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0DanBrown980551
 
Trailblazer Community - Flows Workshop (Session 2)
Trailblazer Community - Flows Workshop (Session 2)Trailblazer Community - Flows Workshop (Session 2)
Trailblazer Community - Flows Workshop (Session 2)Muhammad Tiham Siddiqui
 
Flow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameFlow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameKapil Thakar
 
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxEmil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxNeo4j
 
Where developers are challenged, what developers want and where DevEx is going
Where developers are challenged, what developers want and where DevEx is goingWhere developers are challenged, what developers want and where DevEx is going
Where developers are challenged, what developers want and where DevEx is goingFrancesco Corti
 
UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2DianaGray10
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch TuesdayIvanti
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTopCSSGallery
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIVijayananda Mohire
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FESTBillieHyde
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNeo4j
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl
 

Recently uploaded (20)

How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptx
 
Patch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updatePatch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 update
 
IT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingIT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced Computing
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
 
SheDev 2024
SheDev 2024SheDev 2024
SheDev 2024
 
3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data
 
LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0LF Energy Webinar - Unveiling OpenEEMeter 4.0
LF Energy Webinar - Unveiling OpenEEMeter 4.0
 
Trailblazer Community - Flows Workshop (Session 2)
Trailblazer Community - Flows Workshop (Session 2)Trailblazer Community - Flows Workshop (Session 2)
Trailblazer Community - Flows Workshop (Session 2)
 
Flow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First FrameFlow Control | Block Size | ST Min | First Frame
Flow Control | Block Size | ST Min | First Frame
 
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptxEmil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
Emil Eifrem at GraphSummit Copenhagen 2024 - The Art of the Possible.pptx
 
Where developers are challenged, what developers want and where DevEx is going
Where developers are challenged, what developers want and where DevEx is goingWhere developers are challenged, what developers want and where DevEx is going
Where developers are challenged, what developers want and where DevEx is going
 
UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2UiPath Studio Web workshop series - Day 2
UiPath Studio Web workshop series - Day 2
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch Tuesday
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development Companies
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAI
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FEST
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4j
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile Brochure
 

Multi Client Development with Spring - Josh Long

  • 1. © 2013 SpringSource, by VMware Multi Client Development with Spring Josh Long (⻰龙之春) @starbuxman joshlong.com josh.long@springsource.com slideshare.net/joshlong Wednesday, June 5, 13
  • 3. Servlet 3.0 Initializer Classes public class SampleWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ac.setServletContext(sc); ac.scan( “a.package.full.of.services”, “a.package.full.of.controllers” ); sc.addServlet("spring", new DispatcherServlet(ac)); } } Wednesday, June 5, 13
  • 4. Servlet Support in Spring § Spring Dispatcher Servlet provides a lot of powerful support § lots of convenient utility objects HttpRequestHandlers supports remoting: Caucho, Resin, JAX RPC, etc. DelegatingFilterProxy javax.filter.Filter that delegates to a Spring-managed lifecycle 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 WebApplicationContextUtils has a static method to look up the current ApplicationContext given a ServletContext Wednesday, June 5, 13
  • 5. Spring Web Framework Support •Spring Faces for JSF 1 and 2 •Struts support for Struts 1 •Tapestry, Struts 2, Stripes, Wicket, Vaadin, Play framework, etc. •GWT, Flex Wednesday, June 5, 13
  • 7. classic Spring MVC application architecture DispatcherServlet controller view template delegate request delegate rendering of response render response return control model model incoming requests return response Wednesday, June 5, 13
  • 8. the anatomy of a Spring MVC controller @Controller public class CustomerController { // ... } Wednesday, June 5, 13
  • 9. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value= “/url/of/my/resource”) public String processTheRequest() { // ... return “home”; } } GET http://127.0.0.1:8080/url/of/my/resource Wednesday, June 5, 13
  • 10. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value= “/url/of/my/resource”, method = RequestMethod.GET) public String processTheRequest() { // ... return “home”; } } GET http://127.0.0.1:8080/url/of/my/resource Wednesday, June 5, 13
  • 11. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET) public String processTheRequest( HttpServletRequest request) { String contextPath = request.getContextPath(); // ... return “home”; } } GET http://127.0.0.1:8080/url/of/my/resource Wednesday, June 5, 13
  • 12. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET) public String processTheRequest( @RequestParam(“search”) String searchQuery){ // ... return “home”; } } GET http://127.0.0.1:8080/url/of/my/resource?search=searchQuery Wednesday, June 5, 13
  • 13. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET) public String processTheRequest( @PathVariable(“id”) Long id){ // ... return “home”; } } GET http://127.0.0.1:8080/url/of/my/12345 Wednesday, June 5, 13
  • 14. the anatomy of a Spring MVC controller @Controller public class CustomerController { @Inject private CustomerService service ; @RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET) public String processTheRequest(Model model, @PathVariable(“id”) Long id){ model.addAttribute(“customer”, service.getCustomerById( id ) ); return “home”; } } GET http://127.0.0.1:8080/url/of/my/12345 Wednesday, June 5, 13
  • 15. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET) public String processTheRequest( ... ){ return “home”; } } Wednesday, June 5, 13
  • 16. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET) public View processTheRequest( ... ){ return new XsltView(...); } } Wednesday, June 5, 13
  • 17. the anatomy of a Spring MVC controller @Controller public class CustomerController { @RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.PUT) public ResponseEntity<byte[]> processTheRequest(UriComponentsBuilder componentsBuilder){ byte[] bytesToReturn = ... HttpHeaders headers = new HttpHeaders(); headers.setLocation( componentsBuilder.toUri() ); return new ResponseEntity<byte[]>( bytesToReturn, headers, HttpStatus.CREATED ); } } Wednesday, June 5, 13
  • 19. when dumb clients roamed the earth... Wednesday, June 5, 13
  • 25. Roy Fielding’s “REST” • The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation. § Takeaways: • Use HTTP methods explicitly. • Be stateless • an HTTP resource is uniquely described by its URL Wednesday, June 5, 13
  • 26. RestTemplate •DELETE delete(...) •GET getForObject(...) •HEAD headForHeaders(...) •OPTIONS optionsForAllow(...) •POST postForLocation(...) •PUT put(...) •any HTTP operation - exchange(...) and execute(...) Wednesday, June 5, 13
  • 27. RestTemplate § Google search example § Multiple parameters RestTemplate restTemplate = new RestTemplate(); String url = "http://example.com/hotels/{hotel}/bookings/{booking}"; String result = restTemplate.getForObject(url, String.class, "42", “21”); RestTemplate restTemplate = new RestTemplate(); String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}"; String result = restTemplate.getForObject(url, String.class, "SpringSource"); Wednesday, June 5, 13
  • 28. the anatomy of a Spring MVC REST controller @Controller public class CustomerController { @Inject private CustomerService service ; @RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.GET) public @ResponseBody Customer processTheRequest( ... ) { Customer c = service.getCustomerById( id) ; return c; } } GET http://127.0.0.1:8080/url/of/my/resource Wednesday, June 5, 13
  • 29. the anatomy of a Spring MVC REST controller @Controller public class CustomerController { @RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.POST) public void processTheRequest( @RequestBody Customer customer ) { // ... } } POST http://127.0.0.1:8080/url/of/my/resource Wednesday, June 5, 13
  • 30. A Fly in the Ointment •modern browsers only speak GET and POST <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/</url-pattern> <servlet-name>appServlet</servlet-name> </filter-mapping> Wednesday, June 5, 13
  • 32. build mobile friendly web applications Wednesday, June 5, 13
  • 33. Be Where Your Users Are § Best strategy? Develop Native • Fallback to client-optimized web applications § Spring MVC mobile client-specific content negotiation and rendering • for other devices Wednesday, June 5, 13
  • 34. Registering Spring Android @EnableWebMvc @Configuration public class MobileConfiguration extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers(List< HandlerMethodArgumentResolver > argumentResolvers) { argumentResolvers.add(new DeviceHandlerMethodArgumentResolver()); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new DeviceResolverHandlerInterceptor()); } } Wednesday, June 5, 13
  • 36. build native Android applications Wednesday, June 5, 13
  • 37. What is Spring for Android? § does not prescribe a dependency injection solution § provides an implementation of RestTemplate Wednesday, June 5, 13
  • 38. Some Native Android Code public Customer updateCustomer(long id, String firstName, String lastName) { RestTemplate restTemplate = new RestTemplate(); String url = “http://...8080/url/of/my/{id}”; Customer input = new Customer(id, firstName, lastName); ResponseEntity<Customer> re = restTemplate.postForEntity( url, input, Customer.class, id); HttpStatus statusOfRequest = re.getStatusCode(); if(statusOfRequest.equals( HttpStatus.OK )){ Customer payloadOfResponse = re.getBody(); return payloadOfResponse; } ... } Wednesday, June 5, 13
  • 39. Make Work with § install android development kit http://developer.android.com/sdk/index.html § set up m2e-android http://rgladwell.github.io/m2e-android/ Wednesday, June 5, 13
  • 41. NOT CONFIDENTIAL -- TELL EVERYONE @SpringSource @Starbuxman Questions? Wednesday, June 5, 13
  • 42. a more sociable Spring Wednesday, June 5, 13
  • 43. A Web of APIs Wednesday, June 5, 13
  • 44. What Problems Does OAuth Solve? • new world of many, cooperating web services • some web services may have a user context • this user context can refer to a centrally managed identity (single sign-on) • user passwords should be decoupled from the permissions a client is given Wednesday, June 5, 13
  • 45. What Problems Does OAuth Solve? Wednesday, June 5, 13
  • 46. What Problems Does OAuth Solve? Wednesday, June 5, 13
  • 47. What Problems Does OAuth Solve? Wednesday, June 5, 13
  • 48. Key Components of Spring Social § Connection Factories • Creates connections; Handles back-end of authorization flow § Connection Repository • Persists connections for long-term use § Connection Factory Locator • Used by connect controller and connection repository to find connection factories § API Bindings • Perform requests to APIs, binding to domain objects, error-handling (Facebook, Twitter, etc.) § ConnectController • Orchestrates the web-based connection flow § ProviderSignInController • Signs a user into an application based on an existing connection and links it to the local system Wednesday, June 5, 13
  • 50. ...LOTS of Third Party Bindings Wednesday, June 5, 13
  • 51. Installing Spring Social @Configuration @PropertySource("classpath:social.properties") @EnableJdbcConnectionRepository @EnableFacebook(appId = "${facebook.clientId}", appSecret = "${facebook.clientSecret}") public class SocialConfiguration { @Bean public UserIdSource userIdSource() { return new AuthenticationNameUserIdSource(); } ... Wednesday, June 5, 13
  • 52. The ConnectController @Bean public ConnectController connectController( ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) { return new ConnectController( connectionFactoryLocator, connectionRepository); } establishes an OAuth-secured connection with the service provider and returns an access token Wednesday, June 5, 13
  • 53. The ProviderSignInController @Bean public ProviderSignInController providerSignInController( final UsersConnectionRepository usersConnectionRepository, final ConnectionFactoryLocator connectionFactoryLocator) { SignInAdapter signInAdapter = ... ProviderSignInController psic = new ProviderSignInController( connectionFactoryLocator, usersConnectionRepository, signInAdapter); psic.setSignInUrl("/crm/signin.html"); psic.setPostSignInUrl("/crm/customers.html"); psic.setSignUpUrl("/crm/signup.html"); return psic; } } establishes an OAuth-secured connection with the service provider and links it to a local account Wednesday, June 5, 13
  • 55. secure web applications with Spring Security Wednesday, June 5, 13
  • 56. Security is Hard, Spring Security is Easy § Spring Security provides security services for the Spring framework § integrates with backend identity provider services like LDAP, JAAS, OAuth, etc. § API Bindings • there are lots of implementations of the Spring Security API that can be used in terms of a particular backend identity provider service. § can be used to secure web applications • form submissions, XSS-protection, resource protection § can be used to secure method invocations § authentication and authorization API § cryptography implementations Wednesday, June 5, 13
  • 57. Install Spring Security in your web.xml or Application Initializer public class CrmWebApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { String name = "springSecurityFilterChain"; Filter filter = new DelegatingFilterProxy(); FilterRegistration.Dynamic filterRegistration = servletContext.addFilter(name, filter); filterRegistration.addMappingForUrlPatterns(null, true, "/"); filterRegistration.addMappingForServletNames(null, true, "spring"); filterRegistration.setAsyncSupported(true); } Wednesday, June 5, 13
  • 58. Tell Spring About Your Identities: Inline <sec:authentication-manager> <sec:authentication-provider> <sec:user-service> <sec:user name="jlong" authorities="read" /> <sec:user name="mchang" authorities="read,write" /> </sec:user-service> </sec:authentication-provider> </sec:authentication-manager> Wednesday, June 5, 13
  • 59. Tell Spring About Your Identities With a Custom Implementation <sec:authentication-manager> <sec:authentication-provider user-service-ref = “customUserService” /> </sec:authentication-manager> Wednesday, June 5, 13
  • 60. Tell Spring About Your Identities with LDAP <sec:authentication-manager> <sec:ldap-authentication-provider ... /> </sec:authentication-manager> Wednesday, June 5, 13
  • 61. Secure Access to Certain Web Resources <sec:http auto-config="true" use-expressions="true"> <sec:intercept-url pattern="/secured/**" access="hasRole('ROLE_USER')" /> <sec:intercept-url pattern="/**" access="isAnonymous()" /> <sec:anonymous /> </sec:http> Wednesday, June 5, 13
  • 62. Install a Sign-In Form <sec:http auto-config="true" use-expressions="true"> <sec:intercept-url pattern="/secured/**" access="hasRole('ROLE_USER')" /> <sec:intercept-url pattern="/**" access="isAnonymous()" /> <sec:anonymous /> <sec:form-login login-page="/crm/signin.html" default-target-url="/crm/profile.html" authentication-failure-url="/crm/signin.html?error=true" /> </sec:http> Wednesday, June 5, 13
  • 63. Install a Sign-In Form <form method="POST" action="j_spring_security_check"> Username: <input name="j_username" type="text" /> <br/> Password: <input name="j_password" type="password" /> <br/> <button type="submit" name="action" value="signin" > Sign In</button> </form> Wednesday, June 5, 13
  • 64. Programmatically Authenticate SecurityContext securityContext = SecurityContextHolder.getContext(); // read the current context authentication Authentication authentication = securityContext.getAuthentication(); Object credentials = authentication.getCredentials(); // might be a password String Object details = authentication.getDetails(); // might be a UserDetails object // set the current context authentication Authentication toAuthenticate = ... securityContext.setAuthentication( toAuthenticate ); thread local Wednesday, June 5, 13
  • 65. Restrict Method Invocations @PreAuthorize(" hasRole('ROLE_USER') ") public void updateProfileInformation(String firstName, String lastName) { // ... } <sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"/> Wednesday, June 5, 13
  • 67. secure web services with Spring Security OAuth Wednesday, June 5, 13
  • 68. What Problems Does OAuth Solve? • new world of many, cooperating web services • some web services may have a user context • this user context can refer to a centrally managed identity (single sign-on) • user passwords should be decoupled from the permissions a client is given Wednesday, June 5, 13
  • 69. When Should I Use Spring Security OAuth? § when you want to build an OAuth authentication server § when your REST API has a user context that needs to be managed Wednesday, June 5, 13
  • 70. Spring Security OAuth § Extension to Spring Security • originally a community contribution (now officially part of the project) § Features... • endpoint management for OAuth service types • token management (persistence, authentication) • integrations for the web, as well as through standard Spring Security Wednesday, June 5, 13
  • 71. Tell Spring About the Clients That Might Connect <oauth:client-details-service id="clientDetailsService"> <oauth:client client-id="html5-crm" scope="read,write" authorities="ROLE_USER" authorized-grant-types="authorization_code,implicit" resource-ids="crm"/> <oauth:client client-id="android-crm" scope="read,write" authorities="ROLE_USER" authorized-grant-types="authorization_code,implicit" resource-ids="crm"/> </oauth:client-details-service> Wednesday, June 5, 13
  • 72. Tell Spring About the Clients That Might Connect <oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"> <oauth:authorization-code/> <oauth:implicit/> <oauth:refresh-token/> <oauth:client-credentials/> <oauth:password/> </oauth:authorization-server> @Bean public InMemoryTokenStore tokenStore() { return new InMemoryTokenStore(); } @Bean public DefaultTokenServices tokenServices( InMemoryTokenStore tokenStore, ClientDetailsService clientDetailsService) { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setTokenStore(tokenStore); defaultTokenServices.setSupportRefreshToken(true); defaultTokenServices.setClientDetailsService(clientDetailsService); return defaultTokenServices; } Wednesday, June 5, 13
  • 73. Tell Spring About Which Resources It’s Protecting <oauth:resource-server id="resourceServerFilter" resource-id="crm" token-services-ref="tokenServices"/> <sec:http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager"> <sec:anonymous enabled="true"/> <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/> ... Wednesday, June 5, 13
  • 74. Tell Spring About Which Resources It’s Protecting <oauth:resource-server id="resourceServerFilter" resource-id="crm" token-services-ref="tokenServices"/> <sec:http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager"> <sec:anonymous enabled="true"/> <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/> <sec:intercept-url pattern="/api/users/**/photo" method="GET" access="IS_AUTHENTICATED_ANONYMOUSLY"/> <sec:intercept-url pattern="/api/users" method="GET" access="IS_AUTHENTI CATED_ANONYMOUSLY"/> <sec:intercept-url pattern="/api/**" access="ROLE_USER,SCOPE_READ"/> Wednesday, June 5, 13
  • 75. Optional: Set Up an OAuth-Aware RestTemplate <oauth:rest-template id="crmRestTemplate" resource="crm" /> Wednesday, June 5, 13
  • 76. Enable Access to Certain OAuth-Context Objects in SpEL <sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"> <sec:expression-handler ref="oauthExpressionHandler"/> </sec:global-method-security> <oauth:expression-handler id="oauthExpressionHandler"/> <oauth:web-expression-handler id="oauthWebExpressionHandler"/> Wednesday, June 5, 13
  • 78. NOT CONFIDENTIAL -- TELL EVERYONE @SpringSource @Starbuxman Questions? Wednesday, June 5, 13