Your SlideShare is downloading. ×
Spring Mvc Rest
Upcoming SlideShare
Loading in...5

Thanks for flagging this SlideShare!

Oops! An error has occurred.


Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Spring Mvc Rest


Published on

My Spring MVC and REST talk, updated for NFJS Reston, VA.

My Spring MVC and REST talk, updated for NFJS Reston, VA.

  • Be the first to comment

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

No notes for slide


  • 1. Building RESTful applications with Spring MVC Craig Walls
  • 2. Who Am I? Java, Spring, and OSGi fanatic Principal Consultant with Improving Author XDoclet in Action (Manning) Spring in Action (Manning) Modular Java (Pragmatic Bookshelf) E-mail: Blog: Twitter: @habuma Slides:
  • 3. What REST is NOT!!! Web Services with URLs E-mail: Blog: Twitter: habuma
  • 4. It’s about Resources Things, not actions Requests, not demands Resources, not services Transfer of state, not RPC E-mail: Blog: Twitter: habuma
  • 5. The Pillars of REST Resources URIs/URLs HTTP Methods Representations E-mail: Blog: Twitter: habuma
  • 6. The Pillars of REST Resources Produced as model data in Spring MVC Controllers URIs/URLs Supported in handler methods by @PathParam HTTP Methods @RequestMapping, HiddenHttpMethodFilter, <form:form> Representations Rendered by view resolvers HTML, XML, JSON, RSS, Atom, PDF, Excel, etc. Negotiated by ContentNegotiatingViewResolver E-mail: Blog: Twitter: habuma
  • 7. Identifying Resources E-mail: Blog: Twitter: habuma
  • 8. Demanding URLs Direct Imperative Resource identifier Command is pushed into a query parameter Very service-y Not very cacheable or search engine friendly E-mail: Blog: Twitter: habuma
  • 9. Resourceful URLs The focus is on the product, We’re requesting not the action a product’s info Cacheable This URL also identifies a product (within a context) E-mail: Blog: Twitter: habuma
  • 10. Spring MVC overview E-mail: Blog: Twitter: habuma
  • 11. DispatcherServlet In /WEB-INF/web.xml <servlet> <servlet-name>spitter</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spitter</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping> E-mail: Blog: Twitter: habuma
  • 12. ContextLoaderListener In /WEB-INF/web.xml <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spitter-security.xml classpath:service-context.xml classpath:persistence-context.xml classpath:dataSource-context.xml classpath:setup-context.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> E-mail: Blog: Twitter: habuma
  • 13. UrlRewriteFilter In /WEB-INF/web.xml <filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class> org.tuckey.web.filters.urlrewrite.UrlRewriteFilter </filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> In /WEB-INF/urlrewrite.xml <urlrewrite default-match-type="wildcard"> <rule> 1234 /pr oduct/ <from>/resources/**</from> <to>/resources/$1</to> /1234 </rule> uct /ap p/prod <rule> <from>/**</from> <to>/app/$1</to> </rule> <outbound-rule> <from>/app/**</from> <to>/$1</to> </outbound-rule> </urlrewrite> E-mail: Blog: Twitter: habuma
  • 14. Essential Configuration Scan for controller (and other) components <context:component-scan base-package="com.habuma.sample.mvc" /> Resolve JSP views <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> Handle annotation-driven request mappings <mvc:annotation-driven/> E-mail: Blog: Twitter: habuma
  • 15. Use-case-based controllers VERB!!! @Controller public class DisplayProductController { @RequestMapping(value="/displayProduct.htm") public String showProductBySku(String sku, Map<String,Object> model) { Product product = // ... lookup product ... model.put("product", product); return "product"; } // ... } http://host/myApp/displayProduct.htm?sku=1234 E-mail: Blog: Twitter: habuma
  • 16. Resource-oriented controller Noun @Controller Verb @RequestMapping("/product") public class ProductController { @RequestMapping(value="/{sku}", method=GET) public String showProductBySku( @PathVariable String sku, Map<String,Object> model) { Product product = // ... lookup product ... model.put("product", product); return "product"; } } http://host/myApp/product/1234 E-mail: Blog: Twitter: habuma
  • 17. HTTP Methods GET, DELETE, PUT Idempotent Transfers state of resource POST Not Idempotent Sends data (not nec. state) E-mail: Blog: Twitter: habuma
  • 18. PUT vs. POST PUT Used to transfer state to server Useful when the resource’s URL is known POST Used to send data to server Useful when the resource’s URL is unknown or when transferring partial state E-mail: Blog: Twitter: habuma
  • 19. Handling DELETE @Controller @RequestMapping("/product") public class ProductController { ... @RequestMapping(value="/{sku}", method=DELETE) public String deleteProduct( @PathVariable String sku) { // ... delete product ... return "redirect:home"; } } http://host/myApp/product/1234 E-mail: Blog: Twitter: habuma
  • 20. Handling PUT @Controller @RequestMapping("/product") public class ProductController { ... @RequestMapping(value="/{sku}", method=PUT) public String saveProduct( @PathVariable String sku, Product product) { // ... save product ... return "redirect:/product/" + sku; } } http://host/myApp/product/1234 E-mail: Blog: Twitter: habuma
  • 21. Handling POST @Controller @RequestMapping("/product") public class ProductController { ... @RequestMapping(method=POST) public String setPrice(String sku, double price) { // ... update price ... return "redirect:/product/" + sku; } } http://host/myApp/product FORM DATA: sku=1234 price=5.99 E-mail: Blog: Twitter: habuma
  • 22. Using PUT/DELETE in forms Most browsers only support GET and POST Spring’s <form:form> supports all <form:form method="DELETE" action="http://host/myApp/product/1234"> ... </form:form> Hidden method field <form method="POST" action="http://host/myApp/product/1234"> <input type="hidden" name="_method" value="DELETE"> ... </form> E-mail: Blog: Twitter: habuma
  • 23. HiddenHttpMethodFilter <filter> <filter-name>httpMethodFilter</filter-name> <filter-class> org.springframework.web.filter.HiddenHttpMethodFilter </filter-class> </filter> <filter-mapping> <filter-name>httpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> HiddenHttpMethodFilter POST DELETE _method=DELETE E-mail: Blog: Twitter: habuma
  • 24. Data representation PDF RSS/Atom Spring MVC Views JSON Excel E-mail: Blog: Twitter: habuma
  • 25. Negotiating Content Request Content Negotiating View Resolver E-mail: Blog: Twitter: habuma
  • 26. Choosing a view 1. Determine the media type URL path extension/mediaTypes format parameter URL path extension/JAF HTTP Accept header 2. Find a view resolver that serves that media type E-mail: Blog: Twitter: habuma
  • 27. ContentNegotiatingViewResolver <bean class="org.springframework.web.servlet.view. ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="htm" value="text/html"/> <entry key="json" value="application/json"/> </map> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json. MappingJacksonJsonView" /> </list> </property> </bean> <bean id="spittles" class="com.habuma.spitter.mvc.view.SpittlesAtomView"/> E-mail: Blog: Twitter: habuma
  • 28. Spring’s new views MappingJacksonJsonView MarshallingView AbstractAtomFeedView AbstractRssFeedView E-mail: Blog: Twitter: habuma
  • 29. XML Marshalling View <bean id="oxmMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller" /> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml. MarshallingHttpMessageConverter"> <property name="marshaller" ref="oxmMarshaller" /> <property name="unmarshaller" ref="oxmMarshaller" /> </bean> E-mail: Blog: Twitter: habuma
  • 30. Sample RSS View public class SpittlesRssView extends AbstractRssFeedView { @Override protected List<Item> buildFeedItems( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { @SuppressWarnings("unchecked") List<Spittle> spittles = (List<Spittle>) model.get("spittles"); List<Item> items = new ArrayList<Item>(); for (Spittle spittle : spittles) { Item item = new Item(); item.setTitle(spittle.getText()); item.setPubDate(spittle.getWhen()); item.setAuthor(spittle.getSpitter().getFullName()); items.add(item); } return items; } } E-mail: Blog: Twitter: habuma
  • 31. Sample Atom View public class SpittlesAtomView extends AbstractAtomFeedView { @Override protected List<Entry> buildFeedEntries( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { @SuppressWarnings("unchecked") List<Spittle> spittles = (List<Spittle>) model.get("spittles"); List<Entry> entries = new ArrayList<Entry>(); for (Spittle spittle : spittles) { Entry entry = new Entry(); entry.setTitle(spittle.getText()); entry.setCreated(spittle.getWhen()); entry.setAuthors(asList(spittle.getSpitter().getFullName())); entries.add(entry); } return entries; } } E-mail: Blog: Twitter: habuma
  • 32. ETags Returns HTTP 304 if content is unmodified if-none-match (MD5 Hash comparison) Saves bandwidth <filter> <filter-name>etagFilter</filter-name> <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class> </filter> <filter-mapping> <filter-name>etagFilter</filter-name> <servlet-name>spitter</servlet-name> </filter-mapping> E-mail: Blog: Twitter: habuma
  • 33. RestTemplate In Spring context: (or yes, it could just be new’d up in Java) <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> In Java: RestTemplate rest = (RestTemplate) context.getBean("restTemplate"); Map result = rest.getForObject( "http://localhost:8080/mugbooks/book/1.json", Map.class); E-mail: Blog: Twitter: habuma
  • 34. Summary • Spring provides a flexible web MVC framework • Full support for REST as of Spring 3.0 • Can consume REST services via a template E-mail: Blog: Twitter: habuma
  • 35. Thank You Don’t forget the evals!