Friday, October 26, 2012

Mapping SQL parameters with Spring's BeanPropertySqlParameterSource

If you don't use Spring for your J2EE web application database connectivity, then you should really check it out.

If, instead, you are already using, maybe you don't know a really nice object i discovered some time ago: the BeanPropertySqlParameterSource

The classic way to go in a query (or in an update) is to set the params one by one;
let's take this Person bean as example (id field omitted in this example):

 
 public class Person {         private String name;     private String lastname;     private Date birthdate;     private Language motherTongue;        /* Getters and Setters */        public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public String getLastname() {         return lastname;     }     public void setLastname(String lastname) {         this.lastname = lastname;     }     public Date getBirthdate() {         return birthdate;     }     public void setBirthdate(Date birthdate) {         this.birthdate = birthdate;     }     public Language getMotherTongue() {         return motherTongue;     }     public void setMotherTongue(Language motherTongue) {         this.motherTongue = motherTongue;     } }  

and the Language class referenced in it:

 
class Language {     int id;     int description;         /* Getters and Setters */     public int getId() {         return id;     }     public void setId(int id) {         this.id = id;     }     public int getDescription() {         return description;     }     public void setDescription(int description) {         this.description = description;     }    }  



(with Language values like this: {[1 , English] , [2 , Italian], etc...}


Let's say i've filled all the fields in the Person object, and i want to insert it into a database.
Its instance is named "person". Normally i would go with:

 
String sql = "INSERT INTO person_table " +              " ( name, lastname, birthday, id_language) " +              " VALUES " +              " ( :name, :lastname, :birthdate, :idLanguage) ";        MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("name", person.getName(), Types.VARCHAR); params.addValue("lastname", person.getLastname(), Types.VARCHAR); params.addValue("birthdate", person.getBirthdate(), Types.DATE); params.addValue("idLanguage", person.getLanguage().getId(), Types.NUMERIC); return namedJdbcTemplate.update(sql, params);  

Imagine a big bean with a lot of fields, with every field passed manually... it's not really a good way to go.

With the BeanPropertySqlParameterSource object instead, IF we are taking all the fields from one object (and his inner objects), we can do like this:

 
String sql = "INSERT INTO person_table " +              " ( name, lastname, birthday, id_language) " +              " VALUES " +              " ( :name, :lastname, :birthdate, :language.id) "; BeanPropertySqlParameterSource params = new BeanPropertySqlParameterSource(person); return namedJdbcTemplate.update(sql, params);  

Not bad uh ? It will retrieve the specified fields (and types) through Reflection, including the fields value  in the inner objects contained in the main bean. As you can note, the notation is OGNL-like, with the getter of the inner object starting with a dot and a lower case letter, stripping "get" from the method name:

:language.id
means
person.getLanguage().getId();

PRO:
  • less code;
  • auto-decoding field Type through Reflections, avoiding user errors;
  • changes on query or bean automatically managed, without the needs of change param settings

CONS:
  • less customization possibilities


Enjoy

Wednesday, September 12, 2012

HTML5 - Change the URL without reloading the page

With HTML5 (compliant browsers), it is now possible to alter the URL in the address bar without reloading the page.
 This can be quite handy in many situations...
to try it quickly, run this script after the page is loaded:

 window.history.pushState("","", "heyIJustChangedMyUrlWithoutPosting");

To learn more, refer to:

A) The original article ;

 B) StackOverflow Post 1 and Post 2 ;

C) The Official W3C documentation .


 HTML5 is revealing its beauty every day a bit more!

Tuesday, September 11, 2012

Art and technology: visit the Sistine Chapel and the Uffizi Gallery in a click

I visited this places for real, years ago, and believe me, they're absolutely stunning.
But, if you are curious about them, and want to take a look without having to come to Italy,
just visit this sites and enjoy ;)


Sistine Chapel - 3D reproduction


More on the Sistine Chapel: http://en.wikipedia.org/wiki/Sistine_Chapel


The Uffizi Gallery - visit everything !!


More on the Uffizi Gallery: http://en.wikipedia.org/wiki/Uffizi




Thursday, August 16, 2012

Struts2 - Write your own Interceptor for Session checking

Interceptor Model is another great feature of Struts2.

Interceptors are similar to Servlet Filters (actually, both of them are based on intercepting filter),but more configurable and powerful (note that they need to be Thread-Safe).

SHORT STORY
Basically, every request to an Action is filtered through an Interceptor Stack, a specific list of Interceptors for that specific Action.
Any Interceptor performs some simple operations, then decides if the request can proceeds down the stack, to the next Interceptor (or to the Action, if we're on the last Interceptor), or it has to be redirected (back, or) somewhere else.
When not specified, a request passes through the DEFAULT INTERCEPTOR STACK, that covers most of the needs we may have.
But when our page has specific requirements, we can use a CUSTOM INTERCEPTOR STACK, made by a different number and kind of Interceptors (either available from Struts2 or, if the Interceptor with the logic that we want doesn't exist, created by ourselves).
As Apache Wiki says, "Each and every Interceptor is pluggable, so you can decide exactly which features an Action needs to support."
We can make all the custom stacks we want.
Here is the list of the Interceptors https://cwiki.apache.org/WW/interceptors.html#Interceptors-TheDefaultConfiguration
available on Struts2, and we can notice the Default Stack too, containing the majority of them.


SCENARIO
We want to perform a "Valid Session Checking" on our Actions, without writing any code into themselves or their configuration in Struts.xml.
The goal is NOT to handle user authentication (totally another pair of shoes), but to ensure that our Session is "certified" (think about an Web Application loading data into Session at the beginning, and expecting to find that data in the Session later, during its whole life cycle...).


WE NEED...
one "entry-point" Action (setting up a "mock" Session Validity Token), under the control of Default Interceptor Stack;
one Custom "SessionChecker" Interceptor;
one Custom Interceptor Stack (containing all the default interceptors PLUS our sessionCheckerInterceptor);
one Global Result "sessionExpired" on Struts.xml, redirecting to sessionExpired.jsp.


LET'S START
All of our Actions will extend a base Action called BaseAction:

package com.andrealigios.struts2validation.presentation.action;

    public abstract class BaseAction extends ActionSupport implements SessionAware, ServletResponseAware, ServletRequestAware{

        private static final long serialVersionUID = 1L; 
        public final static String SESSION_VALIDATION_TOKEN_KEY = "SESSION_VALIDATION_TOKEN_KEY";
        public final static boolean SESSION_VALIDATION_TOKEN_VALUE = true;

        private HttpServletRequest req;    

    
        /*  bla 
            bla 
            yada 
            yada */
        public HttpServletRequest getServletRequest() {
            return req;
        }

    }


We need an entry-point Action (let's call it SessionSetupAction), to put a token in session; we will try to read it later from our Interceptor,
to check if session is valid (if session is expired and replaced by a new one, our token won't be there);
In the example, the token is a boolean; in real world applications, obviously we will use something different (generated, unique, salted, obfuscated, crypted stuff...), to prevent attacks and, for example, avoid a user to access the same session of a previous user on the same browser if not every windows/tabs were closed between the logout of the first user and the login of the second one (and the logout procedure didn't destroy properly the session).

The SessionSetupAction must use the Default Interceptors Stack, because when we run this Action, we haven't put the token in the session yet, so we must bypass the sessionCheckerInterecptor this time.

    package com.andrealigios.struts2validation.presentation.action;    

    public class SessionSetupAction extends BaseAction {

        private static final long serialVersionUID = 1L;

         public String execute() throws Exception {
            try {
                getServletRequest().getSession().setAttribute(SESSION_VALIDATION_TOKEN_KEY, true);
            } catch (Exception e){
                // Mock exception log...
                e.printStackTrace();
            }

            return SUCCESS;
        }

    }



   
   
Let's write the first (and only, in our example) of "n" business Actions for our Web Application. Let's call it FirstRealPageAction:
   
    package com.andrealigios.struts2validation.presentation.action;    

    public class FirstRealPageAction extends BaseAction {

        private static final long serialVersionUID = 1L;

        public String execute() throws Exception {

            try {
                // Do business
                // Do business
                // Do business              

                return SUCCESS;
            } catch (Exception e){
                // Mock exception log...
                e.printStackTrace();
                return ERROR;
            }

        }

    }    




   
Now it's the turn of the JSPs:

    <!-- firstRealPage.jsp -->

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>First Real Page</title>
        </head>

        <body>
            <p>
                This is one of the Web Application pages.  <br/>

                You are here, then the token is correctly loaded into the Session.
            </p>
        </body>
    </html>



    


    <!-- error.jsp              -->

    <%@ page isErrorPage="true" %>
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>Error</title>
        </head>

        <body>
            <p>
                An error occurred!
            </p>
        </body>
    </html>





        

    <!-- sessionExpired.jsp       -->

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>Session Expired</title>
        </head>

        <body>
            <p>
                This is the Session Expired page.<br/>

                You are here because: <br/>                

                1) Your session was properly set up, but is expired; <br/>                

                2) Your session was NOT properly set up (for example, you tried to reach this page directly by URL). <br/>
                
                Press the button to pass through the sessionSetup Action and configure your Session properly.
            </p>

            <s:submit action="sessionSetup" value="Restart from the Entry point" />

        </body>
    </html>

    





   
At this point, we only miss the configuration and the interceptor itself. The configuration, quite long but (i hope) well-commented, is the following:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
"http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>        

        <package name="default-package" extends="struts-default">

            <interceptors>

                <!-- ========================================================== -->
                <!-- DECLARATION OF THE DEFAULT INTERCEPTOR STACK               -->
                <!-- ========================================================== -->                        

                <interceptor-stack name="defaultStack">
                    <interceptor-ref name="exception"/>
                    <interceptor-ref name="alias"/>
                    <interceptor-ref name="servletConfig"/>
                    <interceptor-ref name="i18n"/>
                    <interceptor-ref name="prepare"/>
                    <interceptor-ref name="chain"/>
                    <interceptor-ref name="scopedModelDriven"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/>
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="staticParams"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params">
                        <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
                    </interceptor-ref>
                    <interceptor-ref name="conversionError"/>
                    <interceptor-ref name="validation">
                        <param name="excludeMethods">input,back,cancel,browse</param>
                    </interceptor-ref>
                    <interceptor-ref name="workflow">
                        <param name="excludeMethods">input,back,cancel,browse</param>
                    </interceptor-ref>
                    <interceptor-ref name="debugging"/>
                </interceptor-stack>

            </interceptors>



            <!-- ========================================================== -->
            <!-- SIMPLE REDIRECT TO ENTRY POINT WHEN NO PAGE SPECIFIED      -->    
            <!-- ========================================================== -->

            <action name="welcome">    
                <result type="redirect-action">
                    <param name="actionName">sessionSetup</param>
                </result>  
            </action>



            <!-- ========================================================== -->
            <!-- ENTRY POINT ACTION, UNDER DEFAULT INTERCEPTOR STACK        -->
            <!-- ========================================================== -->        

            <action name="sessionSetup" class="com.andrealigios.struts2validation.presentation.action.SessionSetupAction">    
                <result type="redirect-action">
                    <param name="actionName">firstRealPage</param>
                </result>  
            </action>
            
        </package>



        <package name="our-custom-package" extends="struts-default">

            <interceptors>

                <!-- ========================================================== -->
                <!-- DECLARATION OF OUR CUSTOM INTERCEPTOR FOR SESSION CHECKING -->
                <!-- ========================================================== -->
                <interceptor name="our-mock-session-checker-interceptor" 
                            class="com.andrealigios.struts2validation.presentation.interceptor.MockSessionCheckerInterceptor"/>
                <!-- ========================================================== -->
 
                <!-- ============================================== -->
                <!-- DECLARATION OF OUR CUSTOM INTERCEPTOR STACK,   -->
                <!-- THAT WILL USE OUR CUSTOM INTERCEPTOR           -->
                <!-- ============================================== -->            
                <interceptor-stack name="ourCustomStack">

                    <interceptor-ref name="exception"/>
                    <!-- ===================================== -->
                    <!-- WE PUT OUR INTERCEPTOR REFERENCE HERE -->
                    <!-- ===================================== -->
                    <interceptor-ref name="our-mock-session-checker-interceptor"/>
                    <!-- ===================================== -->        
                    <interceptor-ref name="alias"/>
                    <interceptor-ref name="servletConfig"/>
                    <interceptor-ref name="i18n"/>
                    <interceptor-ref name="prepare"/>
                    <interceptor-ref name="chain"/>
                    <interceptor-ref name="scopedModelDriven"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/>
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="staticParams"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params">
                        <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
                    </interceptor-ref>
                    <interceptor-ref name="conversionError"/>
                    <interceptor-ref name="validation">
                        <param name="excludeMethods">input,back,cancel,browse</param>
                    </interceptor-ref>
                    <interceptor-ref name="workflow">
                        <param name="excludeMethods">input,back,cancel,browse</param>
                    </interceptor-ref>
                    <interceptor-ref name="debugging"/>
                </interceptor-stack>            
                <!-- ============================================== -->            
 
             </interceptors>



            <!-- ===================================================== -->
            <!-- THE STACK WE WILL USE FOR THE ACTIONS OF THIS PACKAGE -->
            <!-- ===================================================== -->
            <default-interceptor-ref name="ourCustomStack" />
            <!-- ===================================================== -->


            <global-results>
                <!-- ===================================================== -->
                <!-- THE GLOBAL RESULT USED TO REDIRECT A REQUEST TO THE   -->
                <!-- "SESSION EXPIRED" PAGE FROM WITHIN OUR INTERCEPTOR    -->
                <!-- ===================================================== -->
                <result name="sessionExpired">jsp/sessionExpired.jsp</result>
                <!-- ===================================================== -->
            </global-results>



            <action name="firstRealPage" class="com.andrealigios.struts2validation.presentation.action.FirstRealPageAction">
                <result name="success">jsp/firstRealPage.jsp</param>            
                <result name="error">jsp/error.jsp</param>
            </action>

        </package>

    </struts>




Got it ? When the Actions of the package "our-custom-package" get called, the request passes into our Interceptor, that will perform the check on the token.
Note that it's possible to use different stacks into one package, instead of different packages.

Final part, the one that brought you here: our custom Interceptor.


package com.andrealigios.struts2validation.presentation.interceptor;


import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.StrutsStatics;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 

public class MockSessionCheckerInterceptor extends AbstractInterceptor implements Constants{



    private static final long serialVersionUID = 1L;    

    public String intercept(ActionInvocation invocation) throws Exception {

        final ActionContext context = invocation.getInvocationContext();

        try {                        

                HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);                                

                String sessionToken = (String) request.getSession().getAttribute(SESSION_VALIDATION_TOKEN_KEY);                

                if (sessionToken==null || !sessionToken.equals(SESSION_VALIDATION_TOKEN_VALUE))

                    return "sessionExpired";

                    /*     If the session Token is not there (or is different from what we want), 
                            uses the Global Result "sessionExpired" to redirect the request
                            to a page that will notify the user, giving him the opportunity to 
                            restart    the Session in the right way.
                    */

                 /* Else, everything is fine, let's proceed down the stack ! */

                return invocation.invoke();

        } catch (Exception e){
            e.printStackTrace();
            return ERROR; // not defined in our example...
        } 

    }





   
The coding is over.
If you set up your simple Web Application like this, and try to access directly your "firstRealPage", you should be redirected to the sessionExpired page; the same thing should happen if you stay too much in the "firstRealPage" page and try to reload it...

Despite the messy exposition, I hope you enjoyed this ;)

Tuesday, June 12, 2012

JMS Queue in a Clustered Environment

Using JMS queues is quite simple once set up correctly.

But the simpleness immediately disappears when working in a clustered environment, whichever technology you are using; often you'll get NameNotFoundException or JMSException: Connection not found while trying to contact the JMS server.

The reasons can be many, but most of the time the problem is in the JNDI Lookup procedure: in a clustered environment, is important to preserve uniqueness of server names, to avoid the needs of complex tricks and the appearance of weird and mysterious errors.

A Technote from IBM explains that, in a Websphere clustered environment
"...in which 2 nodes have Application Servers with the same name, an attempt to lookup an EJB in the name space during an EJB invocation finds the wrong server.
[...]
The solution for this problem is to have different server names for the servers for 2 different nodes."

This happens because both Application Servers on different nodes have same name (server1 in the example), and trying to lookup server1 on ejb node from application node will instead return the server1 of application node, the local one.

The same thing happens on Weblogic, as they states in JMS Admin documentation (page 55):

"Note: JMS clients depend on unique WebLogic Server names to successfully access a cluster — even when WebLogic Servers reside in different domains. Therefore, make sure that all WebLogic Servers that JMS clients contact have unique server names."

Different server names, correct Lookups. That's all folks.

Hope that helps ;)

Monday, June 4, 2012

Struts2 XML VALIDATION

Struts 2 framework allows powerful and easy validation through Java, XML or Annotations.
The first way (override of Validate() method) should be avoided.
Both XML and Annotations are good ways to go, but as usual they're poorly documented / exampled.
Let's take a look at XML Validation:


STANDARD XML VALIDATION

Scenario:
You have a JSP that posts a form with new data (let's say one record about a person) to be inserted, to an Action named InsertOneRowAction.java.
Data posted are: Name and Birthday (KISS paradigm ftw...).
Fields in JSP page are named person.name and person.birthday (getters of Person.java value object).
Both fields are mandatory, and Birthday must be a valid date between 1990 and 2000.

Solution:
Create a file with the name of the action and append "-Validation.xml" at the end, in the same package of the action.
We will see then:
com.andrealigios.struts2validation.presentation.action.InsertOneRowAction.java
com.andrealigios.struts2validation.presentation.action.InsertOneRowAction-Validation.xml


Open XML validation file and write the desired rules in there, in this case:

  <field name="person.name">
      <field-validator type="requiredstring">
          <message><![CDATA[ Name is mandatory ]]></message>
      </field-validator>
  </field>
  <field name="person.birthday">
        <field-validator type="required">
            <message><![CDATA[ Birthday is mandatory ]]></message>
        </field-validator>
        <field-validator type="date">
            <param name="min">01/01/1990</param>
            <param name="max">01/01/2000</param>
            <message><![CDATA[ Birthday must be a valid date between ${min} and ${max} ]]></message>
        </field-validator>
    </field>



Now put the tag <fielderrors/> into your JSP.
Done!

Every time your data posted won't match the validation criteria, the Validation Interceptor will redirect your post to the source JSP page, showing the error messages and preventing wrong / incomplete data to reach the action's setters.


DYNAMIC XML VALIDATION - FIELDEXPRESSION VALIDATOR

Let's dig a bit deeper: we need min and max Date parameters to be dynamic, for example read from a database or a configuration file.
We need to create a getter for each parameter, that does its business inside, and returns the desired java.util.Date.
We can put the getter into the Action, or into Actions that are extended by ours (let's say BaseAction). Remind to preserve getters's visibility ;)

 
public Date getMinDateDynamicallyRead(){
 // Do business
 return minDate; 
}

public Date getMaxDateDynamicallyRead(){
 // Do business
 return maxDate; 
}


Now, let's modify XML Validation file as follows:

  <field name="person.birthday">
        <field-validator type="required">
            <message><![CDATA[ Birthday is mandatory ]]></message>
        </field-validator>
        <field-validator type="date">
            <message><![CDATA[ Birthday must be a valid date ]]></message>
        </field-validator>
      <field-validator type="fieldexpression">
        <param name="expression"> 
          <![CDATA[ person.birthday==null || (person.birthday >= minDateDynamicallyRead && person.birthday <=  maxDateDynamicallyRead) ]]>
        </param> 
        <message><![CDATA[ Birthday must be between ${minDateDynamicallyRead} and ${maxDateDynamicallyRead} ]]></message>
         </field-validator>
    </field>



The person.birthday == null part is necessary to avoid redundancy of messages. If date is not provided, then the "required" validator must raise the error message, but there's no need to show that date is not inside our desired interval too...

Note that you can chain multiple "fieldexpression" validators for a single field, performing different controls and showing different messages.


MULTIPLE ROWS XML VALIDATION - VISITOR VALIDATOR

Now let's understand the most powerful, less documented feature of Struts 2 Validation : VISITOR validation.

Scenario:
We are on a different JSP page, that shows us a list of persons, and allows us to perform multiple changes to their Names and Birthdays, and to save 'em all with one click on the UPDATE button.
The main object into the JSP is PersonsTable.java (exposed through a getter from the Action), that exposes a list of Person.java objects, cycled within an iterator in the JSP:


public List<Person> getPersonsFromDatabase(){ 
    return savedPersons; 
}

The JSP UPDATE button posts to an Action named UpdateMultipleRowsAction.java
(We obviously can't validate the persons in the previous way, because we can't (and definitely don't want to) write a huge, static XML file specifying row indexes ;)

Struts2 allows us to resolve the problem like follows:

Create the usual XML Validation file in action's package, beside the action:
com.andrealigios.struts2validation.presentation.action.UpdateMultipleRowsAction.java
com.andrealigios.struts2validation.presentation.action.UpdateMultipleRowsAction-Validation.xml

inside the xml file, let's write:

<validators>
  <field name="personsTable.personsFromDatabase">
      <field-validator type="visitor">
          <message></message>
      </field-validator>
  </field>
</validators>


This command will tell Struts to perform, for EVERY single row, the validation using the validation rules of the object listed (in this case, Person.java).
The real validation must be written into an xml file UNDER THE OBJECT PACKAGE (NOT the Actions package), with a name composed by the Object class concatenated to "-Validation.xml".

For example:
com.andrealigios.struts2validation.valueobject.Person.java
com.andrealigios.struts2validation.valueobject.Person-Validation.xml

Inside Person-Validation.xml, we can put the same rules used in previous examples, pointing to the name of the field (name of the getters of Person.java, in this case "name" or "birthday", without "person" or other stuff before), as follows:


  <field name="name">
      <field-validator type="requiredstring">
          <message><![CDATA[ Name is mandatory ]]></message>
      </field-validator>
  </field>
  <field name="birthday">
        <field-validator type="required">
            <message><![CDATA[ Birthday is mandatory ]]></message>
        </field-validator>
        <field-validator type="date">
            <param name="min">01/01/1990</param>
            <param name="max">01/01/2000</param>
            <message><![CDATA[ Birthday must be a valid date between ${min} and ${max} ]]></message>
        </field-validator>
    </field>


Enjoy, forgive my Engrish and... comment!! ;)