SlideShare una empresa de Scribd logo
1 de 28
Presenting ActiveWeb making Java Web programming fun...again! Igor Polevoy
About me ,[object Object]
Have bad aftertaste of many web frameworks
Presented ActiveJDBC to CJUG last year at about the same time
Was suggested to shut up and make a change
Currently a Chief Technologist at ProductiveEdge, Chicago
But why? Don't we have enough frameworks in Java? Restlet Brill Aranea Web Framework RSF JSF RichFaces Strecks Google Web Toolkit Aurora JPublish Jucas MyFaces WebOnSwing Chrysalis VRaptor SwingWeb Barracuda ThinWire Struts1/2 Turbine Tapestry Cocoon Spring Maverick Echo SOFIA Verge Anvil Jaffa Japple RIFE Swinglets  Millstone  Wicket  DWR  JSPWidget  JOSSO JAT  OpenXava  Stripes  Click  ZK  Caramba  wingS  Helma
All we need is: ,[object Object]
Full stack
Supporting TDD
Can test views
Dynamic
Clean URLs
Fast, lightweight (as few dependencies as possible)
Conforms to (few good) standards
Fun(because of immediate gratification)
History ,[object Object]
In parallel development with ActiveJDBC
First put in production in summer 2010
Currently in production at major insurance company, 4 websites, clustered REST web services, internal tools, displacing legacy systems (Spring/Hibernate)
Meet new friend Navigate  to: http://localhost:8080/testapp/greeting?name=Bob Executes: public   class   GreetingController   extends   AppController{ public   void   index(){ view(“name”, param(“name”)); } } Renders: /WEB-INF/views/greeting/index.ftl View code: Hello, ${name}! Output: Hello, Bob! A few conventions at work here:  URL to Controller Default action view location by controller name view name by action name No configuration.  In fact, ActiveWeb has no property files, no XML, no Yaml, no text files of any kind.
Lets TDD this public   cla ss  G r eetingControllerSpec   extends   ControllerSpec{ @Test public   void   shouldRenderHelloWorld(){ request().param(“name”, “Bob”).get(“index”); a(assigns().get(“name”)).shouldBeEqual(“Bob”); } } Test HTML content: public   class  G reet ingControllerSpec   extends   ControllerSpec{ @Test public   void   shouldRenderHelloWorld(){ request().param(“name”, “Bob”). integrateViews () .get(“index”); a(responseContent().contains(“Hello,   Bob!”)).shouldBeTrue(); } } Convention at work: Controller name from spec name.
Configuration in code public   class   DbConfig   extends   AbstractDBConfig   { public   void   init(AppContext   context)   { environment( "development" ) .jndi( "jdbc/kitchensink_development" ); environment( "development" ).testing() .jdbc( "com.mysql.jdbc.Driver" ,   "jdbc:mysql://localhost/kitchensink_development"  ,   "root" ,   "****" );   environment( "hudson" ).testing() .jdbc( "com.mysql.jdbc.Driver" ,   "jdbc:mysql://172.30.64.31/kitchensink_hudson",  "root", "****" ); environment( "production" ) .jndi( "jdbc/kitchensink_production" ); } } DSL for environments, JNDI, JDBC and testing mode You get help from IDE and from compiler, less likely to make a typo
Structure of project Standard Maven structure,  ,[object Object],Result: Huge selection of anything built under the  sun for Maven in general and Maven Web  specifically
Layouts Default Layout: src/main/webapp/WEB-INF/views/layouts/default_layout.ftl < html > < head > < LINK   href = &quot;${context_path}/css/main.css&quot;   rel = &quot;stylesheet&quot; /> < script   src = &quot;${context_path}/js/jquery-1.4.2.min.js&quot; </ script > < script   src = &quot;${context_path}/js/aw.js&quot; </ script > < title > ActiveWeb -  < @yield   to = &quot;title&quot; /></ title > </ head > < body > < div   class = &quot;main&quot; > < #include   &quot;header.ftl&quot;   > ${page_content}  < #include   &quot;footer.ftl&quot;   > </ div > </ body > </ html > Serves the same purpose as Tiles or Sitemesh, but integrated into the  system as another template. There are wrapper/nested layouts too.
<@content for and <@yield Page titles with custom tags < @content   for = &quot;title&quot; > Books List </@content> This sends content to  < @yield   to = &quot;title&quot; />  located in layout Can send any content to layout with content tag, including links to CSS, JS, etc: < @content   for = &quot;js&quot; > < script   src = &quot;${context_path}/js/page_specific.js&quot;   type = &quot;text/javascript&quot; ></ script > </ @ > Content will be rendered in layout in place of  < @yield   to = &quot;js&quot; /> This allows to easily declare content specific for a page, but rendered outside  page context.
Unobtrusive JS and <@link_to < form   id = &quot;da_form&quot;   > First name:  < input   type = &quot;text&quot;   name = &quot;first_name&quot; >< br > Last name:  < input   type = &quot;text&quot;   name = &quot;last_name&quot; >   </ form > < @link_to   controller = &quot;people&quot;   action = &quot;do-get&quot;   form = &quot;da_form&quot;   destination = &quot;result&quot; > Ajax Get </ @ > Result will be inserted into: < div   id = &quot;result&quot; ></ div > No JavaScript is generated, the HTML page is clean More ways to use Ajax with  link_to Magic happens in   aw.js
Partials Naming src/main/webapp/WEB-INF/views/greeting/_hello.ftl Rendering a partial: < @render   partial = &quot;hello&quot; /> Rendering a collection with a partial (no ugly for loops building iterative HTML): Content of  _fruit.ftl :  Fruit name: ${fruit}<hr> Host page: < @render   partial = &quot;fruit&quot;   collection = fruits /> Result of rendering: Fruit name: apple<hr>Fruit name: prune<hr>Fruit name: pear<hr> Partial will iterate itself. Also: spacers, counters, first and last.

Más contenido relacionado

La actualidad más candente

Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
Dmitry Buzdin
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
Ankur Dongre
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi
 
Introduction to hibernate
Introduction to hibernateIntroduction to hibernate
Introduction to hibernate
hr1383
 

La actualidad más candente (19)

jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practices
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
 
Html 5 in a big nutshell
Html 5 in a big nutshellHtml 5 in a big nutshell
Html 5 in a big nutshell
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Djangocon 2014 angular + django
Djangocon 2014 angular + djangoDjangocon 2014 angular + django
Djangocon 2014 angular + django
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
前端概述
前端概述前端概述
前端概述
 
Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]Fundamental JavaScript [In Control 2009]
Fundamental JavaScript [In Control 2009]
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
Introduction to hibernate
Introduction to hibernateIntroduction to hibernate
Introduction to hibernate
 

Similar a ActiveWeb: Chicago Java User Group Presentation

Intro To Mvc Development In Php
Intro To Mvc Development In PhpIntro To Mvc Development In Php
Intro To Mvc Development In Php
funkatron
 
Strutsjspservlet
Strutsjspservlet Strutsjspservlet
Strutsjspservlet
Sagar Nakul
 

Similar a ActiveWeb: Chicago Java User Group Presentation (20)

Jsp
JspJsp
Jsp
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
Introducing Struts 2
Introducing Struts 2Introducing Struts 2
Introducing Struts 2
 
Introduction To ASP.NET MVC
Introduction To ASP.NET MVCIntroduction To ASP.NET MVC
Introduction To ASP.NET MVC
 
Basic testing with selenium
Basic testing with seleniumBasic testing with selenium
Basic testing with selenium
 
Intro To Mvc Development In Php
Intro To Mvc Development In PhpIntro To Mvc Development In Php
Intro To Mvc Development In Php
 
Retrofitting
RetrofittingRetrofitting
Retrofitting
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
Struts2
Struts2Struts2
Struts2
 
Struts,Jsp,Servlet
Struts,Jsp,ServletStruts,Jsp,Servlet
Struts,Jsp,Servlet
 
Strutsjspservlet
Strutsjspservlet Strutsjspservlet
Strutsjspservlet
 
Strutsjspservlet
Strutsjspservlet Strutsjspservlet
Strutsjspservlet
 
Grails and Dojo
Grails and DojoGrails and Dojo
Grails and Dojo
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Developing and testing ajax components
Developing and testing ajax componentsDeveloping and testing ajax components
Developing and testing ajax components
 
Spring Surf 101
Spring Surf 101Spring Surf 101
Spring Surf 101
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 

ActiveWeb: Chicago Java User Group Presentation

  • 1. Presenting ActiveWeb making Java Web programming fun...again! Igor Polevoy
  • 2.
  • 3. Have bad aftertaste of many web frameworks
  • 4. Presented ActiveJDBC to CJUG last year at about the same time
  • 5. Was suggested to shut up and make a change
  • 6. Currently a Chief Technologist at ProductiveEdge, Chicago
  • 7. But why? Don't we have enough frameworks in Java? Restlet Brill Aranea Web Framework RSF JSF RichFaces Strecks Google Web Toolkit Aurora JPublish Jucas MyFaces WebOnSwing Chrysalis VRaptor SwingWeb Barracuda ThinWire Struts1/2 Turbine Tapestry Cocoon Spring Maverick Echo SOFIA Verge Anvil Jaffa Japple RIFE Swinglets Millstone Wicket DWR JSPWidget JOSSO JAT OpenXava Stripes Click ZK Caramba wingS Helma
  • 8.
  • 14. Fast, lightweight (as few dependencies as possible)
  • 15. Conforms to (few good) standards
  • 16. Fun(because of immediate gratification)
  • 17.
  • 18. In parallel development with ActiveJDBC
  • 19. First put in production in summer 2010
  • 20. Currently in production at major insurance company, 4 websites, clustered REST web services, internal tools, displacing legacy systems (Spring/Hibernate)
  • 21. Meet new friend Navigate to: http://localhost:8080/testapp/greeting?name=Bob Executes: public class GreetingController extends AppController{ public void index(){ view(“name”, param(“name”)); } } Renders: /WEB-INF/views/greeting/index.ftl View code: Hello, ${name}! Output: Hello, Bob! A few conventions at work here: URL to Controller Default action view location by controller name view name by action name No configuration. In fact, ActiveWeb has no property files, no XML, no Yaml, no text files of any kind.
  • 22. Lets TDD this public cla ss G r eetingControllerSpec extends ControllerSpec{ @Test public void shouldRenderHelloWorld(){ request().param(“name”, “Bob”).get(“index”); a(assigns().get(“name”)).shouldBeEqual(“Bob”); } } Test HTML content: public class G reet ingControllerSpec extends ControllerSpec{ @Test public void shouldRenderHelloWorld(){ request().param(“name”, “Bob”). integrateViews () .get(“index”); a(responseContent().contains(“Hello, Bob!”)).shouldBeTrue(); } } Convention at work: Controller name from spec name.
  • 23. Configuration in code public class DbConfig extends AbstractDBConfig { public void init(AppContext context) { environment( &quot;development&quot; ) .jndi( &quot;jdbc/kitchensink_development&quot; ); environment( &quot;development&quot; ).testing() .jdbc( &quot;com.mysql.jdbc.Driver&quot; , &quot;jdbc:mysql://localhost/kitchensink_development&quot; , &quot;root&quot; , &quot;****&quot; ); environment( &quot;hudson&quot; ).testing() .jdbc( &quot;com.mysql.jdbc.Driver&quot; , &quot;jdbc:mysql://172.30.64.31/kitchensink_hudson&quot;, &quot;root&quot;, &quot;****&quot; ); environment( &quot;production&quot; ) .jndi( &quot;jdbc/kitchensink_production&quot; ); } } DSL for environments, JNDI, JDBC and testing mode You get help from IDE and from compiler, less likely to make a typo
  • 24.
  • 25. Layouts Default Layout: src/main/webapp/WEB-INF/views/layouts/default_layout.ftl < html > < head > < LINK href = &quot;${context_path}/css/main.css&quot; rel = &quot;stylesheet&quot; /> < script src = &quot;${context_path}/js/jquery-1.4.2.min.js&quot; </ script > < script src = &quot;${context_path}/js/aw.js&quot; </ script > < title > ActiveWeb - < @yield to = &quot;title&quot; /></ title > </ head > < body > < div class = &quot;main&quot; > < #include &quot;header.ftl&quot; > ${page_content} < #include &quot;footer.ftl&quot; > </ div > </ body > </ html > Serves the same purpose as Tiles or Sitemesh, but integrated into the system as another template. There are wrapper/nested layouts too.
  • 26. <@content for and <@yield Page titles with custom tags < @content for = &quot;title&quot; > Books List </@content> This sends content to < @yield to = &quot;title&quot; /> located in layout Can send any content to layout with content tag, including links to CSS, JS, etc: < @content for = &quot;js&quot; > < script src = &quot;${context_path}/js/page_specific.js&quot; type = &quot;text/javascript&quot; ></ script > </ @ > Content will be rendered in layout in place of < @yield to = &quot;js&quot; /> This allows to easily declare content specific for a page, but rendered outside page context.
  • 27. Unobtrusive JS and <@link_to < form id = &quot;da_form&quot; > First name: < input type = &quot;text&quot; name = &quot;first_name&quot; >< br > Last name: < input type = &quot;text&quot; name = &quot;last_name&quot; > </ form > < @link_to controller = &quot;people&quot; action = &quot;do-get&quot; form = &quot;da_form&quot; destination = &quot;result&quot; > Ajax Get </ @ > Result will be inserted into: < div id = &quot;result&quot; ></ div > No JavaScript is generated, the HTML page is clean More ways to use Ajax with link_to Magic happens in aw.js
  • 28. Partials Naming src/main/webapp/WEB-INF/views/greeting/_hello.ftl Rendering a partial: < @render partial = &quot;hello&quot; /> Rendering a collection with a partial (no ugly for loops building iterative HTML): Content of _fruit.ftl : Fruit name: ${fruit}<hr> Host page: < @render partial = &quot;fruit&quot; collection = fruits /> Result of rendering: Fruit name: apple<hr>Fruit name: prune<hr>Fruit name: pear<hr> Partial will iterate itself. Also: spacers, counters, first and last.
  • 29. Lets flash public class BooksController extends AppController { @POST public void create(){ Book book = new Book(); book.fromMap(params1st()); if (book.save()){ flash( &quot;message&quot; , &quot;New book was added: &quot; + book.get( &quot;title&quot; )); redirect(BooksController. class ); } else { //handle errors } } } //Use in view: < @flash name = &quot;message&quot; /> Flash is a short-lived object, survives only one more request Use in POST/redirect for destructive operations
  • 30. Custom tags 1. Develop: public class HelloTag extends FreeMarkerTag{ protected void render(Map params, String body, Writer writer) throws Exception { writer.write(“hello”); } } 2. Register: public class FreeMarkerConfig extends AbstractFreeMarkerConfig { public void init() { registerTag(“hello”, new HelloTag()); } } 3. Use: < @hello />
  • 31. Dependency Injection with Google Guice public class HelloController extends AppController { private Greeter greeter; public void index(){ view( &quot;message&quot; , greeter.greet()); } @Inject public void setGreeter( Greeter greeter) { this .greeter = greeter; } } public class GreeterModule extends AbstractModule { protected void configure() { bind(Greeter. class ) .to(GreeterImpl. class ).asEagerSingleton(); } } public class AppBootstrap extends Bootstrap { public void init(AppContext context) { setInjector(Guice.createInjector( new GreeterModule())); } }
  • 32. TDD with DI public class GreeterMock implements Greeter{ public String greet() { return &quot;Hello from &quot; + getClass().toString(); } } public class GreeterMockModule extends AbstractModule { @Override protected void configure() { bind(Greeter. class ).to(GreeterMock. class ).asEagerSingleton(); } } public class HelloControllerSpec extends ControllerSpec { @Before public void before(){ setInjector(Guice.createInjector( new GreeterMockModule())); } @Test public void shouldTestWithMockService(){ request().get( &quot;index&quot; ); a(assigns().get( &quot;message&quot; )).shouldBeEqual( &quot;Hello from class app.services.GreeterMock&quot; ); } } Can use any mocking framework.
  • 33. Making tests web specific “ Send” parameters to controller: public class HelloControllerSpec extends ControllerSpec{ @Test public void shouldSendParamsToIndex(){ request() .param( &quot;first_name&quot; , &quot;John&quot; ).param( &quot;last_name&quot; , &quot;Deere&quot; ) .get( &quot;index&quot; ); a(assigns().get( &quot;message&quot; )) .shouldBeEqual( &quot;Hello, John Deere, welcome back!&quot; ); } } Seeing HTML in test! public class HelloControllerSpec extends ControllerSpec @Test public void shouldPrintGeneratedHTML(){ request(). integrateViews ().get( &quot;index&quot; ); System.out.println(responseContent()); // prints entire HMTL, decorated by layout. } }
  • 34.
  • 37. “ Send” GET, POST, DELETE, PUT HTTP requests
  • 40. Controller scenarios with IntegrationTests.
  • 41. Bootstrap entire application with AppIntegrationTests
  • 42. REST web services Controller: public class Books Controller extends AppController { public void index(){ List<Book> books = Book.findAll(); view( &quot; books&quot;, books); render().noLayout(); } } View: <? xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> < books > < #list books as book > < book > < isbn > ${book.isbn} </ isbn > < title > ${book.title} </ title > < author > ${book.author} </ author > </ book > </ #list > </ books > Access: http://host:port/context/books
  • 43. What else can controllers do? //getting parameters String name = param(“name”); List<String> selectValues = param(“myselect”); List<String> params = params1st(); Map<String, String[]> allParams = params(); //passing data to view view(“name”, name); assign(“name”, name); //detecting Ajax: if (xhr()){...} else {...} //Responding directly (short hand XML service): respond( &quot;<message>hello</message>&quot; ) .contentType( &quot;text/xml&quot; ).status( 200 ); //sending view with no layout //(useful in web services when a view is used): render().noLayout();
  • 44. Binary content in controllers //Downloading binary to client: sendFile(f).contentType( &quot;application/pdf&quot; ).status( 200 ); //Streaming large content: streamOut(in).contentType( &quot;applicaiton/pdf&quot; ); //Uploading files: Iterator<FormItem> iterator = uploadedFiles(); while (iterator.hasNext()){ FormItem item = iterator.next(); name = item.getName(); if (item.isFile()){ InputStream in = item.getInputStream()); //process data } }
  • 45. @RESTful routing @RESTful public BooksController extends AppController{} verb path action used for ------------------------------------------------------------------------------------- GET /books index display a list of all books GET /books/new_form new_form HTML form for creating a new book POST /books create create a new book GET /books/id show display a specific book GET /books/id/edit_form edit_form return an HTML form for editing a books PUT /books/id update update a specific book DELETE /books/id destroy delete a specific book
  • 46. Standard routing public BooksController extends AppController{ //GET by default public void index(){} @PUT public void save(); @DELETE public void delete(); @POST public void update(); } Allows only one HTTP method per action
  • 47. GWT Support Compile GWT client.... and PRC server on the fly: GWT server: public class EchoController extends GWTAppController implements EchoService { public String echo(String text) { return &quot;Hello from server :&quot; + text + &quot;,.... and time now is: &quot; + new Date() ; } } GWT client: business as usual GWT DEMO
  • 48.
  • 55.
  • 56. ActiveJDBC is a general purpose ORM for Java
  • 57. ActiveWeb can be used with any other ORM, or without one
  • 58. ActiveWeb has nice features for managing a DB connection at runtime and during tests – tailored for ActiveJDBC, but in either case you can get access to java.sql.Connection and do with it as you wish:
  • 59. java.sql.Connection con = Base.connection();
  • 60.
  • 62. Have access to anything Java under the sun (there is a lot)