0
葉政達    Cheng Ta Yeh12年7月19日星期四
Integrate Spring MVC with      RequireJS & Backbone.js         & Spring Data JPA12年7月19日星期四
Who Am I        • 葉政達 Cheng-Ta Yeh        • Co-founder of Humus Technology (優沃科技)        • Founder of GOGOSamba (Android a...
Once upon a time...12年7月19日星期四
The Dream...12年7月19日星期四
Start lean, get bigger later12年7月19日星期四
What Am I Going To Talk About?          Building a Scalable Single-Page app              from front-end to backend.       ...
Outlines       • Front-end development       • Integrate Backbone with Spring MVC       • Diving into Spring Data JPA12年7月...
Front-end development12年7月19日星期四
Problems ...              • Few conventions and standards12年7月19日星期四
Problems ...        • jQuery is cool, it has plenty of selectors              and callbacks, but ...                      ...
Problems ...      • Between server-side and client-side, we          need efficient tools.12年7月19日星期四
Backbone.js12年7月19日星期四
Who Use Backbone.js                             Basecamp Mobile12年7月19日星期四
Backbone Components       Template                    Render      DOM                                 UI                  ...
Backbone View              • Owns a DOM element              • Talks to its model or collection              • Observe mod...
Backbone Model              • Data storage and business logic              • Changes on the attributes will fire           ...
My Real Case12年7月19日星期四
My Real Case12年7月19日星期四
Backbone Sample Code                                   ItemDetailView     ItemView               Use          window.ItemM...
Backbone Sample Code    ItemDetailView                 window.itemModel.save(                    {name: this.$(#input).val...
That’s It?12年7月19日星期四
How to build loose coupling          scalable applications?12年7月19日星期四
Apply “Module Pattern”,                      but ...                   var testModule = (function () {                   v...
Real life application              • Lots of Screens                • Lots of Modules                  •   Complex depende...
RequireJS12年7月19日星期四
Standards for Modules              • CommonJS Modules 1.1.1                • Targeted at server-side environments         ...
RequirJS AMD Loader                Other AMD loaders:                 • curl                 • lsjs                 • Dojo...
AMD APIs         • Facilitating module definition              • define (module_id?, dependencies?, factory);         • Hand...
Defining Backbone’s Classes into Modules              define(function () {                return new Backbone.Model.extend(...
Your App’s Entry Point        require.config({              // .....        })                                            ...
Set up your HTML Page     <!DOCTYPE html>     <html>         <head>             <title>jQuery+RequireJS Sample Page</title...
Using requireJS Optimizer              • Optimizing all the CSS and JS files in your                project                ...
Tips & Lessons Learned               • Prevent Memory Leaks                    •    All models, collections, views impleme...
Tips & Lessons Learned               • Package Pattern                   • File structure                     • src/ui/wid...
http://s.ctyeh.me/LGW3ug    Integrates Backbone.js with Spring MVC12年7月19日星期四
Backbone Model &              RESTful JSON Inteface        C       itemModel.save();      • POST               /items     ...
Define RESTful Interface                                  • Nouns: URI, addressed resources                                ...
Spring MVC as REST Server12年7月19日星期四
Receiving Values in the URL Path              • The RESTful way                   • @PathVariable in Controller methods   ...
Sending HTTP Response Codes            to Clients                                                                     Abst...
Rarely Need Custom Parsers• Automatically registers several converters.12年7月19日星期四
Controller Methods’   Parameters and Return Values                                     ween                               ...
Parameters and Return Values          • Domain Entity                                                              Control...
Parameters and Return Values              • DTO (Data Transfer Object)                                                    ...
Parameters and Return Values          • JSONObject                                                                   Contr...
Parameters and Return Values              • Domain Entity                • Pros: No extra effort for creation and maintena...
Unit Test for Spring MVC               Controller              • mockito - Mocking framework               • http://code.g...
Unit Test for Spring MVC               Controller          public class ItemControllerTest {                              ...
Diving into Spring Data JPA12年7月19日星期四
Layer Architecture                      Backbone.js       requireJS   HTML                      Spring MVC                ...
Between Spring MVC and                  Spring Data JPA              • Data conversion              • Design concept12年7月1...
Between Spring MVC and                  Spring Data JPA        • Data conversion              •   Using Factory Method in ...
Between Spring MVC and                  Spring Data JPA        • Data conversion              •    Using Factory Method in...
Between Spring MVC and                  Spring Data JPA        • Design concept              • Domain driven design in Dom...
Spring Data Overview              • Abstracts away basic data management concepts              • Support for RDB, NoSQL: G...
Let’s Begin With Plain JPA12年7月19日星期四
The Domain Entities   @Entity   public class Site {   	   @Id   	   @GeneratedValue(strategy = GenerationType.AUTO)   	   ...
The DAO         @Repository         public class TodoDAO {"           @PersistenceContext           private EntityManager ...
The Domain Service               @Service               @Transactional(readOnly = true)               class ItemListServic...
Refactoring to              Spring Data JPA12年7月19日星期四
The Repository (DAO)   public interface ItemRepository extends JpaRepository<Item, Long>   {         List<Item> findBySite...
The Service              @Service              @Transactional(readOnly = true)              class ItemListServiceImpl impl...
Strategy: CREATE              • Split your query methods by prefix and                property names.12年7月19日星期四
Strategy:         USE_DECLARED_QUERY              • @Query               public interface UserRepository extends JpaReposi...
Strategy:         USE_DECLARED_QUERY         • @Modify  @Modifying  @Query("update User u set u.firstname = ?1 where u.las...
Configurations in Spring 3.1       <!-- Activate Spring Data JPA repository support -->         	 <jpa:repositories base-pa...
Put It All Together                    Backbone.js                     requireJS                    Spring MVC            ...
The End & Thank You              http://about.me/ctyeh12年7月19日星期四
Upcoming SlideShare
Loading in...5
×

Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA

10,725

Published on

2012 Java Developer Day

Published in: Technology
1 Comment
16 Likes
Statistics
Notes
No Downloads
Views
Total Views
10,725
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
197
Comments
1
Likes
16
Embeds 0
No embeds

No notes for slide

Transcript of "Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA"

  1. 1. 葉政達 Cheng Ta Yeh12年7月19日星期四
  2. 2. Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA12年7月19日星期四
  3. 3. Who Am I • 葉政達 Cheng-Ta Yeh • Co-founder of Humus Technology (優沃科技) • Founder of GOGOSamba (Android app & Calorie Management Service) • Speaker of TWJUG 2012/5 • Speaker of Google Developer Day 2008 • Speaker of Java One Tokyo 2005 • 12 years Java related experiences12年7月19日星期四
  4. 4. Once upon a time...12年7月19日星期四
  5. 5. The Dream...12年7月19日星期四
  6. 6. Start lean, get bigger later12年7月19日星期四
  7. 7. What Am I Going To Talk About? Building a Scalable Single-Page app from front-end to backend. erview Ov My Les sons L earne d12年7月19日星期四
  8. 8. Outlines • Front-end development • Integrate Backbone with Spring MVC • Diving into Spring Data JPA12年7月19日星期四
  9. 9. Front-end development12年7月19日星期四
  10. 10. Problems ... • Few conventions and standards12年7月19日星期四
  11. 11. Problems ... • jQuery is cool, it has plenty of selectors and callbacks, but ... ily We have to tie d ata to the DOM heav , ca llbacks’ callbacks’... We have to deal with ts...... to manipulate DO M, animations, even http://mysistersjar.wordpress.com/2008/04/02/wanted-moving-boxes/12年7月19日星期四
  12. 12. Problems ... • Between server-side and client-side, we need efficient tools.12年7月19日星期四
  13. 13. Backbone.js12年7月19日星期四
  14. 14. Who Use Backbone.js Basecamp Mobile12年7月19日星期四
  15. 15. Backbone Components Template Render DOM UI Use DOM events Hash tag View Talks Model / Data Router Fragment routing Model events Collection sync Source Morning hashchange Dispatching routers History Event12年7月19日星期四
  16. 16. Backbone View • Owns a DOM element • Talks to its model or collection • Observe model events (change,...) • Handle user’s inputs (DOM events)12年7月19日星期四
  17. 17. Backbone Model • Data storage and business logic • Changes on the attributes will fire `change` event • Talks to server uses RESTful JSON12年7月19日星期四
  18. 18. My Real Case12年7月19日星期四
  19. 19. My Real Case12年7月19日星期四
  20. 20. Backbone Sample Code ItemDetailView ItemView Use window.ItemModel = Backbone.Model.extend(); ItemModel12年7月19日星期四
  21. 21. Backbone Sample Code ItemDetailView window.itemModel.save( {name: this.$(#input).val()} );change name change event window.ItemDetailView = Backbone.View.extend({ ItemView events: { "click #item_input": "doEdit" }, initialize: function() {window.ItemView = Backbone.View.extend({ this.model.bind(change, this.setTitle, this); initialize: function() { }, this.model.bind(change, this.setItemName, this); setTitle: function() { }, $(this.el).html(this.model.get(name)); setItemName: function() { }, $(this.el).html(this.model.get(name)); }, //....}); //.... }); window.ItemModel = Backbone.Model.extend(); ItemModel12年7月19日星期四
  22. 22. That’s It?12年7月19日星期四
  23. 23. How to build loose coupling scalable applications?12年7月19日星期四
  24. 24. Apply “Module Pattern”, but ... var testModule = (function () { var _counter = 0; //private variable function privateMethod(){ //..... } return { incrementCounter: function () { return __counter++; }, resetCounter: function () { console.log( "counter value prior to reset: " + _counter ); _counter = 0; } }; })();12年7月19日星期四
  25. 25. Real life application • Lots of Screens • Lots of Modules • Complex dependency12年7月19日星期四
  26. 26. RequireJS12年7月19日星期四
  27. 27. Standards for Modules • CommonJS Modules 1.1.1 • Targeted at server-side environments • AMD (Asynchronous Module Definition) • A format for writing modular javascript in the browser on JS m m Co12年7月19日星期四
  28. 28. RequirJS AMD Loader Other AMD loaders: • curl • lsjs • Dojo 1.7 and MooTools 2.0 each have their own12年7月19日星期四
  29. 29. AMD APIs • Facilitating module definition • define (module_id?, dependencies?, factory); • Handling dependency async loading • require (dependencies?, callback);12年7月19日星期四
  30. 30. Defining Backbone’s Classes into Modules define(function () {   return new Backbone.Model.extend({   // ...   }); }); ./models/itemModel.js define([../models/itemModel],function (itemModel) {   return new Backbone.View.extend({ model: itemModel; render: function(){ this.model.fetch(); //... }, // ...   }); }); ./views/itemView.js12年7月19日星期四
  31. 31. Your App’s Entry Point require.config({ // ..... }) ./views/itemView.js require([jquery,app], function ($,app) { app.initial(); }); Load Load ./main.js define([../views/itemView],function (itemView) {   return { 1. Set up requireJS configuration. 2. Start to run your app. Execute initial: function(){ // Do initialization..... // Render first App’s screen. itemView.render(); 1. As a top level container. }, 2. Initialize your app. 4. Render your first screen.   }; }); ./app.js12年7月19日星期四
  32. 32. Set up your HTML Page <!DOCTYPE html> <html> <head> <title>jQuery+RequireJS Sample Page</title> <script data-main="scripts/main" src="scripts/require-jquery.js"></script> </head> <body> <h1>Single Page Application Sample Page</h1> <div id=”app_body”> Your DOM elements will be inserted dynamically. </div> </body> </html>12年7月19日星期四
  33. 33. Using requireJS Optimizer • Optimizing all the CSS and JS files in your project > r.js -o app.build.js ({ appDir: "../", baseUrl: "scripts", dir: "../../appdirectory-build", modules: [ { name: "main" } ] }) app.build.js12年7月19日星期四
  34. 34. Tips & Lessons Learned • Prevent Memory Leaks • All models, collections, views implement destructors. • Create an abstraction layer for those destructors. Backbone.View.prototype.close = function () { console.log("Closing a View...”); if (this.beforeClose) { this.beforeClose(); } this.remove(); this.unbind(); };12年7月19日星期四
  35. 35. Tips & Lessons Learned • Package Pattern • File structure • src/ui/widgets.js < Just like Java’s package • src/ui/widgets/ooxx.js define([./widgets/selectors, ./widgets/slider, ./widgets/button],         function(selectors, slider, button) {     return {         ToolSelector: selectors.ToolSelector,         OptionSelector: selectors.OptionSelector,         Slider: slider.Slider,         Button: button.Button     }; }); src/ui/widgets.js12年7月19日星期四
  36. 36. http://s.ctyeh.me/LGW3ug Integrates Backbone.js with Spring MVC12年7月19日星期四
  37. 37. Backbone Model & RESTful JSON Inteface C itemModel.save(); • POST /items R itemModel.fetch(); • GET /items[/{id}] U itemModel.save(); • PUT /items/{id} D itemModel.clear(); • DELETE /items/{id} * POST or PUT base on the id value of Model. * Global ajax error handler is useful12年7月19日星期四
  38. 38. Define RESTful Interface • Nouns: URI, addressed resources • /sites • /sites/{id} • /sites/{id}/items • /sites/{id}/items/{todoId}. Find your resources BEFORE designing Backbone Models and The REST Triangle Spring MVC Controller methods.12年7月19日星期四
  39. 39. Spring MVC as REST Server12年7月19日星期四
  40. 40. Receiving Values in the URL Path • The RESTful way • @PathVariable in Controller methods @RequestMapping(value="/sites/{siteId}/item/{itemId}",method= {RequestMethod.PUT}) public @ResponseBody UIJentoItem updateModule(@PathVariable long siteId,@PathVariable Long itemId,@Valid @RequestBody UIJentoItem item) { UIJentoItem uiObject = new UIJentoItem(); //...... return uiObject; }12年7月19日星期四
  41. 41. Sending HTTP Response Codes to Clients AbstractController • @ResponseStatus extends • @ExecptionHandler. Controller Controller Controller A B C public class AbstractController { @ExceptionHandler(UserNotSigninException.class) @ResponseStatus(UNAUTHORIZED) // HTTP 401 public @ResponseBody UIMessage handleUserNotSigninException(UserNotSigninException e, HttpServletResponse response) { return UIMessage.fail("err.data.usernotsignin"); } @ExceptionHandler(DataNotFoundException.class) @ResponseStatus(NOT_FOUND) // HTTP 404 public @ResponseBody UIMessage handleDataNotFoundException(DataNotFoundException e, HttpServletResponse response) { return UIMessage.fail("err.data.notfound"); } @ExceptionHandler(Exception.class) @ResponseStatus(INTERNAL_SERVER_ERROR)// HTTP 505 public @ResponseBody UIMessage handleException(Exception e, HttpServletResponse response) { return UIMessage.fail("err.internal"); } }12年7月19日星期四
  42. 42. Rarely Need Custom Parsers• Automatically registers several converters.12年7月19日星期四
  43. 43. Controller Methods’ Parameters and Return Values ween s bet ing MVC he b ullet Spr T del & bon e Mo Back12年7月19日星期四
  44. 44. Parameters and Return Values • Domain Entity Controller @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.GET}) @ResponseStatus(OK) public @ResponseBody List<Item> getItems(@PathVariable long id) { //.... Out return itemList; } @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.POST}) @ResponseStatus(OK) public @ResponseBody String createItem( @PathVariable long id,@RequestBody Item item) { //.... In } Controller12年7月19日星期四
  45. 45. Parameters and Return Values • DTO (Data Transfer Object) Controller @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.GET}) @ResponseStatus(OK) public @ResponseBody List<DTOItem> getItems(@PathVariable long id) { //.... Out return itemList; } @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.POST}) @ResponseStatus(OK) public @ResponseBody String createItem( @PathVariable long id,@RequestBody DTOItem item) { //.... } In Controller12年7月19日星期四
  46. 46. Parameters and Return Values • JSONObject Controller import net.sf.json.JSONObject; @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.GET}) @ResponseStatus(OK) public @ResponseBody List<JSONObject> getItems(@PathVariable long id) { //.... Out return itemList; } @RequestMapping(value="/sites/{id}/items",method= {RequestMethod.POST}) @ResponseStatus(OK) public @ResponseBody String createItem( @PathVariable long id, @RequestBody JSONObject itemJSON) { //.... In } Controller12年7月19日星期四
  47. 47. Parameters and Return Values • Domain Entity • Pros: No extra effort for creation and maintenance & readable • Cons: Might waste extra bandwidth for transferring • DTO • Pros: readable • Cons: Extra efforts for maintenance, transferring from domain object to DTO. • JSONObject • Pros: No extra effort for creation and maintenance • Cons: Not readable, Unit testing is mandatory, transferring from domain entity to JSONObject!12年7月19日星期四
  48. 48. Unit Test for Spring MVC Controller • mockito - Mocking framework • http://code.google.com/p/mockito/ • Spring MVC Test Support • https://github.com/SpringSource/spring-test-mvc12年7月19日星期四
  49. 49. Unit Test for Spring MVC Controller public class ItemControllerTest { ItemController private static MockMvc mockMvc; use use private UserSerivce userService; private ItemSerivce itemService; ItemService UserService @Before public void setUp() { userService = mock(UserService.class); itemService = mock(ItemService.class); Create a mock service Setup mockMVC for target Controller mockMvc = standaloneSetup(new ItemController()).build(); // userService.getCurrentUser() will be called in ItemController for URI "/sites/{id}/items" when(userService.getCurrentUser()).thenReturn(new User()); Item item = new Item(); item.setName("This is item name"); when(itemService.getItem(any(Long.class))).thenReturn(item); } tell mocks when some calls happened return something @Test public void getItemsBySiteId() throws Exception { mockMvc.perform(get("/sites/1/items")) .andExpect(status().isOk()) Your URI .andExpect(content().type("application/json;charset=UTF-8")) .andExpect(jsonPath("$.[0].id").value(1)) .andExpect(jsonPath("$.[0].itemName").value("This is item name")) ;12年7月19日星期四
  50. 50. Diving into Spring Data JPA12年7月19日星期四
  51. 51. Layer Architecture Backbone.js requireJS HTML Spring MVC Domain Model Spring Data JPA12年7月19日星期四
  52. 52. Between Spring MVC and Spring Data JPA • Data conversion • Design concept12年7月19日星期四
  53. 53. Between Spring MVC and Spring Data JPA • Data conversion • Using Factory Method in Domain entity or separate Factory classes. DTO JSONObject Spring MVC Domain Object Spring Data JPA12年7月19日星期四
  54. 54. Between Spring MVC and Spring Data JPA • Data conversion • Using Factory Method in Domain entity or separate Factory classes. @Entity public class Item implements Serializable { private String name; //..... public JSONObject toJSON(){ DTO JSONObject JSONObject object = new JSONObject(); //Converting Item to JSONObject. object.put("name", this.name); return object; } Domain Object public static Item fromJSON(JSONObject json){ //Converting JSONObject to Item. return item; } }12年7月19日星期四
  55. 55. Between Spring MVC and Spring Data JPA • Design concept • Domain driven design in Domain Layer • Entity • Service • Value Object • Aggregate • Repository Spring Data borrows this concept.12年7月19日星期四
  56. 56. Spring Data Overview • Abstracts away basic data management concepts • Support for RDB, NoSQL: Graph, Key-Value and Map-Reduce types. • Current implementations • JPA/JDBC • Hadoop • GemFire • REST • Redis/Riak • MongoDB • Neo4j • Blob (AWS S3, Rackspace, Azure,...) • Plan for HBase and Cassandra12年7月19日星期四
  57. 57. Let’s Begin With Plain JPA12年7月19日星期四
  58. 58. The Domain Entities @Entity public class Site { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; // … methods omitted } @Entity public class Item {   @Id @GeneratedValue(strategy = GenerationType.AUTO) 1 private Long id; Site * Item @ManyToOne private Site site;      // … methods omitted }12年7月19日星期四
  59. 59. The DAO @Repository public class TodoDAO {"   @PersistenceContext   private EntityManager em;     @Override   @Transactional   public Item save(Item item) {       if (item.getId() == null) {       em.persist(item);       return item;     } else {       return em.merge(item);     }   }     @Override   public List<Item> findBySiteId(Long siteId) {       TypedQuery query = em.createQuery("select i from Item a where i.site.id = ?1", Item.class);     query.setParameter(1, siteId);       return query.getResultList();   } }12年7月19日星期四
  60. 60. The Domain Service @Service @Transactional(readOnly = true) class ItemListServiceImpl implements ItemListService {     @Autowired   private ItemDAO itemDAO;     @Override   @Transactional   public Item save(Item item) {       return itemDAO.save(item);   }   @Override   public List<Item> findItems(Long siteId) {       return itemDAO.findBySiteId(siteId);   }   }12年7月19日星期四
  61. 61. Refactoring to Spring Data JPA12年7月19日星期四
  62. 62. The Repository (DAO) public interface ItemRepository extends JpaRepository<Item, Long> {     List<Item> findBySite(Site site); }12年7月19日星期四
  63. 63. The Service @Service @Transactional(readOnly = true) class ItemListServiceImpl implements ItemListService {     @Autowired   private ItemRepository repository;     @Override   @Transactional   public Item save(Item item) {       return repository.save(item);   }   @Override   public List<Item> findItems(Site site) {       return repository.findBySite(site);   }   }12年7月19日星期四
  64. 64. Strategy: CREATE • Split your query methods by prefix and property names.12年7月19日星期四
  65. 65. Strategy: USE_DECLARED_QUERY • @Query public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress); } From Spring Data JPA 1.1.0, native SQL is allowed to be executed. Just set nativeQuery flag to true. But, not support pagination and dynamic sort12年7月19日星期四
  66. 66. Strategy: USE_DECLARED_QUERY • @Modify @Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname); @Modifying @Query("update User u set u.firstname = :firstName where u.lastname = :lastName") int setFixedFirstnameFor(@Param("firstName") String firstname, @Param("lastName") String lastname);12年7月19日星期四
  67. 67. Configurations in Spring 3.1 <!-- Activate Spring Data JPA repository support --> <jpa:repositories base-package="com.humus.domain.repo" /> <!-- Declare a JPA entityManagerFactory --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> </props> </property> <property name="packagesToScan"> <list> <value>com.humus.domain.entity</value> </list> </property> </bean> No persistence.xml any more~12年7月19日星期四
  68. 68. Put It All Together Backbone.js requireJS Spring MVC Spring Data JPA12年7月19日星期四
  69. 69. The End & Thank You http://about.me/ctyeh12年7月19日星期四
  1. ¿Le ha llamado la atención una diapositiva en particular?

    Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

×