Spring 4 Web App

43
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Spring 4 Web Applications Rossen Stoyanchev @rstoya05

description

The Web and Spring MVC continue to be one of the most active areas of the Spring Framework with each new release adding plenty of features and refinements requested by the community. Furthermore version 4 added a significant choice for web applications to build WebSocket-style architectures. This talk provides an overview of the areas in which the framework has evolved along with highlights of specific noteworthy features from the most recent releases.

Transcript of Spring 4 Web App

Page 1: Spring 4 Web App

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Spring 4 Web ApplicationsRossen Stoyanchev

@rstoya05

Page 2: Spring 4 Web App

About me

• Spring Framework committer• 598 commits / 143,459 ++ / 95,254 --

• Focus on web applications and Spring MVC

• Spring 4 WebSocket messaging lead

Page 3: Spring 4 Web App

Spring MVC 4.1 update

in context of other recent releases

and related projects

Page 4: Spring 4 Web App

Spring MVC Annotations

• @MVC very popular and evolving through feedback

• Started in 2.5 + REST in 3.0

• Many refinements in 3.1 and 3.2

• WebSocket messaging in 4.0

• Continues to evolve in 4.x

Page 5: Spring 4 Web App

@Controller

• The central component stereotype in Spring MVC

• Contains @RequestMapping methods

• Supporting methods:@ModelAttribute/@InitBinder/@ExceptionHandler

Page 6: Spring 4 Web App

@RestController

• Another component stereotype

• Meta-annotated with @Controller + @ResponseBody

• @ResponseBody “inherited” on method level

• No need to add it, assumed by default

Page 7: Spring 4 Web App

@ControllerAdvice

• Yet another component stereotype

• “Global” supporting methods:@ExceptionHandler, @ModelAttribute, @InitBinder

• Auto-detected, just declare it as a bean

• Fine-grained control @ControllerAdvice(basePackageClasses=MyController.class)

Page 10: Spring 4 Web App

Jackson @JsonView Support

@RestControllerclass UserController {

@RequestMapping("/user")@JsonView(PublicView.class)public User getUser() { return new User("eric", "7!#H2");}

}

interface PublicView {};

class User {

@PublicViewprivate String username;

private String password;

...

}

Page 11: Spring 4 Web App

JSONP Support

Simply declare as Spring-managed bean:

@ControllerAdviceprivate static class JsonpAdviceextends AbstractJsonpResponseBodyAdvice {

public JsonpAdvice() {super("callback");

} }

Name of JSONP query param(s)

Page 12: Spring 4 Web App

java.util.Optional method argument (JDK 1.8)

@RestControllerpublic class TestController { @RequestMapping("/test") public void handle(@RequestParam Optional<LocalDate> date) { StringBuilder sb = new StringBuilder("Date: "); date.ifPresent(s -> sb.append(s.toString())); // ... }

}

Page 13: Spring 4 Web App

ListenableFuture return type

• ListenableFuture• together with AsyncRestTemplate

• Supported on @RequestMapping methods in 4.1• return instead of DeferredResult

• Useful in some cases• business service returns ListenableFuture

Page 14: Spring 4 Web App

@ModelAttribute Method Invocation Order

• Invocation respects inter-dependencies in 4.1

@ModelAttribute("foo")public Object getFoo() {

}

@ModelAttribute("bar")public Object getBar(@ModelAttribute("foo") Object foo) {

}

consumes“foo”

produces“foo”

Page 15: Spring 4 Web App

HttpMessageConverter Additions

• Gson• lighter footprint (vs Jackson); used in Spring Android

• Google Protocol Buffers

• effective inter-service communication data protocol

• Jackson / XML• just add jackson-dataformat-xml to classpath

Page 16: Spring 4 Web App

ResponseEntity builder

public ResponseEntity<String> handle() { String body = "Hello World"; HttpHeaders headers = new HttpHeaders() headers.setLocation(location); return new ResponseEntity<String>(body, headers, HttpStatus.CREATED);}

public ResponseEntity<String> handle() { URI location = ...; return ResponseEntity.created(location).body("Hello World");}

BEFORE

AFTER

Page 17: Spring 4 Web App

RequestEntity builder

HttpHeaders headers = new HttpHeaders();headers.setAccept(MediaType.APPLICATION_JSON);HttpEntity httpEntity = new HttpEntity("Hello World", headers);restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);

restTemplate.exchange(

RequestEntity.post(uri).accept(MediaType.APPLICATION_JSON).body("Hello World"), String.class);

BEFORE

AFTER

Page 18: Spring 4 Web App

Link to @RequestMapping / fromMethodCall

// static import MvcUriComponentsBuilder.*

fromMethodCall(on(MyController.class).getAddress("US")).buildAndExpand(1).toUri();

@RequestMapping("/people/{id}/addresses")public class MyController {

@RequestMapping("/{country}")public HttpEntity getAddress(@PathVariable String country) {}

}

Page 19: Spring 4 Web App

@RequestMapping names

• HandlerMethodMappingNamingStrategy

• A default name assigned to all mappings• e.g. class: MyController, method: getAddress• mapping name: “MC#getAddress”

• Mapping names logged on startup at TRACE

• Override default• @RequestMapping(name=”custom-name”)

Page 20: Spring 4 Web App

Link to @RequestMapping / fromMappingName

// static import MvcUriComponentsBuilder.*

fromMappingName("MC#getAddress").arg(0, "US").buildAndExpand(1);

@RequestMapping("/people/{id}/addresses")public class MyController {

@RequestMapping("/{country}")public HttpEntity getAddress(@PathVariable String country) {}

}

Page 21: Spring 4 Web App

Link to @RequestMapping / in views

• mvcUrl function in Spring JSP tag library• shortcut for MvcUriComponentsBuilder.fromMappingName

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>

<a href="${s:mvcUrl('MC#getAddress) .arg(0, 'US').buildAndExpand(1)}">...</a>

Page 22: Spring 4 Web App

Static Resource Handling

• Major Spring Framework 4.1 feature

• Evolve existing ResourceHttpRequestHandler mechanism

• ResourceResolver and ResourceTransformer chains• arbitrary resolution (version in URL path)

• ResourceUrlProvider • prepare “public” resource URL (e.g. insert version)

Page 23: Spring 4 Web App

“Fingerprinting” URLs (content-based version)

boolean useResourceCache = !this.environment.acceptsProfiles("dev"); VersionResourceResolver resolver = new VersionResourceResolver();resolver.addContentVersionStrategy("/**"); registry.addResourceHandler("/**").addResourceLocations(locations) .resourceChain(useResourceCache).addResolver(resolver);

Example URL:“/css/font-awesome.min-7fbe76cdac.css”

Page 24: Spring 4 Web App

Resource Handling: Comprehensive Strategy

• Much more to discuss• optimization of resources (minify, concatenate)• effective HTTP caching• runtime vs build-time approaches

• Separate talk tomorrow (Wednesday) 8:30 AM

Resource Handling in Spring MVC 4.1Brian Clozel, Rossen Stoyanchev

Page 25: Spring 4 Web App

Groovy Markup Templating

• MarkupTemplateEngine in Groovy 2.3 (XML, XHTML, HTML5)

• DRY markup, Groovy DSL (also see blog post)

yieldUnescaped '<!DOCTYPE html>' html(lang:'en') { head { meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"') title('My page') } body { p('This is an example of HTML contents') } }

Page 26: Spring 4 Web App

Groovy Markup Templating in Spring MVC

• Spring MVC integration

• GroovyMarkupView/ViewResolver/Configurer • similar to FreeMarker and Velocity

Page 27: Spring 4 Web App

New in MVC Java Config: view resolvers

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewResolverRegistry registry) { registry.enableContentNegotiation(new MappingJackson2JsonView()); registry.jsp(); } }

Page 28: Spring 4 Web App

New in MVC Namespace: view resolvers

<mvc:view-resolvers>

<mvc:content-negotiation>

<mvc:default-views>

<bean class="org.springframework.web..MappingJackson2JsonView"/>

</mvc:default-views>

</mvc:content-negotiation>

<mvc:jsp />

</mvc:view-resolvers>

Page 29: Spring 4 Web App

MVC Java Config: enhanced view controllers

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addRedirectViewController("/old/path", "/new/path"); registry.addStatusController("/path", HttpStatus.NOT_FOUND); } }

Page 30: Spring 4 Web App

MVC Namespace: enhanced view controllers

1234

<mvc:redirect-view-controller path="/old" redirect-url="/new" context-relative="false" status-code="308" keep-query-params="true" /> <mvc:status-controller path="/bad" status-code="404" />

Page 31: Spring 4 Web App

WebSocket Support

• Introduced in 4.0

• Foundational WebSocket API

• Transparent SockJS layer• fall back on HTTP streaming or long polling• wide range of browser versions

• Higher-level STOMP messaging• enables @Controller-style programming model

Page 32: Spring 4 Web App

WebSocket Messaging

@Controller

STOMP

WebSocket API

SockJS

websocket / xhr-streaming / eventsource / xhr / ...

spring-messaging

spring-websocket

Page 33: Spring 4 Web App

Example STOMP Message

SENDdestination:/topic/greetingscontent-type:text/plain

Hello world!

COMMANDheader1:value1header2:value2

Body

STOMPFrame

Page 34: Spring 4 Web App

HTTP Requests with Push Notifications

@Controllerpublic class AccountController { @Autowired private SimpMessagingTemplate template; @RequestMapping(value="/accounts", method=RequestMethod.POST) public void save(@Valid Account account) { // ... // notify connected users this.template.convertAndSend("/topic/accounts", account); }

}

Page 35: Spring 4 Web App

@Controller HTTP and WebSocket Processing

@Controllerpublic class PortfolioController { @MessageMapping("/trade") public void executeTrade(Trade trade) { // ... } @RequestMapping(value="/trades/{id}", method=RequestMethod.GET) public Trade getTrade(Integer id) { // ... }

}

Page 36: Spring 4 Web App

Much More on WebSockets

• WebSocket messaging-style, event-driven architecture• very different from REST/HTTP

• There is a lot to consider and learn

• Separate talk today (Tuesday) at 12:45 am

Deep Dive into Spring WebSocketsSergi Almar

Page 37: Spring 4 Web App

• A tool for getting started quickly

• One-stop shop for Spring application development

• Builds on many spring projects• does all the hard work so you don’t have to

• Focused on the 80% common case• more opinionated and more instantly useful• yet remains flexible

Spring Boot

Page 38: Spring 4 Web App

@RestController

@EnableAutoConfiguration

public class Example {

public static void main(String[] args) throws Exception {

SpringApplication.run(Example.class, args);

}

@RequestMapping("/")

public String home() {

return "Hello World!";

}

}

Spring Boot: Up and Running in Minutes!

$ mvn spring-boot:run

Page 39: Spring 4 Web App

• The @MVC programming model you know

• Optimized to be production ready• auto-config, conventions• embedded servlet container, metrics, logging

• Separate talk today (Tuesday) at 2:30 pm

Spring Boot for the Web TierPhil Webb, Dave Syer

Spring Boot for Web Applications

Page 40: Spring 4 Web App

Spring MVC Test Updates

• Assert JSON responses with JSONAssert library• similar to what XMLUnit does for XML

• AsyncRestTemplate client-side support

• MockMvcBuilder "recipes" via MockMvcConfigurer • added to simplify Spring Security setup

Page 41: Spring 4 Web App

HtmlUnit Extension for Spring MVC Test

• Separate Github project spring-test-htmlunit

• Use HtmlUnit, WebDriver, Geb + your Spring MVC Test setup

• See talk tomorrow (Wednesday) at 4:30 pm

The Quest for the Holy Integration TestKen Krueger, Rob Winch

Page 42: Spring 4 Web App

Q & A

Page 43: Spring 4 Web App

Thank you!