SlideShare una empresa de Scribd logo
1 de 46
Descargar para leer sin conexión
Stripes Framework

...in a comparison with Struts!




                         Johannes Carlén
               johannes.carlen@callistaenterprise.se
                     www.callistaenterprise.se
Let's talk about Struts for a minute...

• Pros                                     • Cons
      – De facto standard for a              – Simpler then than now
        couple of years                      – struts-config.xml      (form
      – Simple and powerful                    beans, global forwards, action
        concept. Easy to                       mappings with forwards, message
        understand                             resources, plugins, etc..)

      – Stable and mature                    – Validation
      – Documentation. Internet              – Property Binding
        and books                            – Confusing JSP-tags
      – Easy to find skilled                 – Layout
        developers


Stripes Framework, Slide 2
© Copyright 2009, Callista Enterprise AB
Ok, so what is this Stripes thing?


• Around since 2005 (Tim Fennell)
• Built upon the same design pattern (MVC) and concepts
  as Struts.
• An action based framework
• Exisiting skills in Struts is easily transferred to Stripes –
  no new concepts to learn
• Claim: ”...makes developing web applications in Java
  easy”




Stripes Framework, Slide 3
© Copyright 2009, Callista Enterprise AB
Tell me in a language I understand, please


•   Coding by convention & Annotations
•   No external configuration
•   URL Binding
•   Event Handlers (multiple events form)
•   Property Binding / Type Conversion (nested properties)
•   Interceptors for cross cutting concerns




Stripes Framework, Slide 4
© Copyright 2009, Callista Enterprise AB
And what's in the box?


• Validation mechanisms
• Exception handling
• JSP-tags
• Layout
• Localization
• Testing (Out of container with mock objects)
• Easy to extend




Stripes Framework, Slide 5
© Copyright 2009, Callista Enterprise AB
The fundamentals


• Action Beans & Event Handlers
• URL Binding
• Validation
• Type Conversion and Formatters
• JSP Tags & Layout




Stripes Framework, Slide 6
© Copyright 2009, Callista Enterprise AB
The Struts way - Actions

Action Class
 public class CustomerAction extends DispatchAction {

 public ActionForward save(ActionMapping mapping,
                               ActionForm form,                struts-config.xml
                               HttpServletRequest request,
                     HttpServletResponse response)
           throws Exception {                                   <?xml version="1.0" encoding="ISO-8859-1" ?>
                                                                <!DOCTYPE struts-config PUBLIC
        CustomerForm customerForm = (CustomerForm) form;            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
      // Validate form                                              "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
      if (!isValid(form, mapping, request {                     <struts-config>
           CustomerForm.                                            <form-beans>
           setCustomers(customerService.findAllCustomers());        <form-bean name="customerForm" type="se.callistaenterprise.exampleweb.CustomerForm" />
        return mapping.getInputForward();                           </form-beans>
      }                                                             <global-exceptions>
      Customer customer = (Customer)     customerForm.              <exception type="se.callistaenterprise.examplecommon.BaseException"
                               getCustomerBean().extract();                         handler="se.callistaenterprise.exampleweb.action.BaseExceptionHandler"
         customerService.saveCustomer(customer,                 key="errors.general"/>
 NumericUtils.toLong(customerForm.getCustomerId()));                </global-exceptions>
        return mapping.findForward(FORWARD_SUCCESS);                <global-forwards>
 }                                                                  <forward name="start" path="/start.do" redirect="true"/>
                                                                    </global-forwards>
                                                                    <action-mappings>
                                                                                    <action path="/customer"
                                                                                    type="org.springframework.web.struts.DelegatingActionProxy"
Form Bean                                                                           scope="request"
                                                                                    parameter="task"
                                                                                    input=".customer.save"
 public class BaseForm extends ValidatorForm {
                                                                                    name="customerForm"
 private CustomerBean customer;
                                                                                    validate="false">
 private String startDate;
                                                                                    <forward name="success" path="/customer/customer.do?task=edi
 public CustomerBean getCustomer() {return customer;}
                                                                                     redirect="true" />
 public void setCustomer(CustomerBean customer)
                                                                                    <forward name="failure_redirect" path="/customer/list.do" redirect="true" />
 {this.customer=customer;}
                                                                    </action>
 public String getStartDate() {return startDate;}
                                                                    </action-mappings>
 public void setStartDate(String date){this.startDate=date;}
                                                                    <plug-in className="org.apache.struts.tiles.TilesPlugin">
 }
                                                                        <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
                                                                        <set-property property="moduleAware" value="true" />
                                                                        <set-property property="definitions-parser-validate" value="true" />
View helper bean                                                    </plug-in>
                                                                </struts-config>
 public class CustomerBean {
 private String id;
 private String name;
 private String email;

 public   String getId() {return id;}
 public   void setId(String id) {this.id=id;}
 public   String getName() {return name;}
 public   void setName(String name) {this.name=name;}
   Stripes Framework, Slide 7
 public   String getEmail() {return email;}
 public   void setEmail(String email) {this.email=email;}
 } © Copyright 2009, Callista Enterprise AB
The fundamentals – Action Beans


• Handles an action and encapsulates the model beans
• Implements the ActionBean interface:

            public interface ActionBean {
                public ActionBeanContext getContext();
                public void setContext(ActionBeanContext context);
            }




Stripes Framework, Slide 8
© Copyright 2009, Callista Enterprise AB
The Struts way – Dispatch Actions



    public class CustomerAction extends DispatchAction {

    public ActionForward save(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {

        CustomerForm customerForm = (CustomerForm) form;
        if (!isValid(form, mapping, request {
          CustomerForm.setCustomers(customerService.findAllCustomers());
          return mapping.getInputForward();
        }
        Customer customer = (Customer) customerForm.getCustomerBean().extract();
        customerService.saveCustomer(customer,customerForm.getCustomerId()));
        return mapping.findForward(FORWARD_SUCCESS);
    }




Stripes Framework, Slide 9
© Copyright 2009, Callista Enterprise AB
The fundamentals – Event Handlers


• Stripes responds to a request and invokes a method in
  the action bean – an event handler.
• Action Bean method
   – has no parameters and returns a Resolution

 public class CustomerActionBean implements ActionBean {
     @Validate
     private Customer customer;
     public Resolution save() {
         customerManager.save(this.customer);
         return new ForwardResolution("/WEB-INF/pages/customers.jsp");
     }
     ...
 }

Stripes Framework, Slide 10
© Copyright 2009, Callista Enterprise AB
Resolutions


• Tells Stripes what to do next in a request

• Examples:

             new ForwardResolution(”/WEB-INF/pages/my.jsp”);

             new ForwardResolution(AnotherActionBean.class,”someEvent”);

             new RedirectResolution(”/some/other.jsp”);

             new StreamingResolution(”application/pdf”,myStream);




Stripes Framework, Slide 11
© Copyright 2009, Callista Enterprise AB
The fundamentals


• Action Beans & Event Handlers
• URL Binding
• Validation
• Type Conversion and Formatters
• JSP Tags & Layout




Stripes Framework, Slide 12
© Copyright 2009, Callista Enterprise AB
The Struts way – URL Binding


    struts-config.xml

    <action-mappings>
        <action path="/customer"
          type="org.springframework.web.struts.DelegatingActionProxy"
          scope="request"
          parameter="task"
         input=".customer.save"
         name="customerForm"
         validate="false">
         <forward name="success" path="/customer.do?task=edit" redirect="true" />
         <forward name="failure" path="/customer.do?task=list" redirect="true" />
         </action>
     </action-mappings>




Stripes Framework, Slide 13
© Copyright 2009, Callista Enterprise AB
The fundamentals - URL Binding


• By convention

          The action bean class:
          se.callistaenterprise.web.store.CustomerActionBean


          ...defaults to:
          http://myserver/mycontext/store/Customer.action




Stripes Framework, Slide 14
© Copyright 2009, Callista Enterprise AB
The fundamentals - URL Binding


• Override using @UrlBinding


         @UrlBinding(”/customer/{$event}.html”)
         public class CustomerAction implements ActionBean {
             public Resolution save() {
             ...
             }
         }


      – Use this URL to trigger event:
                    http://myserver/mycontext/customer/save.html



Stripes Framework, Slide 15
© Copyright 2009, Callista Enterprise AB
The fundamentals


• Action Beans & Event Handlers
• URL Binding
• Validation
• Type Conversion and Formatters
• JSP Tags & Layout




Stripes Framework, Slide 16
© Copyright 2009, Callista Enterprise AB
The Struts way – Validation

• Validation in action method, form bean, validator.xml and
  validator-rules.xml

     Action Class                                                             Form Bean
     public class CustomerAction extends DispatchAction {                     public class CustomerBeann extends ActionForm {

     public ActionForward save(ActionMapping mapping,                         public ActionErrors validate(ActionMapping mapping,
                                   ActionForm form,                                                         HttpServletRequest request) {
                                   HttpServletRequest request,                    ActionErrors actionErrors = new ActionErrors();
                         HttpServletResponse response)                            // validate credit
               throws Exception {                                                 if (credit > Credit.LIMIT) {
                                                                                     actionErrors.add("credte", new ActionMessage("error.name"));
            CustomerForm customerForm = (CustomerForm) form;                      }
          // Validate form                                                        return actionErrors;
          if (!isValid(form, mapping, request {                               }
               CustomerForm.                                                  ...
               setCustomers(customerService.findAllCustomers());
            return mapping.getInputForward();
          }
          Customer customer = (Customer)     customerForm.
                                   getCustomerBean().extract();
             customerService.saveCustomer(customer,
     NumericUtils.toLong(customerForm.getCustomerId()));                                           validator-rules.xml
            return mapping.findForward(FORWARD_SUCCESS);
     }                                                                                             <validator name="email"
                                                                                                                   classname="org.apache.struts.validator.FieldChecks"
                                                                                                                   method="validateEmail"
                                                                                                                   methodParams="java.lang.Object,
                                                                                                                   org.apache.commons.validator.ValidatorAction,

      validator.xml                                                                                                org.apache.commons.validator.Field,
                                                                                                               org.apache.struts.action.ActionMessages,
                                                                                                               org.apache.commons.validator.Validator,
      <form name="customerForm">                                                                               javax.servlet.http.HttpServletRequest"
          <field property="customerBean.customerId" depends="required">                                    depends="" msg="errors.email" />
              <arg name="required" key="action.customer.customerId" position="0" />
          </field>
          <field property="customerBean.customer.namn" depends="required">
              <arg name="required" key="action.customer.namn" position="0" />
          </field>
          <field property="customerBean.customer.email" depends="email">
              <arg0 key="action.customer.email" />
          </field>
      </form>
Stripes Framework, Slide 17
© Copyright 2009, Callista Enterprise AB
The fundamentals - Validation


• Using @Validate
          (field,required,on,minlength,maxlength,expression,mask,minvalue,maxvalue,
          converter,trim,label,ignore,encrypted)



             @Validate(required=true,minlength=8, maxlength=32)
             private String password

             @Validate(required=true, expression=”this>=startDate”,
                       converter=DateConverter.class)
             private Date endDate;

             @ValidateNestedProperties({
                 @Validate(field=”email” required=true, on=”save”),
                 @Validate(field=”name” requried=true, on=”save”)})
             private Customer customer;


Stripes Framework, Slide 18
© Copyright 2009, Callista Enterprise AB
The fundamentals - Validation


• Custom validation with @ValidationMethod


          @ValidationMethod(on=”save”)
          public void validateCustomerUsername() {
              if(customerManager.usernameExists(customer.getUsername)){
                   // Add validation error
              }
          }




Stripes Framework, Slide 19
© Copyright 2009, Callista Enterprise AB
The fundamentals


• Action Beans & Event Handlers
• URL Binding
• Validation
• Type Conversion and Formatters
• JSP Tags & Layout




Stripes Framework, Slide 20
© Copyright 2009, Callista Enterprise AB
The Struts way – Type conversion

• Conversion in action class.

      CustomerAction.java

          ...
          CustomerForm customerForm = (CustomerForm) form;
          Customer customer = new Customer();
          float credit = Float.parseFloat(customerForm.getCredit());
          c.setCredit(credit);
          ...




      Customer.java

      private float credit;
      public float getCredit() {return credit;}
      public void setCredit(float credit) {this.credit=credit;}




Stripes Framework, Slide 21
© Copyright 2009, Callista Enterprise AB
The fundamentals – Type Conversion


• Used for parameter binding
• Built in converters for standard types (numericals, booleans, enums,
  email, credit card, one-to-many)
• Write your own custom converter by implementing the
  TypeConverter<T> interface




Stripes Framework, Slide 22
© Copyright 2009, Callista Enterprise AB
The fundamentals – Type Conversion

• Example - converting String to PhoneNumber
  MyActionBean.java

  @Validate(required=true, converter=PhoneNumberConverter.class)
  private PhoneNumber phoneNumber;



  PhoneNumberConverter.java

   public class PhoneNumberConverter implements TypeConverter<PhoneNumber> {
         @Override
         public PhoneNumber convert(String input, Class<? extends PhoneNumber> targetType,
                                        Collection<ValidationError> errors) {
             try {
                  PhoneNumber phoneNumber = new PhoneNumber(input);
                  return phoneNumber;
             } catch (IllegalArgumentException e) {
                  errors.add(new ScopedLocalizableError("converter.phonenumber",
                                                        "invalidPhoneNumber"));
                  return null;
             }
         }
         ...
   }
Stripes Framework, Slide 23
© Copyright 2009, Callista Enterprise AB
The fundamentals – Formatters


• Type conversion in the opposite direction
• An object is converted to a String to be displayed to the user
• Locale-sensitive
• Write a custom formatter by implementing the Formatter interface
• Best practice - use the same class to implement both TypeConverter
  and Formatter




Stripes Framework, Slide 24
© Copyright 2009, Callista Enterprise AB
The fundamentals


• Action Beans & Event Handlers
• URL Binding
• Validation
• Type Conversion and Formatters
• JSP Tags & Layout




Stripes Framework, Slide 25
© Copyright 2009, Callista Enterprise AB
The Struts way – JSP tags


• Example of a simple JSP:

     editCustomer.jsp

        <html:form action="/customer">
          <html:errors />
          <html:hidden property="customerId" />
          <bean:message key=”customer.company” />
          <html:select property="customerCompanyId">
            <hmtl:optionsCcollection property="companies" value="id" label="name" />
          </html:select>
          <bean:message key=”customer.name.and.phone” />
          <html:text property="customer.name"/>
          <html:text property="customer.phoneNumber"/>
        </html:form>




Stripes Framework, Slide 26
© Copyright 2009, Callista Enterprise AB
The Fundamentals - JSP tags


• JSP tags equivalent to Struts HTML tags
• Uses the name attribute to bind a value to an action bean property
• Labels from resource bundles
• All HTML attributes
            editcustomer.jsp

            <stripes:form action="/customer.html">
              <stripes:errors />
              <stripes:hidden name="customer.id" />
              <stripes:select name="customer.company.id">
                <stripes:options-collection collection="${actionBean.companies}"
                                            value="id" label="name" />
              </stripes:select>
              <stripes:text name="customer.name" style=”customerLabels” />
              <stripes:text name="customer.phoneNumber" />
            </stripes:form>

Stripes Framework, Slide 27
© Copyright 2009, Callista Enterprise AB
The Tiles way – JSP layout

tiles-def.xml
<tiles-definitions>
    <definition name=".layout" path="/WEB-INF/pages/layout/layout.jsp">
        <put name="menu" value="/WEB-INF/pages/topmenu.jsp"/>                struts-config.xml
        <put name="body" value="/WEB-INF/pages/start.jsp"/>
                                                                             <plug-in
    </definition>                                                            className="org.apache.struts.tiles.TilesPlugin">
    <definition name=".customer.view" extends=".layout">                             <set-property property="definitions-config"
                                                                             value="/WEB-INF/tiles-defs.xml" />
        <put name="body" value="/WEB-INF/pages/customer/view.jsp"/>                  <set-property property="moduleAware"
                                                                             value="true" />
    </definition>                                                                    <set-property property="definitions-parser-
    <definition name=".customer.edit" extends=".layout">                     validate" value="true" />
                                                                             </plug-in>
        <put name="body" value="/WEB-INF/pages/customer/edit.jsp"/>
                                                                             <action path="/customer"
    </definition>                                                            type="org.apache.struts.actions.ForwardAction"
<tiles-definitions>                                                                  parameter="homepage"/>




layout.jsp
<html>
<body>
    <tiles:insert attribute="menu"/>
    <tiles:insert attribute="body"/>
</body>
</html>



                                                       edit.jsp
                                                         <h1>On this page you can edit the
view.jsp                                                 customer</h1>
  Stripes Framework, Slide 28
   <h1>This page outputs the customer</h1>
  © Copyright 2009, Callista Enterprise AB
The Fundamentals - JSP layout

• No configuration
• Concepts: Layout, Renderer, Component, Attributes
• Three tags: layout-definition, layout-render, layout-component
layout.jsp

<stripes:layout-definition>
  <h1>${title}</h1>
  <stripes:layout-component name=”${menu}”/>
          My default menu</stripes:layout-component>
  <stripes:layout-component name=”body”/>
</stripes:layout-definition>



                view.jsp (renderer)

                <stripes:layout-render name=”/WEB-INF/pages/layout.jsp”
                                       title=”View customer”>
                  <stripes:layout-component name=”body”/>
                          Output the customer..</stripes:layout-component>
                </stripes:layout-render>
 Stripes Framework, Slide 29
 © Copyright 2009, Callista Enterprise AB
More features


• Web Flows
• Interceptors
• Localization, Messages and Validation Errors
• Testing




Stripes Framework, Slide 30
© Copyright 2009, Callista Enterprise AB
The Struts Way – No flow


• No mechanism in Struts for wizard-like functionality
• Alternatives: Struts Flow (sandbox), Spring Web Flow
• ..or by hand




Stripes Framework, Slide 31
© Copyright 2009, Callista Enterprise AB
The Stripes Wizard


• The @Wizard annotation
      – generates hidden inputs for already submitted fields
      – keeps track of which fields are to be validated for each step



            @Wizard
            public class CustomerActionBean implements ActionBean {
                public Resolution view() {...}
                public Resolution save() {...}
            }




Stripes Framework, Slide 32
© Copyright 2009, Callista Enterprise AB
More features


• Web Flows
• Interceptors
• Localization, Messages and Validation Errors
• Testing




Stripes Framework, Slide 33
© Copyright 2009, Callista Enterprise AB
The Struts way – Interceptors


• No real equivalent functionality in Struts

CustomerAction.java

public ActionForward view(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response) throws Exception {

    CustomerForm customerForm = (CustomerForm) form;
     customerForm.setCustomer(customerService.findCustomer(customerForm.getId()));
    return mapping.findForward(FORWARD_SUCCESS_VIEW);
}

public ActionForward save(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response) throws Exception {

    CustomerForm customerForm = (CustomerForm) form;
    Customer customer = (Customer) customerForm.getCustomerBean().extract();
    customerService.saveCustomer(customer);
    customerForm.setCustomer(customerService.findCustomer(customerForm.getId()));
     return mapping.findForward(FORWARD_SUCCESS_VIEW);
 }
Stripes Framework, Slide 34
© Copyright 2009, Callista Enterprise AB
Interceptors


• Code that is executed before and/or after a life cycle stage
• Two ways to intercept:
      – Before / After methods (applies to a specific action bean)
      – Global interceptor (intercepts all requests at given stages)
                             EST
                       R EQU
                   G
           O   MIN                           Request    ActionBean    Handler
       INC
                                               Init     Resolution   Resolution


                                                                                  Binding And
                                                                                   Validation



                                                                                   Custom
                                         E
                                P   ON S                                          Validation
                          RES
                    NG
                 GOI
          OUT                                 Request   Resolution    Event
                                             Complete   Execution    Handling
Stripes Framework, Slide 35
© Copyright 2009, Callista Enterprise AB
Interceptors


                                                                     T
                                                                 UE S
                                                             R EQ
                                                        NG
                                                    OM I
• Before and after methods
                                                                    Request   ActionBean    Handler
                                              INC                     Init    Resolution   Resolution

                                                                                                        Binding And

      – Add a method to an action bean                                                                   Validation


                                                                 SE                                      Custom
      – Annotate with @Before or @After           GOI
                                                     NG
                                                        R ES
                                                            P ON                                        Validation

                                               OUT         Request            Resolution    Event
                                                          Complete            Execution    Handling




 @After(stages = LifecycleStage.BindingAndValidation, on = {"view”,”edit"})
 public void populateCustomer() {
     customer = customerManager.findById(customer.getId());
 }




Stripes Framework, Slide 36
© Copyright 2009, Callista Enterprise AB
Interceptors

                                                                     EST
                                                           R   EQU
                                                        NG
                                                    OM I             Request   ActionBean    Handler
                                              INC
• Global Interceptor
                                                                       Init    Resolution   Resolution

                                                                                                         Binding And
                                                                                                          Validation
       – Implement the Interceptor interface                                                              Custom
                                                                 E
                                                              ONS
                                                          ESP                                            Validation
          and indicate life cycle stages       OUT
                                                  GOI
                                                     N GR
                                                           Request             Resolution    Event
                                                          Complete             Execution    Handling




                                                                                            }
   @Intercepts(LifecycleStage.EventHandlingResolution)
   public class AuditLogInterceptor implements Interceptor {
       public Resolution intercept(ExecutionContext context) throws Exception
       {
           logEventStarted(context);
           Resolution resolution = context.proceed();
           logEventCompleted(context);

                return resolution;
         }
   }
Stripes Framework, Slide 37
© Copyright 2009, Callista Enterprise AB
More features


• Web Flows
• Interceptors
• Localization, Messages and Validation Errors
• Testing




Stripes Framework, Slide 38
© Copyright 2009, Callista Enterprise AB
The Struts way – I18n and messages


• ApplicationResources.properties – single resource bundle
• Use the struts-bean taglib:
          <bean:message key="app.name" />
• Use <html:errors/> and <html:messages/> to display validation
  errors and messages

                     editCustomer.jsp

                        <html:form action="/customer">
                          <html:errors /><br />
                          <bean:message key=”customer.label.name” />
                          <html:text property="customer.name"/>
                        </html:form>




Stripes Framework, Slide 39
© Copyright 2009, Callista Enterprise AB
Localization, Messages & Validation Errors

• Localization relies on standard ResourceBundles
• JSTL with <fmt:message> for text
• Application messages and validation errors by key:
  CustomerActionBean.java

  @ValidationMethod(on=”save”)
  public void validateCustomerUsername() {
      if(customerManager.usernameExists(customer.getUsername)){
          getContext.getValidationErrors.
            add(new LocalizableError(”customer.invalid.username”,customer.getUsername());
      }
  }



        editCustomer.jsp

        <stripes:form action="/customer.html">
          <stripes:errors /><br />
          <fmt:message key=”customer.name” />
          <stripes:text name="customer.name" style=”customerLabels” />
        </stripes:form>
Stripes Framework, Slide 40
© Copyright 2009, Callista Enterprise AB
More features


• Web Flows
• Interceptors
• Localization, Messages and validation errors
• Testing




Stripes Framework, Slide 41
© Copyright 2009, Callista Enterprise AB
The Struts way – Out of container testing


• Struts TestCase on Sourceforge
• Mock objects
• Unit tests extends MockStrutsTestCase

                public class TestCustomerAction extends MockStrutsTestCase {

                     public TestCustomerAction(String testName) { super(testName); }

                     public void testSave() {
                        setConfigFile("mymodule","/WEB-INF/struts-config.xml");
                        setRequestPathInfo("/customer.do");
                        addRequestParameter("task","save");
                        addRequestParameter("customer.email","NO_VALID_EMAIL_ADRESS");
                        actionPerform();
                        verifyForward("edit");
                        verifyActionErrors(new String[] {"error.invalid.email"});
                     }
                }




Stripes Framework, Slide 42
© Copyright 2009, Callista Enterprise AB
Automated testing


• What?
      – Submit a form, validating response with any validation errors
      – Type conversion
      – URL Bindings
      – Interceptors
• How?
      – Using mock objects for Session, Request, Response,
        ServletContext objects etc)
      – MockRoundtrip simulates requests to action beans



Stripes Framework, Slide 43
© Copyright 2009, Callista Enterprise AB
Test example


@Test
public void testEmailRequired() throws Exception {

      MockRoundtrip trip = new MockRoundtrip(mockServletContext,
                                             CustomerActionBean.class);
      trip.setParameter("customer.email", "NO_VALID_EMAIL_ADRESS");
      trip.execute("save");

      assertEquals(1, trip.getValidationErrors().size());
}




Stripes Framework, Slide 44
© Copyright 2009, Callista Enterprise AB
Wrapping up


• Easy but still powerful MVC framework without the Struts caveats
• Short learning curve for existing Struts developers
      – Manage in hours – control in a couple of days
• 30% less code (at least)
• Simplicity saves time
• Good documentation
• And yes the Stripes team's claim holds – Stripes really makes web
  application development easier.




Stripes Framework, Slide 45
© Copyright 2009, Callista Enterprise AB
As simple as that...




                                           Q&A
                                        Johannes Carlén
                              johannes.carlen@callistaenterprise.se
                                    www.callistaenterprise.se




Stripes Framework, Slide 46
© Copyright 2009, Callista Enterprise AB

Más contenido relacionado

La actualidad más candente

BPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveBPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveAlfresco Software
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developersKai Koenig
 
Planbox Backbone MVC
Planbox Backbone MVCPlanbox Backbone MVC
Planbox Backbone MVCAcquisio
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoRob Bontekoe
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryPamela Fox
 
Dom selecting & jQuery
Dom selecting & jQueryDom selecting & jQuery
Dom selecting & jQueryKim Hunmin
 
ILUG 2010 - Deploying plug-ins to the enterprise
ILUG 2010 - Deploying plug-ins to the enterpriseILUG 2010 - Deploying plug-ins to the enterprise
ILUG 2010 - Deploying plug-ins to the enterpriseRené Winkelmeyer
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletonGeorge Nguyen
 
JSP Syntax_1
JSP Syntax_1JSP Syntax_1
JSP Syntax_1brecke
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJSAaronius
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsIMC Institute
 
JavaServer Faces 2.0 - JavaOne India 2011
JavaServer Faces 2.0 - JavaOne India 2011JavaServer Faces 2.0 - JavaOne India 2011
JavaServer Faces 2.0 - JavaOne India 2011Arun Gupta
 
JavaFX – 10 things I love about you
JavaFX – 10 things I love about youJavaFX – 10 things I love about you
JavaFX – 10 things I love about youAlexander Casall
 
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces Skills Matter
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
Templates
TemplatesTemplates
Templatessoon
 

La actualidad más candente (19)

BPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveBPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep Dive
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
Planbox Backbone MVC
Planbox Backbone MVCPlanbox Backbone MVC
Planbox Backbone MVC
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Dom selecting & jQuery
Dom selecting & jQueryDom selecting & jQuery
Dom selecting & jQuery
 
ILUG 2010 - Deploying plug-ins to the enterprise
ILUG 2010 - Deploying plug-ins to the enterpriseILUG 2010 - Deploying plug-ins to the enterprise
ILUG 2010 - Deploying plug-ins to the enterprise
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
JSP Syntax_1
JSP Syntax_1JSP Syntax_1
JSP Syntax_1
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom Tags
 
AngularJS On-Ramp
AngularJS On-RampAngularJS On-Ramp
AngularJS On-Ramp
 
JavaServer Faces 2.0 - JavaOne India 2011
JavaServer Faces 2.0 - JavaOne India 2011JavaServer Faces 2.0 - JavaOne India 2011
JavaServer Faces 2.0 - JavaOne India 2011
 
JavaFX – 10 things I love about you
JavaFX – 10 things I love about youJavaFX – 10 things I love about you
JavaFX – 10 things I love about you
 
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
Templates
TemplatesTemplates
Templates
 
Advanced Visualforce Webinar
Advanced Visualforce WebinarAdvanced Visualforce Webinar
Advanced Visualforce Webinar
 

Destacado

Who Am I Cooper
Who Am I CooperWho Am I Cooper
Who Am I CooperKathryn271
 
Perkembangan asuransi syariah di indonesia 2012
Perkembangan asuransi syariah di indonesia 2012Perkembangan asuransi syariah di indonesia 2012
Perkembangan asuransi syariah di indonesia 2012Wiku Suryomurti
 
Why and how to use graphs and infographics in your presentations
Why and how to use graphs and infographics in your presentationsWhy and how to use graphs and infographics in your presentations
Why and how to use graphs and infographics in your presentationsFormation 3.0
 
презентация1[1]
презентация1[1]презентация1[1]
презентация1[1]gueste73644a
 
презентация1[1]
презентация1[1]презентация1[1]
презентация1[1]gueste73644a
 
Quality of Consumer Experience in the Future Internet
Quality of Consumer Experience in the Future InternetQuality of Consumer Experience in the Future Internet
Quality of Consumer Experience in the Future InternetVali Lalioti
 
Presentation missouri
Presentation missouriPresentation missouri
Presentation missourifeoropeza
 
Making Peace With Russia Dec 3 2010
Making Peace With Russia Dec 3 2010Making Peace With Russia Dec 3 2010
Making Peace With Russia Dec 3 2010petersimmie
 
Créez votre cours en ligne flyer automne
Créez votre cours en ligne   flyer automneCréez votre cours en ligne   flyer automne
Créez votre cours en ligne flyer automneFormation 3.0
 
Selfportraits
SelfportraitsSelfportraits
Selfportraitsmertxita
 
Victor Alavardo Geometry Project
Victor Alavardo Geometry ProjectVictor Alavardo Geometry Project
Victor Alavardo Geometry ProjectVictorAlvarado
 

Destacado (20)

Audi
AudiAudi
Audi
 
Who Am I Cooper
Who Am I CooperWho Am I Cooper
Who Am I Cooper
 
Virtual team tools
Virtual team toolsVirtual team tools
Virtual team tools
 
Prml sec6
Prml sec6Prml sec6
Prml sec6
 
chapter4 Blood Circle
chapter4 Blood Circlechapter4 Blood Circle
chapter4 Blood Circle
 
Perkembangan asuransi syariah di indonesia 2012
Perkembangan asuransi syariah di indonesia 2012Perkembangan asuransi syariah di indonesia 2012
Perkembangan asuransi syariah di indonesia 2012
 
Why and how to use graphs and infographics in your presentations
Why and how to use graphs and infographics in your presentationsWhy and how to use graphs and infographics in your presentations
Why and how to use graphs and infographics in your presentations
 
Strategic Planning
Strategic PlanningStrategic Planning
Strategic Planning
 
Audi
AudiAudi
Audi
 
презентация1[1]
презентация1[1]презентация1[1]
презентация1[1]
 
презентация1[1]
презентация1[1]презентация1[1]
презентация1[1]
 
Quality of Consumer Experience in the Future Internet
Quality of Consumer Experience in the Future InternetQuality of Consumer Experience in the Future Internet
Quality of Consumer Experience in the Future Internet
 
The Son's Strategy
The Son's StrategyThe Son's Strategy
The Son's Strategy
 
DondeEsta
DondeEstaDondeEsta
DondeEsta
 
Presentation missouri
Presentation missouriPresentation missouri
Presentation missouri
 
Making Peace With Russia Dec 3 2010
Making Peace With Russia Dec 3 2010Making Peace With Russia Dec 3 2010
Making Peace With Russia Dec 3 2010
 
Créez votre cours en ligne flyer automne
Créez votre cours en ligne   flyer automneCréez votre cours en ligne   flyer automne
Créez votre cours en ligne flyer automne
 
Selfportraits
SelfportraitsSelfportraits
Selfportraits
 
Victor Alavardo Geometry Project
Victor Alavardo Geometry ProjectVictor Alavardo Geometry Project
Victor Alavardo Geometry Project
 
Meraviglioso
MeravigliosoMeraviglioso
Meraviglioso
 

Similar a Stripes Framework

Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortalJennifer Bourey
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkara JUG
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksHjörtur Hilmarsson
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5Tieturi Oy
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web FrameworkLuther Baker
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesNCCOMMS
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript FrameworkAll Things Open
 
Primefaces Confess 2012
Primefaces Confess 2012Primefaces Confess 2012
Primefaces Confess 2012cagataycivici
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 

Similar a Stripes Framework (20)

Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web Framework
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_libraries
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
 
Primefaces Confess 2012
Primefaces Confess 2012Primefaces Confess 2012
Primefaces Confess 2012
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Asp.NET MVC
Asp.NET MVCAsp.NET MVC
Asp.NET MVC
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 

Último

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
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
 
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
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
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
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
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
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
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
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 

Último (20)

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
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
 
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
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
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!
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
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
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
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)
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 

Stripes Framework

  • 1. Stripes Framework ...in a comparison with Struts! Johannes Carlén johannes.carlen@callistaenterprise.se www.callistaenterprise.se
  • 2. Let's talk about Struts for a minute... • Pros • Cons – De facto standard for a – Simpler then than now couple of years – struts-config.xml (form – Simple and powerful beans, global forwards, action concept. Easy to mappings with forwards, message understand resources, plugins, etc..) – Stable and mature – Validation – Documentation. Internet – Property Binding and books – Confusing JSP-tags – Easy to find skilled – Layout developers Stripes Framework, Slide 2 © Copyright 2009, Callista Enterprise AB
  • 3. Ok, so what is this Stripes thing? • Around since 2005 (Tim Fennell) • Built upon the same design pattern (MVC) and concepts as Struts. • An action based framework • Exisiting skills in Struts is easily transferred to Stripes – no new concepts to learn • Claim: ”...makes developing web applications in Java easy” Stripes Framework, Slide 3 © Copyright 2009, Callista Enterprise AB
  • 4. Tell me in a language I understand, please • Coding by convention & Annotations • No external configuration • URL Binding • Event Handlers (multiple events form) • Property Binding / Type Conversion (nested properties) • Interceptors for cross cutting concerns Stripes Framework, Slide 4 © Copyright 2009, Callista Enterprise AB
  • 5. And what's in the box? • Validation mechanisms • Exception handling • JSP-tags • Layout • Localization • Testing (Out of container with mock objects) • Easy to extend Stripes Framework, Slide 5 © Copyright 2009, Callista Enterprise AB
  • 6. The fundamentals • Action Beans & Event Handlers • URL Binding • Validation • Type Conversion and Formatters • JSP Tags & Layout Stripes Framework, Slide 6 © Copyright 2009, Callista Enterprise AB
  • 7. The Struts way - Actions Action Class public class CustomerAction extends DispatchAction { public ActionForward save(ActionMapping mapping, ActionForm form, struts-config.xml HttpServletRequest request, HttpServletResponse response) throws Exception { <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC CustomerForm customerForm = (CustomerForm) form; "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" // Validate form "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> if (!isValid(form, mapping, request { <struts-config> CustomerForm. <form-beans> setCustomers(customerService.findAllCustomers()); <form-bean name="customerForm" type="se.callistaenterprise.exampleweb.CustomerForm" /> return mapping.getInputForward(); </form-beans> } <global-exceptions> Customer customer = (Customer) customerForm. <exception type="se.callistaenterprise.examplecommon.BaseException" getCustomerBean().extract(); handler="se.callistaenterprise.exampleweb.action.BaseExceptionHandler" customerService.saveCustomer(customer, key="errors.general"/> NumericUtils.toLong(customerForm.getCustomerId())); </global-exceptions> return mapping.findForward(FORWARD_SUCCESS); <global-forwards> } <forward name="start" path="/start.do" redirect="true"/> </global-forwards> <action-mappings> <action path="/customer" type="org.springframework.web.struts.DelegatingActionProxy" Form Bean scope="request" parameter="task" input=".customer.save" public class BaseForm extends ValidatorForm { name="customerForm" private CustomerBean customer; validate="false"> private String startDate; <forward name="success" path="/customer/customer.do?task=edi public CustomerBean getCustomer() {return customer;} redirect="true" /> public void setCustomer(CustomerBean customer) <forward name="failure_redirect" path="/customer/list.do" redirect="true" /> {this.customer=customer;} </action> public String getStartDate() {return startDate;} </action-mappings> public void setStartDate(String date){this.startDate=date;} <plug-in className="org.apache.struts.tiles.TilesPlugin"> } <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /> <set-property property="moduleAware" value="true" /> <set-property property="definitions-parser-validate" value="true" /> View helper bean </plug-in> </struts-config> public class CustomerBean { private String id; private String name; private String email; public String getId() {return id;} public void setId(String id) {this.id=id;} public String getName() {return name;} public void setName(String name) {this.name=name;} Stripes Framework, Slide 7 public String getEmail() {return email;} public void setEmail(String email) {this.email=email;} } © Copyright 2009, Callista Enterprise AB
  • 8. The fundamentals – Action Beans • Handles an action and encapsulates the model beans • Implements the ActionBean interface: public interface ActionBean { public ActionBeanContext getContext(); public void setContext(ActionBeanContext context); } Stripes Framework, Slide 8 © Copyright 2009, Callista Enterprise AB
  • 9. The Struts way – Dispatch Actions public class CustomerAction extends DispatchAction { public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerForm customerForm = (CustomerForm) form; if (!isValid(form, mapping, request { CustomerForm.setCustomers(customerService.findAllCustomers()); return mapping.getInputForward(); } Customer customer = (Customer) customerForm.getCustomerBean().extract(); customerService.saveCustomer(customer,customerForm.getCustomerId())); return mapping.findForward(FORWARD_SUCCESS); } Stripes Framework, Slide 9 © Copyright 2009, Callista Enterprise AB
  • 10. The fundamentals – Event Handlers • Stripes responds to a request and invokes a method in the action bean – an event handler. • Action Bean method – has no parameters and returns a Resolution public class CustomerActionBean implements ActionBean { @Validate private Customer customer; public Resolution save() { customerManager.save(this.customer); return new ForwardResolution("/WEB-INF/pages/customers.jsp"); } ... } Stripes Framework, Slide 10 © Copyright 2009, Callista Enterprise AB
  • 11. Resolutions • Tells Stripes what to do next in a request • Examples: new ForwardResolution(”/WEB-INF/pages/my.jsp”); new ForwardResolution(AnotherActionBean.class,”someEvent”); new RedirectResolution(”/some/other.jsp”); new StreamingResolution(”application/pdf”,myStream); Stripes Framework, Slide 11 © Copyright 2009, Callista Enterprise AB
  • 12. The fundamentals • Action Beans & Event Handlers • URL Binding • Validation • Type Conversion and Formatters • JSP Tags & Layout Stripes Framework, Slide 12 © Copyright 2009, Callista Enterprise AB
  • 13. The Struts way – URL Binding struts-config.xml <action-mappings> <action path="/customer" type="org.springframework.web.struts.DelegatingActionProxy" scope="request" parameter="task" input=".customer.save" name="customerForm" validate="false"> <forward name="success" path="/customer.do?task=edit" redirect="true" /> <forward name="failure" path="/customer.do?task=list" redirect="true" /> </action> </action-mappings> Stripes Framework, Slide 13 © Copyright 2009, Callista Enterprise AB
  • 14. The fundamentals - URL Binding • By convention The action bean class: se.callistaenterprise.web.store.CustomerActionBean ...defaults to: http://myserver/mycontext/store/Customer.action Stripes Framework, Slide 14 © Copyright 2009, Callista Enterprise AB
  • 15. The fundamentals - URL Binding • Override using @UrlBinding @UrlBinding(”/customer/{$event}.html”) public class CustomerAction implements ActionBean { public Resolution save() { ... } } – Use this URL to trigger event: http://myserver/mycontext/customer/save.html Stripes Framework, Slide 15 © Copyright 2009, Callista Enterprise AB
  • 16. The fundamentals • Action Beans & Event Handlers • URL Binding • Validation • Type Conversion and Formatters • JSP Tags & Layout Stripes Framework, Slide 16 © Copyright 2009, Callista Enterprise AB
  • 17. The Struts way – Validation • Validation in action method, form bean, validator.xml and validator-rules.xml Action Class Form Bean public class CustomerAction extends DispatchAction { public class CustomerBeann extends ActionForm { public ActionForward save(ActionMapping mapping, public ActionErrors validate(ActionMapping mapping, ActionForm form, HttpServletRequest request) { HttpServletRequest request, ActionErrors actionErrors = new ActionErrors(); HttpServletResponse response) // validate credit throws Exception { if (credit > Credit.LIMIT) { actionErrors.add("credte", new ActionMessage("error.name")); CustomerForm customerForm = (CustomerForm) form; } // Validate form return actionErrors; if (!isValid(form, mapping, request { } CustomerForm. ... setCustomers(customerService.findAllCustomers()); return mapping.getInputForward(); } Customer customer = (Customer) customerForm. getCustomerBean().extract(); customerService.saveCustomer(customer, NumericUtils.toLong(customerForm.getCustomerId())); validator-rules.xml return mapping.findForward(FORWARD_SUCCESS); } <validator name="email" classname="org.apache.struts.validator.FieldChecks" method="validateEmail" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, validator.xml org.apache.commons.validator.Field, org.apache.struts.action.ActionMessages, org.apache.commons.validator.Validator, <form name="customerForm"> javax.servlet.http.HttpServletRequest" <field property="customerBean.customerId" depends="required"> depends="" msg="errors.email" /> <arg name="required" key="action.customer.customerId" position="0" /> </field> <field property="customerBean.customer.namn" depends="required"> <arg name="required" key="action.customer.namn" position="0" /> </field> <field property="customerBean.customer.email" depends="email"> <arg0 key="action.customer.email" /> </field> </form> Stripes Framework, Slide 17 © Copyright 2009, Callista Enterprise AB
  • 18. The fundamentals - Validation • Using @Validate (field,required,on,minlength,maxlength,expression,mask,minvalue,maxvalue, converter,trim,label,ignore,encrypted) @Validate(required=true,minlength=8, maxlength=32) private String password @Validate(required=true, expression=”this>=startDate”, converter=DateConverter.class) private Date endDate; @ValidateNestedProperties({ @Validate(field=”email” required=true, on=”save”), @Validate(field=”name” requried=true, on=”save”)}) private Customer customer; Stripes Framework, Slide 18 © Copyright 2009, Callista Enterprise AB
  • 19. The fundamentals - Validation • Custom validation with @ValidationMethod @ValidationMethod(on=”save”) public void validateCustomerUsername() { if(customerManager.usernameExists(customer.getUsername)){ // Add validation error } } Stripes Framework, Slide 19 © Copyright 2009, Callista Enterprise AB
  • 20. The fundamentals • Action Beans & Event Handlers • URL Binding • Validation • Type Conversion and Formatters • JSP Tags & Layout Stripes Framework, Slide 20 © Copyright 2009, Callista Enterprise AB
  • 21. The Struts way – Type conversion • Conversion in action class. CustomerAction.java ... CustomerForm customerForm = (CustomerForm) form; Customer customer = new Customer(); float credit = Float.parseFloat(customerForm.getCredit()); c.setCredit(credit); ... Customer.java private float credit; public float getCredit() {return credit;} public void setCredit(float credit) {this.credit=credit;} Stripes Framework, Slide 21 © Copyright 2009, Callista Enterprise AB
  • 22. The fundamentals – Type Conversion • Used for parameter binding • Built in converters for standard types (numericals, booleans, enums, email, credit card, one-to-many) • Write your own custom converter by implementing the TypeConverter<T> interface Stripes Framework, Slide 22 © Copyright 2009, Callista Enterprise AB
  • 23. The fundamentals – Type Conversion • Example - converting String to PhoneNumber MyActionBean.java @Validate(required=true, converter=PhoneNumberConverter.class) private PhoneNumber phoneNumber; PhoneNumberConverter.java public class PhoneNumberConverter implements TypeConverter<PhoneNumber> { @Override public PhoneNumber convert(String input, Class<? extends PhoneNumber> targetType, Collection<ValidationError> errors) { try { PhoneNumber phoneNumber = new PhoneNumber(input); return phoneNumber; } catch (IllegalArgumentException e) { errors.add(new ScopedLocalizableError("converter.phonenumber", "invalidPhoneNumber")); return null; } } ... } Stripes Framework, Slide 23 © Copyright 2009, Callista Enterprise AB
  • 24. The fundamentals – Formatters • Type conversion in the opposite direction • An object is converted to a String to be displayed to the user • Locale-sensitive • Write a custom formatter by implementing the Formatter interface • Best practice - use the same class to implement both TypeConverter and Formatter Stripes Framework, Slide 24 © Copyright 2009, Callista Enterprise AB
  • 25. The fundamentals • Action Beans & Event Handlers • URL Binding • Validation • Type Conversion and Formatters • JSP Tags & Layout Stripes Framework, Slide 25 © Copyright 2009, Callista Enterprise AB
  • 26. The Struts way – JSP tags • Example of a simple JSP: editCustomer.jsp <html:form action="/customer"> <html:errors /> <html:hidden property="customerId" /> <bean:message key=”customer.company” /> <html:select property="customerCompanyId"> <hmtl:optionsCcollection property="companies" value="id" label="name" /> </html:select> <bean:message key=”customer.name.and.phone” /> <html:text property="customer.name"/> <html:text property="customer.phoneNumber"/> </html:form> Stripes Framework, Slide 26 © Copyright 2009, Callista Enterprise AB
  • 27. The Fundamentals - JSP tags • JSP tags equivalent to Struts HTML tags • Uses the name attribute to bind a value to an action bean property • Labels from resource bundles • All HTML attributes editcustomer.jsp <stripes:form action="/customer.html"> <stripes:errors /> <stripes:hidden name="customer.id" /> <stripes:select name="customer.company.id"> <stripes:options-collection collection="${actionBean.companies}" value="id" label="name" /> </stripes:select> <stripes:text name="customer.name" style=”customerLabels” /> <stripes:text name="customer.phoneNumber" /> </stripes:form> Stripes Framework, Slide 27 © Copyright 2009, Callista Enterprise AB
  • 28. The Tiles way – JSP layout tiles-def.xml <tiles-definitions> <definition name=".layout" path="/WEB-INF/pages/layout/layout.jsp"> <put name="menu" value="/WEB-INF/pages/topmenu.jsp"/> struts-config.xml <put name="body" value="/WEB-INF/pages/start.jsp"/> <plug-in </definition> className="org.apache.struts.tiles.TilesPlugin"> <definition name=".customer.view" extends=".layout"> <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /> <put name="body" value="/WEB-INF/pages/customer/view.jsp"/> <set-property property="moduleAware" value="true" /> </definition> <set-property property="definitions-parser- <definition name=".customer.edit" extends=".layout"> validate" value="true" /> </plug-in> <put name="body" value="/WEB-INF/pages/customer/edit.jsp"/> <action path="/customer" </definition> type="org.apache.struts.actions.ForwardAction" <tiles-definitions> parameter="homepage"/> layout.jsp <html> <body> <tiles:insert attribute="menu"/> <tiles:insert attribute="body"/> </body> </html> edit.jsp <h1>On this page you can edit the view.jsp customer</h1> Stripes Framework, Slide 28 <h1>This page outputs the customer</h1> © Copyright 2009, Callista Enterprise AB
  • 29. The Fundamentals - JSP layout • No configuration • Concepts: Layout, Renderer, Component, Attributes • Three tags: layout-definition, layout-render, layout-component layout.jsp <stripes:layout-definition> <h1>${title}</h1> <stripes:layout-component name=”${menu}”/> My default menu</stripes:layout-component> <stripes:layout-component name=”body”/> </stripes:layout-definition> view.jsp (renderer) <stripes:layout-render name=”/WEB-INF/pages/layout.jsp” title=”View customer”> <stripes:layout-component name=”body”/> Output the customer..</stripes:layout-component> </stripes:layout-render> Stripes Framework, Slide 29 © Copyright 2009, Callista Enterprise AB
  • 30. More features • Web Flows • Interceptors • Localization, Messages and Validation Errors • Testing Stripes Framework, Slide 30 © Copyright 2009, Callista Enterprise AB
  • 31. The Struts Way – No flow • No mechanism in Struts for wizard-like functionality • Alternatives: Struts Flow (sandbox), Spring Web Flow • ..or by hand Stripes Framework, Slide 31 © Copyright 2009, Callista Enterprise AB
  • 32. The Stripes Wizard • The @Wizard annotation – generates hidden inputs for already submitted fields – keeps track of which fields are to be validated for each step @Wizard public class CustomerActionBean implements ActionBean { public Resolution view() {...} public Resolution save() {...} } Stripes Framework, Slide 32 © Copyright 2009, Callista Enterprise AB
  • 33. More features • Web Flows • Interceptors • Localization, Messages and Validation Errors • Testing Stripes Framework, Slide 33 © Copyright 2009, Callista Enterprise AB
  • 34. The Struts way – Interceptors • No real equivalent functionality in Struts CustomerAction.java public ActionForward view(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerForm customerForm = (CustomerForm) form; customerForm.setCustomer(customerService.findCustomer(customerForm.getId())); return mapping.findForward(FORWARD_SUCCESS_VIEW); } public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerForm customerForm = (CustomerForm) form; Customer customer = (Customer) customerForm.getCustomerBean().extract(); customerService.saveCustomer(customer); customerForm.setCustomer(customerService.findCustomer(customerForm.getId())); return mapping.findForward(FORWARD_SUCCESS_VIEW); } Stripes Framework, Slide 34 © Copyright 2009, Callista Enterprise AB
  • 35. Interceptors • Code that is executed before and/or after a life cycle stage • Two ways to intercept: – Before / After methods (applies to a specific action bean) – Global interceptor (intercepts all requests at given stages) EST R EQU G O MIN Request ActionBean Handler INC Init Resolution Resolution Binding And Validation Custom E P ON S Validation RES NG GOI OUT Request Resolution Event Complete Execution Handling Stripes Framework, Slide 35 © Copyright 2009, Callista Enterprise AB
  • 36. Interceptors T UE S R EQ NG OM I • Before and after methods Request ActionBean Handler INC Init Resolution Resolution Binding And – Add a method to an action bean Validation SE Custom – Annotate with @Before or @After GOI NG R ES P ON Validation OUT Request Resolution Event Complete Execution Handling @After(stages = LifecycleStage.BindingAndValidation, on = {"view”,”edit"}) public void populateCustomer() { customer = customerManager.findById(customer.getId()); } Stripes Framework, Slide 36 © Copyright 2009, Callista Enterprise AB
  • 37. Interceptors EST R EQU NG OM I Request ActionBean Handler INC • Global Interceptor Init Resolution Resolution Binding And Validation – Implement the Interceptor interface Custom E ONS ESP Validation and indicate life cycle stages OUT GOI N GR Request Resolution Event Complete Execution Handling } @Intercepts(LifecycleStage.EventHandlingResolution) public class AuditLogInterceptor implements Interceptor { public Resolution intercept(ExecutionContext context) throws Exception { logEventStarted(context); Resolution resolution = context.proceed(); logEventCompleted(context); return resolution; } } Stripes Framework, Slide 37 © Copyright 2009, Callista Enterprise AB
  • 38. More features • Web Flows • Interceptors • Localization, Messages and Validation Errors • Testing Stripes Framework, Slide 38 © Copyright 2009, Callista Enterprise AB
  • 39. The Struts way – I18n and messages • ApplicationResources.properties – single resource bundle • Use the struts-bean taglib: <bean:message key="app.name" /> • Use <html:errors/> and <html:messages/> to display validation errors and messages editCustomer.jsp <html:form action="/customer"> <html:errors /><br /> <bean:message key=”customer.label.name” /> <html:text property="customer.name"/> </html:form> Stripes Framework, Slide 39 © Copyright 2009, Callista Enterprise AB
  • 40. Localization, Messages & Validation Errors • Localization relies on standard ResourceBundles • JSTL with <fmt:message> for text • Application messages and validation errors by key: CustomerActionBean.java @ValidationMethod(on=”save”) public void validateCustomerUsername() { if(customerManager.usernameExists(customer.getUsername)){ getContext.getValidationErrors. add(new LocalizableError(”customer.invalid.username”,customer.getUsername()); } } editCustomer.jsp <stripes:form action="/customer.html"> <stripes:errors /><br /> <fmt:message key=”customer.name” /> <stripes:text name="customer.name" style=”customerLabels” /> </stripes:form> Stripes Framework, Slide 40 © Copyright 2009, Callista Enterprise AB
  • 41. More features • Web Flows • Interceptors • Localization, Messages and validation errors • Testing Stripes Framework, Slide 41 © Copyright 2009, Callista Enterprise AB
  • 42. The Struts way – Out of container testing • Struts TestCase on Sourceforge • Mock objects • Unit tests extends MockStrutsTestCase public class TestCustomerAction extends MockStrutsTestCase { public TestCustomerAction(String testName) { super(testName); } public void testSave() { setConfigFile("mymodule","/WEB-INF/struts-config.xml"); setRequestPathInfo("/customer.do"); addRequestParameter("task","save"); addRequestParameter("customer.email","NO_VALID_EMAIL_ADRESS"); actionPerform(); verifyForward("edit"); verifyActionErrors(new String[] {"error.invalid.email"}); } } Stripes Framework, Slide 42 © Copyright 2009, Callista Enterprise AB
  • 43. Automated testing • What? – Submit a form, validating response with any validation errors – Type conversion – URL Bindings – Interceptors • How? – Using mock objects for Session, Request, Response, ServletContext objects etc) – MockRoundtrip simulates requests to action beans Stripes Framework, Slide 43 © Copyright 2009, Callista Enterprise AB
  • 44. Test example @Test public void testEmailRequired() throws Exception { MockRoundtrip trip = new MockRoundtrip(mockServletContext, CustomerActionBean.class); trip.setParameter("customer.email", "NO_VALID_EMAIL_ADRESS"); trip.execute("save"); assertEquals(1, trip.getValidationErrors().size()); } Stripes Framework, Slide 44 © Copyright 2009, Callista Enterprise AB
  • 45. Wrapping up • Easy but still powerful MVC framework without the Struts caveats • Short learning curve for existing Struts developers – Manage in hours – control in a couple of days • 30% less code (at least) • Simplicity saves time • Good documentation • And yes the Stripes team's claim holds – Stripes really makes web application development easier. Stripes Framework, Slide 45 © Copyright 2009, Callista Enterprise AB
  • 46. As simple as that... Q&A Johannes Carlén johannes.carlen@callistaenterprise.se www.callistaenterprise.se Stripes Framework, Slide 46 © Copyright 2009, Callista Enterprise AB