Spring Framework 4.0 Web Applications

  • View
    2.602

  • Download
    6

  • Category

    Software

Preview:

DESCRIPTION

Speaker: Rossen Stoyanchev Web / JavaScript Track 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.

Citation preview

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

Spring 4 Web ApplicationsRossen Stoyanchev

@rstoya05

About me

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

• Focus on web applications and Spring MVC

• Spring 4 WebSocket messaging lead

Spring MVC 4.1 update

in context of other recent releases

and related projects

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

@Controller

• The central component stereotype in Spring MVC

• Contains @RequestMapping methods

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

@RestController

• Another component stereotype

• Meta-annotated with @Controller + @ResponseBody

• @ResponseBody “inherited” on method level

• No need to add it, assumed by default

@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)

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;

...

}

JSONP Support

Simply declare as Spring-managed bean:

@ControllerAdviceprivate static class JsonpAdviceextends AbstractJsonpResponseBodyAdvice {

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

} }

Name of JSONP query param(s)

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())); // ... }

}

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

@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”

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

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

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

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) {}

}

@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”)

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) {}

}

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>

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)

“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”

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

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') } }

Groovy Markup Templating in Spring MVC

• Spring MVC integration

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

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(); } }

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>

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); } }

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" />

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

WebSocket Messaging

@Controller

STOMP

WebSocket API

SockJS

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

spring-messaging

spring-websocket

Example STOMP Message

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

Hello world!

COMMANDheader1:value1header2:value2

Body

STOMPFrame

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); }

}

@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) { // ... }

}

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

• 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

@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

• 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

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

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

Q & A

Thank you!

Recommended