Spring Boot in the Web Tier

035ae18f5f948ab3c8a5cbf40bbea383?s=47 Dave Syer
September 09, 2014

Spring Boot in the Web Tier

This presentation shows you how to understand and harness those features for maximum benefit. We will cover the basics of opinionated application configuration, showing what Spring Boot has to offer the web developer out of the box: content negotiation, internationalization, view templates, security, messaging with websockets, etc. We will look at the embedded servlet container abstractions in Spring Boot, showing how to customize the containers, and how to extract the most from the containers at runtime. We will also show how Spring Boot can embed some other interesting and popular web technologies, like Jersey and Ratpack, giving developers instant access to a wide range of useful features, and zero-effort integration with the Spring for middleware integration.

035ae18f5f948ab3c8a5cbf40bbea383?s=128

Dave Syer

September 09, 2014
Tweet

Transcript

  1. Spring Boot for the Web Tier Phillip Webb twiiter: @phillip_webb

    email: pwebb@pivotal.io Dave Syer twitter: @david_syer email: dsyer@pivotal.io http://localhost:4000/decks/spring-boot-for-the-web-tier.html 1 of 43 10/09/14 08:15
  2. Presentation Overview Part 1 - Static Content Part 2 -

    Dynamic Content Part 3 - Embedded Server Part 4 - Other Stacks http://localhost:4000/decks/spring-boot-for-the-web-tier.html 2 of 43 10/09/14 08:15
  3. Static Content - Serving Files Can't use /src/main/webapp for jar

    deployments Put static files from src/main/resources/static or .../public or .../resources or .../META- INF/resources http://localhost:4000/decks/spring-boot-for-the-web-tier.html 3 of 43 10/09/14 08:15
  4. Static Content - Conventions src/main/resources/static/index.html is mapped to /index.html &

    / Add a src/main/resources/favicon.ico to replace the Spring Leaf Imported "webjars" are automatically mapped http://localhost:4000/decks/spring-boot-for-the-web-tier.html 4 of 43 10/09/14 08:15
  5. Demo - Static Content http://localhost:4000/decks/spring-boot-for-the-web-tier.html 5 of 43 10/09/14 08:15

  6. Static Content: Grunt Toolchain For serious front end developers the

    best choice is a Javascript toolchain. Good community, lots of tools Package static assets into a jar And/or build them as part of a very thin back end Spring Boot CLI makes a great lightweight back end in production or for Java devs http://localhost:4000/decks/spring-boot-for-the-web-tier.html 6 of 43 10/09/14 08:15
  7. Static Content - wro4j Great for Java developers Often good

    enough JsHint CssLint JsMin Google Closure compressor UglifyJs Less Sass http://localhost:4000/decks/spring-boot-for-the-web-tier.html 7 of 43 10/09/14 08:15
  8. Static Content - Wro4j with Maven http://localhost:4000/decks/spring-boot-for-the-web-tier.html 8 of 43

    10/09/14 08:15
  9. <plugin> <groupId>ro.isdc.wro4j</groupId> <artifactId>wro4j-maven-plugin</artifactId> <version>${wro4j.version}</version> <executions><execution> <phase>generate-resources</phase> <goals><goal>run</goal></goals> </execution></executions> <configuration> <wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.Configu

    rableWroManagerFactory</wroManagerFactory> <destinationFolder>${basedir}/target/generated-resources /static/</destinationFolder> <wroFile>${basedir}/src/main/wro/wro.xml</wroFile> <extraConfigFile>${basedir}/src/main/wro /wro.properties</extraConfigFile> </configuration> </plugin> http://localhost:4000/decks/spring-boot-for-the-web-tier.html 9 of 43 10/09/14 08:15
  10. Static Content - Wro4j with Maven src/main/wro/wro.xml <groups xmlns="http://www.isdc.ro/wro"> <group

    name="wro"> <css>file:./src/main/wro/main.less</css> </group> </groups> src/main/wro/wro.properties postProcessors=less4j http://localhost:4000/decks/spring-boot-for-the-web-tier.html 10 of 43 10/09/14 08:15
  11. Dynamic Content - Templating Support Thymeleaf Groovy Template Language Freemarker

    Velocity JSP (not recommended) http://localhost:4000/decks/spring-boot-for-the-web-tier.html 11 of 43 10/09/14 08:15
  12. Dynamic Content - Template Conventions Templates live in src/main/resources/templates and

    are accessed via classpath:/templates/ Default Extensions are: *.html - Thymeleaf *.tpl - Groovy *.ftl - Freemarker *.vm - Velocity http://localhost:4000/decks/spring-boot-for-the-web-tier.html 12 of 43 10/09/14 08:15
  13. Dynamic Content - Template Customization User spring.xxx.prefix and spring.xxx.suffix eg.

    spring.freemarker.suffix=fm http://localhost:4000/decks/spring-boot-for-the-web-tier.html 13 of 43 10/09/14 08:15
  14. Demo - Templatinghttp://localhost:4000/decks/spring-boot-for-the-web-tier.html 14 of 43 10/09/14 08:15

  15. Dynamic Content - Custom Support Add a ViewResolver Optionally add

    a TemplateAvailabilityProvider http://localhost:4000/decks/spring-boot-for-the-web-tier.html 15 of 43 10/09/14 08:15
  16. public class GroovyTemplateAvailabilityProvider implements TemplateAvailabilityProvider { @Override public boolean isTemplateAvailable(String

    view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) { if (ClassUtils.isPresent("groovy.text.TemplateEngine", classLoader)) { String prefix = environment.getProperty("spring.groovy.template.prefix", GroovyTemplateProperties.DEFAULT_PREFIX); String suffix = environment.getProperty("spring.groovy.template.suffix", GroovyTemplateProperties.DEFAULT_SUFFIX); return resourceLoader.getResource(prefix + view + suffix).exists(); } return false; } } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 16 of 43 10/09/14 08:15
  17. Dynamic Content - Internationalization A MessageSource bean is added when

    src/main/resources /messages.properties exists Use messages_LOCALE.properties to add additional locales e.g. messages_FR.properties Choose a specific locale using the spring.mvc.locale property Choose a specific date format using the spring.mvc.date- format property http://localhost:4000/decks/spring-boot-for-the-web-tier.html 17 of 43 10/09/14 08:15
  18. Dynamic Content - HttpMessageConverter Add HttpMessageConverter beans and Spring Boot

    will try to do the right thing It tries to be intelligent about the order Add a HttpMessageConverters bean if you need more control http://localhost:4000/decks/spring-boot-for-the-web-tier.html 18 of 43 10/09/14 08:15
  19. Dynamic Content - Rest Use the @RestContoller annotation Use ResponseEntity

    builder methods with Spring Framework 4.1 ResponseEntity. accepted(). contentLength(3). contentType(MediaType.TEXT_PLAIN). body("Yo!"); http://localhost:4000/decks/spring-boot-for-the-web-tier.html 19 of 43 10/09/14 08:15
  20. Demo - HttpMessageConverter http://localhost:4000/decks/spring-boot-for-the-web-tier.html 20 of 43 10/09/14 08:15

  21. Dynamic Content - Hidden Gems You can get the RequestContext

    from RequestContextHolder anywhere The request has some useful things in it (from Spring), e.g. HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE All Converter, Formatter, GenericConverter beans are automatically added Use spring.mvc.message-codes-resolver-format to add a MessageCodesResolver prefix_error_code or postfix_error_code # prefix_error_code empty.customer.name=Customer name is required http://localhost:4000/decks/spring-boot-for-the-web-tier.html 21 of 43 10/09/14 08:15
  22. # postfix_error_code customer.name.empty=Customer name is required http://localhost:4000/decks/spring-boot-for-the-web-tier.html 22 of 43

    10/09/14 08:15
  23. Embedded Server When using WARs a ServletContainerInitializer creates the Spring

    ApplicationContext When running embedded the ApplicationContext creates the Server Expects a single EmbeddedServletContainerFactory bean Odd dance for WebApplicationContext.getServletContext() and ServletConfigAware http://localhost:4000/decks/spring-boot-for-the-web-tier.html 23 of 43 10/09/14 08:15
  24. Embedded Server - Initialization The following beans are used to

    configure the server: Servlet Filter ServletRequestListener ServletRequestAttributeListener HttpSessionAttributeListener HttpSessionListener ServletContextListener http://localhost:4000/decks/spring-boot-for-the-web-tier.html 24 of 43 10/09/14 08:15
  25. Embedded Server - Initialization For more control use ServletRegistrationBean FilterRegistrationBean

    ServletListenerRegistrationBean http://localhost:4000/decks/spring-boot-for-the-web-tier.html 25 of 43 10/09/14 08:15
  26. @Bean public ServletRegistrationBean myServlet() { ServletRegistrationBean bean = new ServletRegistrationBean(new

    MyServlet(), "/mine"); bean.setAsyncSupported(false); bean.setInitParameters(Collections.singletonMap("debug", "true")); return bean; } @Bean public FilterRegistrationBean myFilter() { return new FilterRegistrationBean(new MyFilter(), myServlet()); } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 26 of 43 10/09/14 08:15
  27. Embedded Server - Initialization By design the following are not

    called with embedded servers: javax.servlet.ServletContainerInitializer org.springframework.web.WebApplicationInitializer Use o.s.boot.context.embedded.ServletContextInitializer http://localhost:4000/decks/spring-boot-for-the-web-tier.html 27 of 43 10/09/14 08:15
  28. /** * Configure the given {@link ServletContext} with any servlets,

    filters, listeners * context-params and attributes necessary for initialization. * @param servletContext the {@code ServletContext} to initialize * @throws ServletException if any call against the given {@code ServletContext} * throws a {@code ServletException} */ void onStartup(ServletContext servletContext) throws ServletException; http://localhost:4000/decks/spring-boot-for-the-web-tier.html 28 of 43 10/09/14 08:15
  29. Embedded Server - Customization Use ServerProperties (e.g. server.port=8080) EmbeddedServletContainerCustomizer Customize

    common things (e.g. the port, error-pages, context-path) Tomcat Specific TomcatConnectorCustomizer TomcatContextCustomizer Jetty Specific JettyServerCustomizer http://localhost:4000/decks/spring-boot-for-the-web-tier.html 29 of 43 10/09/14 08:15
  30. Embedded Server - Customization If all else fails subclass EmbeddedServletContainerFactory

    Lots of protected methods to override TomcatEmbeddedServletContainerFactory JettyEmbeddedServletContainerFactory http://localhost:4000/decks/spring-boot-for-the-web-tier.html 30 of 43 10/09/14 08:15
  31. @Bean public TomcatEmbeddedServletContainerFactory tomcatFactory() { return new TomcatEmbeddedServletContainerFactory(7070) { @Override

    protected void customizeConnector(Connector connector) { // Something with the connector } @Override protected void configureSsl(AbstractHttp11JsseProtocol<?> protocol, Ssl ssl) { // Something with ssl } }; } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 31 of 43 10/09/14 08:15
  32. Embedded Server - Tomcat Behind HTTPD Running behind Apache HTTPD

    is a common option Especially useful with SSL termination Real IP and SSL information is passed in headers server.tomcat.protocol-header=x-forwarded-proto server.tomcat.remote-ip-header=x-forwarded-for http://localhost:4000/decks/spring-boot-for-the-web-tier.html 32 of 43 10/09/14 08:15
  33. Embedded Server - Tomcat Behind HTTPD <VirtualHost *:80> ServerName example.spring.io

    ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPass / http://${TOMCAT_IP}:8080/ ProxyPassReverse / http://${TOMCAT_IP}:8080/ </VirtualHost> <VirtualHost *:443> SSLEngine on SSLCertificateFile /etc/apache2/ssl/apache.crt SSLCertificateKeyFile /etc/apache2/ssl/apache.key ProxyPass / http://${TOMCAT_IP}:8080/ ProxyPassReverse / http://${TOMCAT_IP}:8080/ RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" </VirtualHost> http://localhost:4000/decks/spring-boot-for-the-web-tier.html 33 of 43 10/09/14 08:15
  34. Demo - Running Behind HTTPS http://localhost:4000/decks/spring-boot-for-the-web-tier.html 34 of 43 10/09/14

    08:15
  35. Other Stacks JAX-RS: Jersey 1.x, Jersey 2.x dsyer/spring-boot-jersey, CXF (allegedly

    works) Netty and NIO: Ratpack dsyer/spring-boot-ratpack Servlet 2.5 scratches/spring-boot-legacy Vaadin peholmst/vaadin4spring http://localhost:4000/decks/spring-boot-for-the-web-tier.html 35 of 43 10/09/14 08:15
  36. Jersey 1.x Easy to integrate with Spring Boot using Filter

    (or Servlet), e.g. http://localhost:4000/decks/spring-boot-for-the-web-tier.html 36 of 43 10/09/14 08:15
  37. @Configuration @EnableAutoConfiguration @Path("/") public class Application { @GET @Produces("text/plain") public

    String hello() { return "Hello World"; } @Bean public FilterRegistrationBean jersey() { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new ServletContainer()); bean.addInitParameter("com.sun.jersey.config.property.packages", "com.mycompany.myapp"); return bean; } } (N.B. with fat jar you need to explicitly list the nested jars that have JAX-RS resources in them.) http://localhost:4000/decks/spring-boot-for-the-web-tier.html 37 of 43 10/09/14 08:15
  38. Jersey 2.x Spring integration is provided out of the box,

    but a little bit tricky to use with Spring Boot, so some autoconfiguration is useful. Example app: @Configuration @Path("/") public class Application extends ResourceConfig { @GET public String message() { return "Hello"; } public Application() { register(Application.class); } } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 38 of 43 10/09/14 08:15
  39. Ratpack Originally inspired by Sinatra, but now pretty much diverged.

    Provides a nice programming model on top of Netty (potentially taking advantage of non-blocking IO). 2 approaches: Ratpack embeds Spring (and uses it as a Registry), supported natively in Ratpack 0.9.9 Spring embeds Ratpack (and uses it as an HTTP listener) = spring- boot-ratpack http://localhost:4000/decks/spring-boot-for-the-web-tier.html 39 of 43 10/09/14 08:15
  40. Spring Boot embedding Ratpack Trivial example (single Handler): @Bean public

    Handler handler() { return (context) -> { context.render("Hello World"); }; } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 40 of 43 10/09/14 08:15
  41. Spring Boot embedding Ratpack More interesting example (Action<Chain> registers Handlers):

    @Bean public Handler hello() { return (context) -> { context.render("Hello World"); }; } @Bean public Action<Chain> handlers() { return (chain) -> { chain.get(hello()); }; } http://localhost:4000/decks/spring-boot-for-the-web-tier.html 41 of 43 10/09/14 08:15
  42. Spring Boot Ratpack DSL A valid Ratpack Groovy application: ratpack

    { handlers { get { render "Hello World" } } } launched with Spring Boot: $ spring run app.groovy http://localhost:4000/decks/spring-boot-for-the-web-tier.html 42 of 43 10/09/14 08:15
  43. Questions? http://projects.spring.io/spring-boot/ https://github.com/SpringOne2GX-2014/spring-boot-for-the-web-tier http://localhost:4000/decks/spring-boot-for-the-web-tier.html 43 of 43 10/09/14 08:15