SlideShare une entreprise Scribd logo
1  sur  69
Télécharger pour lire hors ligne
葉政達
    Cheng Ta Yeh


12年7月19日星期四
Integrate Spring MVC with
      RequireJS & Backbone.js
         & Spring Data JPA

12年7月19日星期四
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 experiences


12年7月19日星期四
Once upon a time...




12年7月19日星期四
The Dream...




12年7月19日星期四
Start lean, get bigger later
12年7月19日星期四
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 d
12年7月19日星期四
Outlines


       • Front-end development
       • Integrate Backbone with Spring MVC
       • Diving into Spring Data JPA



12年7月19日星期四
Front-end development
12年7月19日星期四
Problems ...
              • Few conventions and standards




12年7月19日星期四
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日星期四
Problems ...
      • Between server-side and client-side, we
          need efficient tools.




12年7月19日星期四
Backbone.js
12年7月19日星期四
Who Use Backbone.js
                             Basecamp Mobile




12年7月19日星期四
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                      Event




12年7月19日星期四
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日星期四
Backbone Model

              • Data storage and business logic
              • Changes on the attributes will fire
                `change` event

              • Talks to server uses RESTful JSON



12年7月19日星期四
My Real Case

12年7月19日星期四
My Real Case

12年7月19日星期四
Backbone Sample Code
                                   ItemDetailView




     ItemView




               Use
          window.ItemModel =
        Backbone.Model.extend();

          ItemModel




12年7月19日星期四
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();

                           ItemModel



12年7月19日星期四
That’s It?




12年7月19日星期四
How to build loose coupling
          scalable applications?




12年7月19日星期四
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日星期四
Real life application
              • Lots of Screens
                • Lots of Modules
                  •   Complex dependency




12年7月19日星期四
RequireJS
12年7月19日星期四
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
                                 Co

12年7月19日星期四
RequirJS AMD Loader




                Other AMD loaders:
                 • curl
                 • lsjs
                 • Dojo 1.7 and MooTools 2.0 each have their own


12年7月19日星期四
AMD APIs

         • Facilitating module definition
              • define (module_id?, dependencies?, factory);

         • Handling dependency async loading
              • require (dependencies?, callback);



12年7月19日星期四
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.js


12年7月19日星期四
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.js
12年7月19日星期四
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日星期四
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.js



12年7月19日星期四
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日星期四
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.js

12年7月19日星期四
http://s.ctyeh.me/LGW3ug




    Integrates Backbone.js with Spring MVC
12年7月19日星期四
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 useful
12年7月19日星期四
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日星期四
Spring MVC as REST Server




12年7月19日星期四
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日星期四
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日星期四
Rarely Need Custom Parsers



• Automatically registers several converters.




12年7月19日星期四
Controller Methods’
   Parameters and Return Values


                                     ween
                                s bet ing MVC
                     he b ullet     Spr
                   T         del &
                   bon e Mo
              Back



12年7月19日星期四
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
                                         }
                                                                                                 Controller


12年7月19日星期四
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
                                                                                                   Controller


12年7月19日星期四
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
                                           }
                                                                                                    Controller

12年7月19日星期四
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日星期四
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-mvc




12年7月19日星期四
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日星期四
Diving into Spring Data JPA
12年7月19日星期四
Layer Architecture
                      Backbone.js       requireJS   HTML




                      Spring MVC




                      Domain Model


                      Spring Data JPA




12年7月19日星期四
Between Spring MVC and
                  Spring Data JPA

              • Data conversion
              • Design concept




12年7月19日星期四
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 JPA



12年7月19日星期四
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日星期四
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日星期四
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 Cassandra

12年7月19日星期四
Let’s Begin With Plain JPA




12年7月19日星期四
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日星期四
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日星期四
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日星期四
Refactoring to
              Spring Data JPA



12年7月19日星期四
The Repository (DAO)

   public interface ItemRepository extends JpaRepository<Item, Long>
   {
    
     List<Item> findBySite(Site site);
   }




12年7月19日星期四
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日星期四
Strategy: CREATE
              • Split your query methods by prefix and
                property names.




12年7月19日星期四
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 sort




12年7月19日星期四
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日星期四
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日星期四
Put It All Together

                    Backbone.js

                     requireJS


                    Spring MVC



                   Spring Data JPA

12年7月19日星期四
The End & Thank You


              http://about.me/ctyeh

12年7月19日星期四

Contenu connexe

En vedette

Share My Lesson: The Slope of a Line
Share My Lesson: The Slope of a LineShare My Lesson: The Slope of a Line
Share My Lesson: The Slope of a LineShare My Lesson
 
Modern Architectures with Spring and JavaScript
Modern Architectures with Spring and JavaScriptModern Architectures with Spring and JavaScript
Modern Architectures with Spring and JavaScriptmartinlippert
 
Creating MVC Application with backbone js
Creating MVC Application with backbone jsCreating MVC Application with backbone js
Creating MVC Application with backbone jsMindfire Solutions
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsCarol McDonald
 
Slope in the real world
Slope in the real worldSlope in the real world
Slope in the real world96lynraw44888
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016Matt Raible
 
Application of Calculus in Real World
Application of Calculus in Real World Application of Calculus in Real World
Application of Calculus in Real World milanmath
 
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 Sungchul Park
 
Application of integral calculus
Application of integral calculusApplication of integral calculus
Application of integral calculusHabibur Rahman
 
Numerical integration
Numerical integrationNumerical integration
Numerical integrationMohammed_AQ
 
Application of calculus in everyday life
Application of calculus in everyday lifeApplication of calculus in everyday life
Application of calculus in everyday lifeMohamed Ibrahim
 
Calculus in real life
Calculus in real lifeCalculus in real life
Calculus in real lifeSamiul Ehsan
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...ENSET, Université Hassan II Casablanca
 

En vedette (14)

Share My Lesson: The Slope of a Line
Share My Lesson: The Slope of a LineShare My Lesson: The Slope of a Line
Share My Lesson: The Slope of a Line
 
Modern Architectures with Spring and JavaScript
Modern Architectures with Spring and JavaScriptModern Architectures with Spring and JavaScript
Modern Architectures with Spring and JavaScript
 
Creating MVC Application with backbone js
Creating MVC Application with backbone jsCreating MVC Application with backbone js
Creating MVC Application with backbone js
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.js
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Slope in the real world
Slope in the real worldSlope in the real world
Slope in the real world
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
 
Application of Calculus in Real World
Application of Calculus in Real World Application of Calculus in Real World
Application of Calculus in Real World
 
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
 
Application of integral calculus
Application of integral calculusApplication of integral calculus
Application of integral calculus
 
Numerical integration
Numerical integrationNumerical integration
Numerical integration
 
Application of calculus in everyday life
Application of calculus in everyday lifeApplication of calculus in everyday life
Application of calculus in everyday life
 
Calculus in real life
Calculus in real lifeCalculus in real life
Calculus in real life
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
 

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

Custom Android Code Templates
Custom Android Code TemplatesCustom Android Code Templates
Custom Android Code Templatesmurphonic
 
Understanding Webkit Rendering
Understanding Webkit RenderingUnderstanding Webkit Rendering
Understanding Webkit RenderingAriya Hidayat
 
So, you think you know widgets.
So, you think you know widgets.So, you think you know widgets.
So, you think you know widgets.danielericlee
 
MongoDB for Java Developers with Spring Data
MongoDB for Java Developers with Spring DataMongoDB for Java Developers with Spring Data
MongoDB for Java Developers with Spring DataChris Richardson
 
MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB for Java Devs with Spring Data - MongoPhilly 2011MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB for Java Devs with Spring Data - MongoPhilly 2011MongoDB
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
Backbone beyond jQuery
Backbone beyond jQueryBackbone beyond jQuery
Backbone beyond jQueryAdam Krebs
 
Building businesspost.ie using Node.js
Building businesspost.ie using Node.jsBuilding businesspost.ie using Node.js
Building businesspost.ie using Node.jsRichard Rodger
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
Dependency Injection @ AngularJS
Dependency Injection @ AngularJSDependency Injection @ AngularJS
Dependency Injection @ AngularJSRan Mizrahi
 
Planbox Backbone MVC
Planbox Backbone MVCPlanbox Backbone MVC
Planbox Backbone MVCAcquisio
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM ManipulationsYnon Perek
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
GR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk KönigGR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk KönigGR8Conf
 

Similaire à Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA (20)

Custom Android Code Templates
Custom Android Code TemplatesCustom Android Code Templates
Custom Android Code Templates
 
Understanding Webkit Rendering
Understanding Webkit RenderingUnderstanding Webkit Rendering
Understanding Webkit Rendering
 
Backbone
BackboneBackbone
Backbone
 
So, you think you know widgets.
So, you think you know widgets.So, you think you know widgets.
So, you think you know widgets.
 
MongoDB for Java Developers with Spring Data
MongoDB for Java Developers with Spring DataMongoDB for Java Developers with Spring Data
MongoDB for Java Developers with Spring Data
 
MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB for Java Devs with Spring Data - MongoPhilly 2011MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB for Java Devs with Spring Data - MongoPhilly 2011
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
Backbone beyond jQuery
Backbone beyond jQueryBackbone beyond jQuery
Backbone beyond jQuery
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
 
Terrific Frontends
Terrific FrontendsTerrific Frontends
Terrific Frontends
 
Building businesspost.ie using Node.js
Building businesspost.ie using Node.jsBuilding businesspost.ie using Node.js
Building businesspost.ie using Node.js
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Dependency Injection @ AngularJS
Dependency Injection @ AngularJSDependency Injection @ AngularJS
Dependency Injection @ AngularJS
 
Grails 2.0 Update
Grails 2.0 UpdateGrails 2.0 Update
Grails 2.0 Update
 
Fork cli tool
Fork cli toolFork cli tool
Fork cli tool
 
Planbox Backbone MVC
Planbox Backbone MVCPlanbox Backbone MVC
Planbox Backbone MVC
 
WebGL and three.js
WebGL and three.jsWebGL and three.js
WebGL and three.js
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM Manipulations
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
GR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk KönigGR8Conf 2009: Groovy Usage Patterns by Dierk König
GR8Conf 2009: Groovy Usage Patterns by Dierk König
 

Dernier

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Dernier (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

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

  • 1. 葉政達 Cheng Ta Yeh 12年7月19日星期四
  • 2. Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA 12年7月19日星期四
  • 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 experiences 12年7月19日星期四
  • 4. Once upon a time... 12年7月19日星期四
  • 6. Start lean, get bigger later 12年7月19日星期四
  • 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 d 12年7月19日星期四
  • 8. Outlines • Front-end development • Integrate Backbone with Spring MVC • Diving into Spring Data JPA 12年7月19日星期四
  • 10. Problems ... • Few conventions and standards 12年7月19日星期四
  • 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. Problems ... • Between server-side and client-side, we need efficient tools. 12年7月19日星期四
  • 14. Who Use Backbone.js Basecamp Mobile 12年7月19日星期四
  • 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 Event 12年7月19日星期四
  • 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. Backbone Model • Data storage and business logic • Changes on the attributes will fire `change` event • Talks to server uses RESTful JSON 12年7月19日星期四
  • 20. Backbone Sample Code ItemDetailView ItemView Use window.ItemModel = Backbone.Model.extend(); ItemModel 12年7月19日星期四
  • 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(); ItemModel 12年7月19日星期四
  • 23. How to build loose coupling scalable applications? 12年7月19日星期四
  • 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. Real life application • Lots of Screens • Lots of Modules • Complex dependency 12年7月19日星期四
  • 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 Co 12年7月19日星期四
  • 28. RequirJS AMD Loader Other AMD loaders: • curl • lsjs • Dojo 1.7 and MooTools 2.0 each have their own 12年7月19日星期四
  • 29. AMD APIs • Facilitating module definition • define (module_id?, dependencies?, factory); • Handling dependency async loading • require (dependencies?, callback); 12年7月19日星期四
  • 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.js 12年7月19日星期四
  • 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.js 12年7月19日星期四
  • 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. 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.js 12年7月19日星期四
  • 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. 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.js 12年7月19日星期四
  • 36. http://s.ctyeh.me/LGW3ug Integrates Backbone.js with Spring MVC 12年7月19日星期四
  • 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 useful 12年7月19日星期四
  • 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. Spring MVC as REST Server 12年7月19日星期四
  • 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. 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. Rarely Need Custom Parsers • Automatically registers several converters. 12年7月19日星期四
  • 43. Controller Methods’ Parameters and Return Values ween s bet ing MVC he b ullet Spr T del & bon e Mo Back 12年7月19日星期四
  • 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 } Controller 12年7月19日星期四
  • 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 Controller 12年7月19日星期四
  • 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 } Controller 12年7月19日星期四
  • 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. 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-mvc 12年7月19日星期四
  • 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. Diving into Spring Data JPA 12年7月19日星期四
  • 51. Layer Architecture Backbone.js requireJS HTML Spring MVC Domain Model Spring Data JPA 12年7月19日星期四
  • 52. Between Spring MVC and Spring Data JPA • Data conversion • Design concept 12年7月19日星期四
  • 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 JPA 12年7月19日星期四
  • 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. 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. 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 Cassandra 12年7月19日星期四
  • 57. Let’s Begin With Plain JPA 12年7月19日星期四
  • 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. 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. 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. Refactoring to Spring Data JPA 12年7月19日星期四
  • 62. The Repository (DAO) public interface ItemRepository extends JpaRepository<Item, Long> {     List<Item> findBySite(Site site); } 12年7月19日星期四
  • 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. Strategy: CREATE • Split your query methods by prefix and property names. 12年7月19日星期四
  • 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 sort 12年7月19日星期四
  • 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. 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. Put It All Together Backbone.js requireJS Spring MVC Spring Data JPA 12年7月19日星期四
  • 69. The End & Thank You http://about.me/ctyeh 12年7月19日星期四