29 July 2012

Programmatic servlet configuration

Servlet 3 allows you to configure your webapplication in Java.
A set of methods have been added to ServletContext to support this, e.g.

  • addFilter
  • addListener
  • addServlet
When your application starts, you can call these methods from a  ServletContextListener:
@WebListener
public class MyServletContextListener implements ServletContextListener {
  public void contextInitialized(ServletContextEvent event) {
    ServletContext ctx = event.getServletContext();
    ServletRegistration servlet = ctx.addServlet ("ProServlet","org.edu.ProServlet");   
    servlet.addMapping("/dyna/*");
  }
  public void contextDestroyed(ServletContextEvent event) {}
}
After the ServletContext is initialised, you can't call these methods anymore.

Servlet listeners

Scope Lifecycle listeners Attribute change listeners Register
Application ServletContextListener ServletContextAttributeListener @WebListener
Servlet HttpServlet @PostConstruct
@PreDestroy
Session HttpSessionListener HttpSessionAttributeListener @WebListener
Request ServletRequestListener ServletRequestAttributeListener @WebListener
Asynchronous Request AsyncListener AsyncContext#addListener

What’s new in Servlet 3 (edit)

Servlets 3 (JSR 315) highlights:

  • Instead of configuring the web application in the web.xml deployment description you now have more options
    • modular deployment descriptor
      jars can be bundled with your webapp containing a web-fragment.xml file. These files are merged with the main web.xml file of your webapp. This allows for easy plugging in of web application modules. If you plugin a framework jar, you won’t have to modify the web.xml of your application anymore (e.g. to send all *.do files to a framework servlet).
    • annotations
      @WebServlet ("/jeeves")
      public class ZServlet extends HttpServlet {
      ....
      }
      • Extends HttpServlet, no POJO (yes!)
    • programmatic configuration
    • Asynchronous servlets
      @WebServlet ("/jeeves", asyncSupported=true) 
      public class ZServlet extends HttpServlet { 
      private AsyncContext ctx
      
      public void doGet( HttpServletRequest req, HttpServletResponse res) { 
      
         ctx = req.startAsync(); 
        // kick off a thread for async work
        ctx.start(new L8r());
        //method returns immediatly, no response sent
      } // end doGet method
      
      class L8r implements Runnable{
         public void run(){
          // do work
          ...
          // response ready
          ctx.complete();
          // alternative: ctx.dispatch("responseViewer.jsp");
        } // end run method
       } //end L8r class
      } //end ZServlet class

      The asynchronous servlet doGet() method does not wait for the L8r thread to complete. The request/response parameters however are not committed, but they are cached in AsyncContext. The L8r thread can then use these to reply to the waiting client.
    • Security
      • ProgrammaticLogin class
      • Java EE5 authorisation annotations
        • @RolesAllowed
        • @PermitAll
        • @DenyAll
      • @transportprotected: use SSL
      • Session security
      • <session-config>
        <!-- do not expose session id by using URL rewriting --> 
          <tracking-mode>COOKIE</tracking-mod>
          <cookie-config>
            <!-- do not expose cookie to javascript-->
            <http-only>true</ttp-only>
            <!-- only transit cookie over encrypted connection-->
            <secure>true</secure>
          </cookie-config>
        </session-config>
        
    • EL 2.2
      Method calls are now possible from EL, e.g.:
        #{portfolio.add('ORCL',100)}

    • File upload (aka multipart support) 

    26 July 2012

    Web components: extra exercises

    Module 3 Exercise 2 (extra): a DAO model

    1. Extend the Anniversary class with an extra attribute: flowers
    2. Add the following files with a new model to the project: AnniversaryMemoryDao with interface AnniversaryDao
    3. Modify the  AnniversaryControl servlet
      1.  Instantiate an AnniversaryDao
        AnniversaryDao dao = AnniversaryMemoryDao.getAnniversaryDAO();
      2. Use anniversaryDao as the model
    4. Modify the JSP to show the flowers you get at the anniversary
    5. (Optional) Create a trivial unit test for the model
      1. Right click the project and select New > Other... > Unit TestsTest Packages  > JU Test for existing class
        1. Browse to the AnniversaryDao class
        2. Click Finish
      2. In the generated Test class
        1. Remove the TestGetAnniversaryDao class
        2. In the testGetByYear method
          1.  Create an AnniversaryDao instance like you did in the Controller servlet
          2. Supply an anniversary year to the getByYear method
          3. Modify the assertEquals method
            1. As a first argument type the name of the flowers matching the anniversary year
            2. As a second argument call the getFlowers method
          4. Add another assertEquals method testing the material
          5. Remove the fail method at the end of the test
        3. In the project window, right click the AnniversaryMemoryTest class and select Test File

    Module 4 Exercise 2 (extra): working with sessions

    1.      Add a “Set colour preferences” link to the Anniversary application index page
    a.    The link should take the user to a colourpicker web page.
    2.      Create the ColourPicker web page, that shows a drop down list with some of these colours:
    a. Aqua Black Blue Fuchsia Gray Green Lime Maroon Navy Olive Purple Red Silver Teal Yellow
      (these are HTML color names defined in the HTML 3 standard)
    b.   Add an OK button that takes you to the ColourControl servlet
    3.      Create the ColourControl servlet. In the servlet
    1. Save the colour in the session
    2. Go back to the home page
    4.      On the showAnniversary.jsp, show the text in the chosen colour. If there is no chosen colour, use black. 

     Hints:

    HTML font tag example: <font color=”Black">  See the difference? </font>
    EL ternary expression example ${aVariable == “”?”empty”:bVariable}

    Module 5 Exercise 2 (extra): Default Colour

    1. Specify an initialization parameter with a default colour for the ColourControl servlet.
    2. Save the value in a session attribute
    3. Use the session attribute to set this colour as the default selected colour in the drop down list in the colourpicker page
    4. Test your application.
    5. The first time you go to the page the default colour is not selected. If you choose a colour and go back to the page the default colour is selected. Explain this behaviour.

    Hint: HTML to set an option as the selected option:

      <option selected>Peach</option>

    Module 6 Exercise 1 Task 2 (extra): Display multivalued headers

    Write a version of the HTTP Headers list that is capable of displaying headers with multiple values

    Module 6 Exercise 3 (extra): Call methods from EL

    1. Add a method calculateWeddingYear() to the Anniversary class in the wedding anniversary project.
    2.  Add a message to showAnniversary.jsp: You were married in the year xxxx!
    3. Test the project and correct any errors until you have the expected result.
    4. Optional: If the AnniversaryMemoryDao does not have an anniversary (e.g. 100) in its list it will return an Anniversary object where the material is empty. Show the message with material and flowers only if you have found an Anniversary object with a material. Show the message with the year of marriage only if you have found an Anniversary object with an empty material.

     

    Module 8 Exercise 3 (extra): Count headers

    Change Module 6 exercise 1 to display the number of headers on top of the list.

     

    Module 8 Exercise 4 (extra): Colourpicker

    Modify the colourpicker in the anniversary project:
    1. supply the colours as a comma separated string: aqua,black,blue,fuchsia gray,green,lime,maroon,navy,olive,purple,red,silver,teal,yellow.
    2. generate the choice menu using a foreach loop
    3. Optional: When you return to the picker the previously chosen color should be selected by default.

     

    Module 8 Exercise 5 (extra): Write a jspx document

    1. Copy index.jsp from Module 6 exercise 1 to index.jspx.
    2. Modify the code to be compliant with a jspx document.
    Solution.

     

    Module 10 Exercise 2 (extra): AnniversaryJpaDao

    In the wedding anniversary project, add a AnniversaryJpaDao.
    1. Create the AnniversaryJpaDao class that implements the AnniversaryDao interface
      1. Add a constructor that takes an EntityManagerFactory as an argument.
      2. Implement the interface methods
        1. In the methods create an EntityManager:
          Entitymanager em = emf.createEntityManager();
        2. Use the EntityManager to access the database.
        3.  Adapt the AnniversaryControl servlet to use the AnniversaryJpaDao.
        4. Inject an EntityManagerFactory in the AnniversaryControl
          @PersistenceUnit private EntityManagerFactory emf;
        5. When the servlet is created, create the AnniversaryJpaDao and assign it to an AnniversaryDao attribute.
        6. Remove any reference to other AnniversaryDao implementations.
    2. Change the Anniversary class into a JPA Entity. 
      1. Use the year as a primary key.
    3.  Create a persistence unit in the project, use an existing glassfish DB resource
    4. Run the project.
      1. Ignore any errors that complain that the Anniversary table already exists.
      2. Correct other errors
    5. Enter the flowers entries into the database
      1.  Collect database characteristics
        1. In the services tab, right click Servers> GlassFish Server> Resources> JDBC> JDBC Resources
        2. Right click the database you used in the project, and select Properties
        3. Write down the Pool Name
        4. Rght click Servers> GlassFish Server> Resources> JDBC> Connection Pools
        5. Right click the pool name you found and select properties
        6. Write down the properties
      2. Create a connection to the database in Netbeans
        1.  Right click the Databases tab and select New Connection...
        2. Select a Java DB (Network) driver and click Next>
        3. Enter the properties of the server database
        4. Append to the JDBC URL
           ;create=true
        5.  Click Finish
      3. Insert the entries
        1. Right click the database connection you created an select Connect...
        2. Right click the database connection you created an select Execute Command...
        3. Copy the contents of this file into the window
        4. Right click in the window and select Run File
    6. Test the application. Verify that all entries returned from the database are in CAPITALS.

    12 July 2012

    Java EE Applications: Calling a JSF page from a non-JSF page

    Lab 6 replaces the CustomerController servlet with the ustomerDetails.xhtml JSF page.
    Existing JSP pages need to be adapted to call the JSF page. Here's how you call a JSF page from a JSP or plain HTML page and pass a parameter to it.

    1. Change the AllCustomers.jsp page to call the JSF page.
      • Existing call to the servlet
      •  <a href="CustomerController?customerIdentity=<%= customers[i].getId()%>&submit=Get Customer">
      • New call to the JSF page
      • <a href="CustomerDetails.xhtml?customerIdentity=<%= customers[i].getId()%>">  
      • Change the JSF backing bean to receive parameters and call code when it is created by a GET request.
        1. Receive a GET parameter in an attribute
        2. @ManagedBean(name="customerDetails")
          @RequestScoped
          public class CustomerManagedBean {
          
             @ManagedProperty("#{param.customerIdentity}")
             private String customerId = "";
             ...
          }
        3. Call a method when the bean is created. The method looks up data using the value stored in the attribute in the previous step.
        4. @PostConstruct
          public void initCustomer() {
            if (customerId != null && customerId.length()!= 0){
              retrieveCustomer();
            }
          }
          

    4 July 2012

    iGoogle to retire

    Google will retire their personalised home page iGoogle on 11/2013.
    This was a pretty neat service combining RSS feeds, overview of discussion groups and financial portfolio's. You had nice gadgets like currency convertors and art of the day, all embedded in changing themes (comics, travel photo's...).
    The logic behind this is not clear to me. There will be some cost shavings, but i can not imagine that iGoogle is that expensive.
    Google encourages you to use Android and Chrome as a replacement. Android has nothing to do with desktops so they may be wanting to push Chrome. Strange: retiring a service is not encouraging for using another service of that same company.
    There will be some collateral damage too: iGoogle gadgets pushed you towards Google discussion groups, Google Finance etc.
    So it's back to My Yahoo for me, which is close, but not as slik.
    Maybe I should start preparing for WordPress as well...