Tuesday, February 28, 2012

RPC Practice: Practice of Redstone RPC Server and RPC Client

XML-RPC is a remote procedure call (RPC) protocol which
uses XML to encode its calls and HTTP as a transport mechanism.

Redstone XML-RPC Library is a implementation of the XML-RPC specification.

This post practice create the RPC server and
call service by RPC client with Redstone XML-RPC Library.

1. The RPC Server
1.1 The XmlRpcServlet and related classes

TestService.java

package test;

import javax.servlet.*;

import redstone.xmlrpc.XmlRpcServlet;

/**
 * The servlet that extends redstone.xmlrpc.XmlRpcServlet
 */
public class TestService extends XmlRpcServlet {
    /**
     * auto-generated serial version UID
     */
    private static final long serialVersionUID = 7764199825847356985L;

    public void init( ServletConfig servletConfig )
        throws ServletException {
        // init
        super.init( servletConfig );
        // regist the Service
        // HelloClockService is the service name for client to invoke
        // new HelloClock() is the instance that provide this service
        getXmlRpcServer().addInvocationHandler( "HelloClockService", new HelloClock());
    }
}

only one handler in this servlet named "HelloClockService" handled by
an instance of HelloClock

HelloClock.java

package test;

/** this class provide the HelloClockService,
  * only one service 'sayHello'
  */
public class HelloClock {
    /**
     * sayHello service of HelloClockService
     * @param name the name to say hello
     * @return HelloClockMessage contains hello message and current time
     */
    public HelloClockMessage sayHello (String name) {
        return new HelloClockMessage(name);
    }
}

HelloClock provide one service, sayHello, with one String parameter.
It will return an instance of HelloClockMessage

HelloClockMessage.java


package test;

import java.util.*;

/**
 * The message that will reply to client by
 * HelloClockService.sayHello
 */
public class HelloClockMessage {
    private String _msg;
    private Date _date;
    public HelloClockMessage () {
        
    }
    public HelloClockMessage (String name) {
        _msg = "Hello " + name;
        _date = new Date();
    }
    public HelloClockMessage (String msg, Date date) {
        _msg = msg;
        _date = date;
    }
    public String getMsg () {
        return _msg;
    }
    public Date getDate () {
        return _date;
    }
}

HelloClockMessage create the msg by the input name,
and create a Date object

The return message of HelloClockService will contains two parameter,
msg and date, with respect to the getter getMsg () and getDate () in HelloClockMessage

1.2 The servlet config (in web.xml)

config for xml-rpc

<servlet>
        <servlet-name>xml-rpc</servlet-name>
        <servlet-class>test.TestService</servlet-class>
        <init-param>
            <param-name>streamMessages</param-name>
            <param-value>1</param-value>
        </init-param>
        <init-param> <!-- Optional! Defaults to text/xml and ISO-8859-1 -->
            <param-name>contentType</param-name>
            <param-value>text/xml; charset=UTF-8</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>xml-rpc</servlet-name>
        <url-pattern>/xml-rpc/*</url-pattern>
    </servlet-mapping>

2. The RPC Client

TestRPCClient.java

package test;

import java.util.*;

import redstone.xmlrpc.XmlRpcCallback;
import redstone.xmlrpc.XmlRpcClient;
import redstone.xmlrpc.XmlRpcException;
import redstone.xmlrpc.XmlRpcStruct;
/**
 * test RPC call
 */
public class TestRPCClient {
    // the callback for async RPC
    private static XmlRpcCallback xrc = new XmlRpcCallback() {
        public void onException(XmlRpcException exception) {
            exception.printStackTrace();
        }
        public void onFault(int faultCode, java.lang.String faultMessage) {}
        public void onResult(java.lang.Object result) {
            System.out.println("########## Async RPC Callback ##########");
            // get the HelloClockMessage object by the response
            HelloClockMessage hcm = XmlToHelloClockMessage((XmlRpcStruct)result);

            // Show the value of created HelloClockMessage
            System.out.println(hcm.getMsg());
            System.out.println(hcm.getDate().getHours() + ":" + hcm.getDate().getMinutes());
        }
    };
    /**
     * convert XmlRpcStruct to HelloClockMessage
     * @param resp the XmlRpcStruct response
     * @return HelloClockMessage object
     */
    public static HelloClockMessage XmlToHelloClockMessage (XmlRpcStruct resp) {
        HelloClockMessage hcm =
            new HelloClockMessage((String)resp.get("msg"), (Date)resp.get("date"));
        return hcm;
    }
    public static void main( String[] args ) throws Exception {
        // create client
        XmlRpcClient client =
            new XmlRpcClient( "http://localhost:8080/RPCServer/xml-rpc", true);
        // invoke RPC method with param "Ben"
        // get the response
        XmlRpcStruct resp =
            (XmlRpcStruct)client
                .invoke( "HelloClockService.sayHello", new Object[] {"Ben"});
        // get the HelloClockMessage object by the response
        HelloClockMessage hcm = XmlToHelloClockMessage(resp);

        // show the Class of response parameter
        System.out.println(resp.get("date").getClass());
        System.out.println(resp.get("msg").getClass());

        // Show the value of created HelloClockMessage
        System.out.println(hcm.getMsg());
        System.out.println(hcm.getDate().getHours() + ":" + hcm.getDate().getMinutes());

        System.out.println();

        // invoke RPC Asynchronously
        client.invokeAsynchronously("HelloClockService.sayHello",
                new Object[] {"Benbai"}, xrc);
    }
}

This client call RPC twice,
one sync call, one async call with a callback object.

The HelloClockMessage is the same with server's one.

3. Test result

Run TestRPCClient as Java Program:


Download:

The full project is at github
RPCClient:
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/WebServicePractice/RPC/RPCClient
RPCServer:
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/WebServicePractice/RPC/RPCServer

References:

Redstone:
http://xmlrpc.sourceforge.net/

wiki:
http://en.wikipedia.org/wiki/XML-RPC

Sunday, February 26, 2012

EL Practice: Expression Language Logic and Arithmetic Operators

This post practice the Logic and Arithmetic Operators of  Expression Language

Logic >, <, >=, <=, ==, !=

code fragment:

<div class="practice_body">
    <!-- 1 > 2? -->
    <div>
        <div class="practice_element_left">
            ${num_one} &gt; ${num_two}?
        </div>
        <div class="practice_element_right">
            ${num_one > num_two}, ${num_one gt num_two};
        </div>
    </div>
    <!-- 1 < 2? -->
    <div>
        <div class="practice_element_left">
            ${num_one} &lt; ${num_two}?
        </div>
        <div class="practice_element_right">
            ${num_one < num_two}, ${num_one lt num_two};
        </div>
    </div>
    <!-- 1 >= 1? -->
    <div>
        <div class="practice_element_left">
            ${num_one} &gt;= ${1}?
        </div>
        <div class="practice_element_right">
            ${num_one >= 1}, ${num_one ge 1};
        </div>
    </div>
    <!-- 1 <= 1? -->
    <div>
        <div class="practice_element_left">
            ${num_one} &lt;= ${1}?
        </div>
        <div class="practice_element_right">
            ${num_one <= 1}, ${num_one le 1};
        </div>
    </div>
    <!-- 2 == 2? -->
    <div>
        <div class="practice_element_left">
            2 == ${num_two}?
        </div>
        <div class="practice_element_right">
            ${2 == num_two}, ${2 eq num_two};
        </div>
    </div>
    <!-- 1 != 2? -->
    <div>
        <div class="practice_element_left">
            ${num_one} != ${num_two}?
        </div>
        <div class="practice_element_right">
            ${num_one != num_two}, ${num_one ne num_two};
        </div>
    </div>
</div>

result:


Logic &&, ||, !

code fragment

<div class="practice_body">
    <!-- true && true? -->
    <div>
        <div class="practice_element_left">
            true &amp;&amp; true?
        </div>
        <div class="practice_element_right">
            ${true && true}, ${true and true}
        </div>
    </div>
    <!-- true && false? -->
    <div>
        <div class="practice_element_left">
            true &amp;&amp; false?
        </div>
        <div class="practice_element_right">
            ${true && false}, ${true and false}
        </div>
    </div>
    <!-- true || true? -->
    <div>
        <div class="practice_element_left">
            true || true?
        </div>
        <div class="practice_element_right">
            ${true || true}, ${true or true}
        </div>
    </div>
    <!-- true || false? -->
    <div>
        <div class="practice_element_left">
            true || false?
        </div>
        <div class="practice_element_right">
            ${true || false}, ${true or false}
        </div>
    </div>
    <!-- true && !true? -->
    <div>
        <div class="practice_element_left">
            true &amp;&amp; !true?
        </div>
        <div class="practice_element_right">
            ${true && !true}, ${true and not true}
        </div>
    </div>
    <!-- true || !true? -->
    <div>
        <div class="practice_element_left">
            true || !true?
        </div>
        <div class="practice_element_right">
            ${true || !true}, ${true or not true}
        </div>
    </div>
</div>

result:


Logic ?, :

code fragment

<div class="practice_body">
    <!-- 1 > 2? 'IS_TRUE' : 'IS_FALSE' -->
    <div>
        <div class="practice_element_left">
            1 &gt; 2?
        </div>
        <div class="practice_element_right">
            ${1 > 2? 'IS_TRUE' : 'IS_FALSE'}
        </div>
    </div>
</div>

result:


Arithmetic +, -, *, /, % (mod), ()

code fragment:

<div class="practice_body">
    <!-- 11 + 2 -->
    <div>
        <div class="practice_element_left">
            11 + 2?
        </div>
        <div class="practice_element_right">
            ${11 + 2}
        </div>
    </div>
    <!-- 11 - 2 -->
    <div>
        <div class="practice_element_left">
            11 - 2?
        </div>
        <div class="practice_element_right">
            ${11 - 2}
        </div>
    </div>
    <!-- 11 * 2 -->
    <div>
        <div class="practice_element_left">
            11 * 2?
        </div>
        <div class="practice_element_right">
            ${11 * 2}
        </div>
    </div>
    <!-- 11 / 2 -->
    <div>
        <div class="practice_element_left">
            11 / 2?
        </div>
        <div class="practice_element_right">
            ${11 / 2}
        </div>
    </div>
    <!-- 11 mod 2 -->
    <div>
        <div class="practice_element_left">
            11 mod 2?
        </div>
        <div class="practice_element_right">
            ${11 % 2}
        </div>
    </div>
    <!-- 1 + 2 * 3 -->
    <div>
        <div class="practice_element_left">
            1 + 2 * 3?
        </div>
        <div class="practice_element_right">
            ${1 + 2 * 3}
        </div>
    </div>
    <!-- (1 + 2) * 3 -->
    <div>
        <div class="practice_element_left">
            (1 + 2) * 3?
        </div>
        <div class="practice_element_right">
            ${(1 + 2) * 3}
        </div>
    </div>
</div>

result:


Download:

You can download the full project at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/ELPractice

The files of this practice:
src/test/filters/ELLogicArithmeticFilter.java
WebContent/el_logic_arithmetic_practice.jsp

Reference:

The official document

Tuesday, February 14, 2012

Java Practice: java.net practice, Use Google Geocode Web Service

Just simple log:

Assume we have the java application below:

package test;

import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class GeocodeService {
    public static void main (String args[]) {
        String result = null;
        try {
            System.out.println("First request\n\n");
            // request service by Lat, Lng
            StringBuilder sb = getResponse("http://maps.googleapis.com/maps/api/geocode/json?latlng=40.70594140,-74.0088760&sensor=true&language=ja");
            result = sb.toString();
            System.out.println(result+"\n");
            System.out.println("Second request\n\n");
            sb.setLength(0);
            // request service by address
            sb = getResponse("http://maps.googleapis.com/maps/api/geocode/json?address="
                    +java.net.URLEncoder.encode("59 ウォール街 マンハッタン ニューヨーク 10005 アメリカ合衆国", "UTF-8")+"&sensor=true&language=en");
            result = sb.toString();
            System.out.println(result);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    public static StringBuilder getResponse(String path){
        try {
            System.out.println(path);
            java.net.URL url = new java.net.URL(path);
            java.net.HttpURLConnection uc = (java.net.HttpURLConnection) url.openConnection();
            uc.setRequestProperty("User-agent", "Mozilla/5.0");

            uc.setRequestProperty("Accept-Charset", "UTF-8"); // encoding
            uc.setReadTimeout(30000);// timeout limit
            uc.connect();// connect
            int status = uc.getResponseCode();

            switch (status) {
                case java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT://504 timeout
                    break;
                case java.net.HttpURLConnection.HTTP_FORBIDDEN://403 forbidden
                    break;
                case java.net.HttpURLConnection.HTTP_INTERNAL_ERROR://500 server error
                    break;
                case java.net.HttpURLConnection.HTTP_NOT_FOUND://404 not exist
                    break;
                case java.net.HttpURLConnection.HTTP_OK: // ok
                    InputStreamReader reader = new InputStreamReader(uc.getInputStream(), "UTF-8");

                    int ch;
                    StringBuilder sb = new StringBuilder("");
                    while((ch = reader.read())!= -1){
                        sb.append((char)ch);
                    }
                    return sb;
            }

        } catch (java.net.MalformedURLException e) { // invalid address format
            e.printStackTrace();
        } catch (java.io.IOException e) { // connection broken
            e.printStackTrace();
        }
        return null;
    }
}

The result will be:

First request


http://maps.googleapis.com/maps/api/geocode/json?latlng=40.70594140,-74.0088760&sensor=true&language=ja
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "2",
               "short_name" : "2",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "ハノーバー・ストリート",
               "short_name" : "ハノーバー・ストリート",
               "types" : [ "route" ]
            },
            {
               "long_name" : "ダウンタウン",
               "short_name" : "ダウンタウン",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "10005",
               "short_name" : "10005",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "2 ハノーバー・ストリート マンハッタン ニューヨーク 10005 アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.70595330,
                  "lng" : -74.00886570
               },
               "southwest" : {
                  "lat" : 40.70549480,
                  "lng" : -74.00910170
               }
            },
            "location" : {
               "lat" : 40.70594550,
               "lng" : -74.00888990
            },
            "location_type" : "RANGE_INTERPOLATED",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.70707303029150,
                  "lng" : -74.00763471970851
               },
               "southwest" : {
                  "lat" : 40.70437506970850,
                  "lng" : -74.01033268029151
               }
            }
         },
         "types" : [ "street_address" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "Wall St",
               "short_name" : "Wall St",
               "types" : [ "subway_station", "establishment", "transit_station" ]
            },
            {
               "long_name" : "ダウンタウン",
               "short_name" : "ダウンタウン",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "10005",
               "short_name" : "10005",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "Wall St, ニューヨーク 10005 アメリカ合衆国",
         "geometry" : {
            "location" : {
               "lat" : 40.7068210,
               "lng" : -74.00910
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.70816998029150,
                  "lng" : -74.00775101970849
               },
               "southwest" : {
                  "lat" : 40.70547201970850,
                  "lng" : -74.01044898029151
               }
            }
         },
         "types" : [ "subway_station", "establishment", "transit_station" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "10265",
               "short_name" : "10265",
               "types" : [ "postal_code" ]
            },
            {
               "long_name" : "ダウンタウン",
               "short_name" : "ダウンタウン",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "マンハッタン ニューヨーク 10265 アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.70839880,
                  "lng" : -74.00650899999999
               },
               "southwest" : {
                  "lat" : 40.70530210,
                  "lng" : -74.01091610
               }
            },
            "location" : {
               "lat" : 40.70556480,
               "lng" : -74.0081070
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.70839880,
                  "lng" : -74.00650899999999
               },
               "southwest" : {
                  "lat" : 40.70530210,
                  "lng" : -74.01091610
               }
            }
         },
         "types" : [ "postal_code" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "10005",
               "short_name" : "10005",
               "types" : [ "postal_code" ]
            },
            {
               "long_name" : "ウォール・ストリート",
               "short_name" : "ウォール・ストリート",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "WALL STREET",
               "short_name" : "WALL STREET",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "WALL STREET ニューヨーク 10005 アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.7091540,
                  "lng" : -73.99918690
               },
               "southwest" : {
                  "lat" : 40.6949950,
                  "lng" : -74.0135830
               }
            },
            "location" : {
               "lat" : 40.69984330,
               "lng" : -74.00724360
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.7091540,
                  "lng" : -73.99918690
               },
               "southwest" : {
                  "lat" : 40.6949950,
                  "lng" : -74.0135830
               }
            }
         },
         "types" : [ "postal_code" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "ダウンタウン",
               "short_name" : "ダウンタウン",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "ダウンタウン ニューヨーク アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.74252620,
                  "lng" : -73.97164459999999
               },
               "southwest" : {
                  "lat" : 40.70046310,
                  "lng" : -74.01933500000001
               }
            },
            "location" : {
               "lat" : 40.72300840,
               "lng" : -74.00063279999999
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.74252620,
                  "lng" : -73.97164459999999
               },
               "southwest" : {
                  "lat" : 40.70046310,
                  "lng" : -74.01933500000001
               }
            }
         },
         "types" : [ "neighborhood", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "マンハッタン",
               "short_name" : "マンハッタン",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "マンハッタン ニューヨーク アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.8822140,
                  "lng" : -73.9070
               },
               "southwest" : {
                  "lat" : 40.67954790,
                  "lng" : -74.0472850
               }
            },
            "location" : {
               "lat" : 40.78343450,
               "lng" : -73.96624950
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.8200450,
                  "lng" : -73.90331300000001
               },
               "southwest" : {
                  "lat" : 40.6980780,
                  "lng" : -74.03514899999999
               }
            }
         },
         "types" : [ "sublocality", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "ニューヨーク アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.8822140,
                  "lng" : -73.9070
               },
               "southwest" : {
                  "lat" : 40.67954790,
                  "lng" : -74.0472850
               }
            },
            "location" : {
               "lat" : 40.78306030,
               "lng" : -73.97124880
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.8822140,
                  "lng" : -73.9070
               },
               "southwest" : {
                  "lat" : 40.67954790,
                  "lng" : -74.0472850
               }
            }
         },
         "types" : [ "administrative_area_level_2", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "ニューヨーク",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "ニューヨーク アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.9175770,
                  "lng" : -73.7002720
               },
               "southwest" : {
                  "lat" : 40.4959080,
                  "lng" : -74.25908790
               }
            },
            "location" : {
               "lat" : 40.71435280,
               "lng" : -74.00597309999999
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.9175770,
                  "lng" : -73.7002720
               },
               "southwest" : {
                  "lat" : 40.4959080,
                  "lng" : -74.25908790
               }
            }
         },
         "types" : [ "locality", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "ニューヨーク",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "ニューヨーク アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 45.0158650,
                  "lng" : -71.85626990
               },
               "southwest" : {
                  "lat" : 40.49594540,
                  "lng" : -79.76214390
               }
            },
            "location" : {
               "lat" : 43.29942850,
               "lng" : -74.21793260000001
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 45.0158650,
                  "lng" : -71.85626990
               },
               "southwest" : {
                  "lat" : 40.49594540,
                  "lng" : -79.76214390
               }
            }
         },
         "types" : [ "administrative_area_level_1", "political" ]
      },
      {
         "address_components" : [
            {
               "long_name" : "アメリカ合衆国",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "アメリカ合衆国",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 71.3898880,
                  "lng" : -66.94539480000002
               },
               "southwest" : {
                  "lat" : 18.91106430,
                  "lng" : 172.45469670
               }
            },
            "location" : {
               "lat" : 37.090240,
               "lng" : -95.7128910
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 71.3898880,
                  "lng" : -66.94539480000002
               },
               "southwest" : {
                  "lat" : 18.91106430,
                  "lng" : 172.45469670
               }
            }
         },
         "types" : [ "country", "political" ]
      }
   ],
   "status" : "OK"
}


Second request


http://maps.googleapis.com/maps/api/geocode/json?address=59+%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB%E8%A1%97+%E3%83%9E%E3%83%B3%E3%83%8F%E3%83%83%E3%82%BF%E3%83%B3+%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A8%E3%83%BC%E3%82%AF+10005+%E3%82%A2%E3%83%A1%E3%83%AA%E3%82%AB%E5%90%88%E8%A1%86%E5%9B%BD&sensor=true&language=en
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "59",
               "short_name" : "59",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Wall St",
               "short_name" : "Wall St",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Lower Manhattan",
               "short_name" : "Lower Manhattan",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "Manhattan",
               "short_name" : "Manhattan",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "New York",
               "short_name" : "New York",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "New York",
               "short_name" : "New York",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "New York",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "10005",
               "short_name" : "10005",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "59 Wall St, New York, NY 10005, USA",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.70593059999999,
                  "lng" : -74.00882020
               },
               "southwest" : {
                  "lat" : 40.70591870,
                  "lng" : -74.00883060
               }
            },
            "location" : {
               "lat" : 40.70591870,
               "lng" : -74.00883060
            },
            "location_type" : "RANGE_INTERPOLATED",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.70727363029150,
                  "lng" : -74.00747641970850
               },
               "southwest" : {
                  "lat" : 40.70457566970850,
                  "lng" : -74.01017438029150
               }
            }
         },
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

Download:
The file GeocodeService.java at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JAVA/Net/src/test

Reference:
http://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests
http://code.google.com/intl/en/apis/maps/documentation/geocoding/

Sunday, February 12, 2012

C/C++ Practice: Struct Practice One, Define Data Structure

This is the first practice of C/C++ Struct:

Practice use struct and union to define a 'data' struct that can contains different type of data

Assume we have a code fragment as below:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

/** This is the first practice of struct
  * Practice use struct and union to define a 'data' struct
  * that can contains different type of data
  */

// declare a struct that contains
// only a float variable
// define its type as 'first'
typedef struct first {
        float floatData;
} first;
// declare a struct that contains
// an int variable and a char variable
// define its type as 'second'
typedef struct second {
        int intData;
        char charData;
} second;
// declara a struct that contains
// an int variable thet denotes the data type,
// and an union that will be one of the two data type declared above,
// define its type as 'data'
typedef struct data {
        int type;
        union {
              first firstTypeData;
              second secondTypeData;
        };
} data;
// showData function declaration
void showData (data d);
int main () {
    data dataOne;
    data dataTwo;
    first firstData;
    second secondData;

    // set the type of dataOne
    // set the value of firstData
    // assign firstData to dataOne
    dataOne.type = 1; // first type
    firstData.floatData = 1.2;
    dataOne.firstTypeData = firstData;

    // set the type of data two
    // set the values of secondData
    // assign secondData to dataTwo
    dataTwo.type = 2; // second type
    secondData.intData = 3;
    secondData.charData = 'd';
    dataTwo.secondTypeData = secondData;

    // call showData to show the value(s) of dataOne and dataTwo
    showData(dataOne);
    showData(dataTwo);
    system("PAUSE");
}
void showData (data d) {

     switch (d.type) { // check data type by data.type
            case 1: // first type
                 printf ("float data = %.2f \n\n", d.firstTypeData.floatData);
                 break;
            case 2: // second type
                 printf ("int data = %d\nchar data = %c\n\n", d.secondTypeData.intData, d.secondTypeData.charData);
                 break;
     }
}

The result will be:



Download:
The file struct_practice_001.c of this practice is available at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/C_Struct

Reference:
http://www.cplusplus.com/doc/tutorial/structures/
http://www.cplusplus.com/doc/tutorial/other_data_types/

Saturday, February 11, 2012

C/C++ Practice: Pointer Practice Four, The Function Pointer

This is the fourth practice of C/C++ pointer:

Practice the Function Pointer.

Assume we have a code fragment as below:


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <conio.h>

/** This is the fourth C/C++ Pointer Practice
  * Practice the Function Pointer
  * store the function and the related key code in a struct
  * execute function based on the input
  */

// declare a structure contains
// function pointer: int (*fp) (int, int);
// key: char, will be '+', '-', '*' or '/'
typedef struct op {
    int (*calc) (int, int);
    char key;
} op;

// the function that do the Plus operation
int doPlus (int a, int b) {
     return a+b;
}
// the function that do the Subtract operation
int doSubtract (int a, int b) {
     return a-b;
}
// the function that do the Multiple operation
int doMultiple (int a, int b) {
     return a*b;
}
// the function that do the Divide operation
int doDivide (int a, int b) {
     return a/b;
}

int main () {
    char ch;
    bool finish = true;
    int i;
    // declare an array of the strcuture op,
    // set the function pointer of operation
    // and the proper key char to it.
    op opList[] = {
         &doPlus, '+',
         &doSubtract, '-',
         &doMultiple, '*',
         &doDivide, '/'
    };

    // an infinite loop
    // will output the value
    // 10 + 2, 10 - 2, 10 * 2 or 10 / 2
    // with respect to the input key +, -, * or /
    for (;;) {
        printf("please enter '+', '-', '*' or '/' \nto calculate 10(op)2, or others to exit\n\n");
        ch = getch();
        for (i = 0; i < sizeof(opList)/sizeof(op); i++) {
            if (opList[i].key == ch) {
               // the opList[i].calc is the function to execute
               printf("10 %c 2 = %d\n", ch, opList[i].calc(10, 2));
               finish = false;
            }
        }
        if (finish)
           break;
        finish = true;
    }
    system("PAUSE");
}

The result will be:




Download:
The file pointer_practice_004.c of this practice is available at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/C_Pointer

Reference:
http://www.cplusplus.com/doc/tutorial/pointers/
http://www.newty.de/fpt/index.html

C/C++ Practice: Pointer Practice Three, Use Pointer to Simulate 2D Array

This is the third practice of C/C++ pointer

Try use Pointer to create 2D array.

Assume we have a code fragment as below:


#include <stdio.h>
#include <stdlib.h>

/** This is the third C/C++ Pointer Practice
  * Try use Pointer to create 2D array.
  * The fires dimension is a set of pointers that
  * point to the 1D int array,
  * each 1D int array can have different size.
  * 
  * The only problem is unlike we can use sizeof(an_array)
  * to get the size of an array,
  * we have to handle the size here.
  */
int main () {
    // declare a pointer that points to int pointers.
    int** num_ptr_first;
    int i, j;
    // allocates 3 block of memory that will store the int pointers.
    num_ptr_first = (int**) malloc (sizeof(int*) * 3);
    // for each block of int pointer,
    // allocates the block(s) of memory that will store the int value(s).
    for (i = 0; i < 3; i++)
        *(num_ptr_first+i) = (int*) malloc ((i+1)*sizeof(int));
    // assign value to each int value in the simulated 2D array
    for (i = 0; i < 3; i++) {
        for (j = 0; j < i+1; j++)
            num_ptr_first[i][j] = (i+1)*(j+1);
    }
    // print the values
    for (i = 0; i < 3; i++) {
        for (j = 0; j < i+1; j++)
            printf("%d, ", num_ptr_first[i][j]);
        printf("\n");
    }
    // free the blocks of the int pointers that point to int values
    for (i = 0; i < 3; i++)
        free(num_ptr_first[i]);
    // free the blocks of the pointer that points to int pointers
    free(num_ptr_first);
    printf("\n");
    system("PAUSE");
}

The result will be:



Download:
The file pointer_practice_003.c of this practice is available at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/C_Pointer

Reference:
http://www.cplusplus.com/doc/tutorial/pointers/
http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/

C/C++ Practice: Pointer Practice Two, Pointer and Array

This is the second practice of C/C++ pointer,
practice concept:

An array can be considered a constant pointer

Assume we have a code fragment as below:


#include <stdio.h>
#include <stdlib.h>

/** This is the second practice of C/C++ pointer,
  * practice concept:
  * An array can be considered a constant pointer
  */

int main () {
    // declare an int array that contains 5 elements
    int num_arr[5];
    // get the length of the array num
    // we know it is '5', just show how we can get it
    // if we don't know it
    int length = sizeof(num_arr)/sizeof(num_arr[0]);
    // the num_arr can be considered a constant pointer points the num[0]
    int* num_arr_ptr = num_arr;
    int i;

    // assign values to num_arr by the pointer
    // where *(num_arr_ptr+i) denotes
    // 'the ith int element after the first element in num_arr'
    for (i = 0; i < length; i++)
        *(num_arr_ptr+i) = i*10 + i;
    // print the elements of num_arr
    for (i = 0; i < length; i++)
        printf("%d\n", num_arr[i]);
    printf("\n");
    // print the elements of num_arr through pointer
    for (i = 0; i < length; i++)
        printf("%d\n", *(num_arr_ptr+i));
    printf("\n");

    // change the num_arr_ptr that points the
    // 3rd element of num_arr and assign value
    num_arr_ptr = &num_arr[2];
    *num_arr_ptr = 55;
    // change the num_arr_ptr that points the
    // 4th element of num_arr and assign value
    num_arr_ptr = num_arr+3;
    *num_arr_ptr = 66;
    // increase the num_arr_ptr so it points
    // the 5th element and assign value
    num_arr_ptr++;
    *num_arr_ptr = 77;
    // print the elements of num_arr again
    for (i = 0; i < length; i++)
        printf("%d\n", num_arr[i]);
    printf("\n");
    system("pause");
}

The result will be:


Download:
The file pointer_practice_002.c of this practice is available at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/C_Pointer

Reference:
http://www.cplusplus.com/doc/tutorial/pointers/

C/C++ Practice: Pointer Practice One, Reference and Dereference

This is the first practice of C/C++ pointer, it practice two concept:

'&' is the reference operator and can be read as "address of"

and

'*' is the dereference operator and can be read as "value pointed by"

Assume we have a code fragment as below:

#include <stdio.h>
#include <stdlib.h>

/** This is the first practice of C/C++ pointer, it practice two concept:
  * '&' is the reference operator and can be read as "address of"
  * and
  * '*' is the dereference operator and can be read as "value pointed by"
  */
int main () {
    // declare an int variable
    int num = 5;
    // declare an int pointer variable and assign
    // the memory address of an int variable to it.
    int* num_ptr = &num;
    // declare a double variable
    double dblNum = 6.7;
    // declare a double pointer variable and assign
    // the memory address of a double variable to it.
    double* dblNum_ptr = &dblNum;

    // print the value of an int variable
    printf("\n\t%d\n", num);
    // print the memory address of an int variable
    printf("\t%x\n", &num);
    // print the value of an int pointer points to
    printf("\t%d\n", *num_ptr);
    // print the value of an int pointer
    printf("\t%x\n\n", num_ptr);

    // print the value of a double variable
    printf("\t%.2f\n", dblNum);
    // print the address of a double variable
    printf("\t%x\n", &dblNum);
    // print the value of a double pointer points to
    printf("\t%.2f\n", *dblNum_ptr);
    // print the value of a double pointer
    printf("\t%x\n\n", dblNum_ptr);

    // assign the address of a double variable by cast it to int pointer
    num_ptr = (int*)&dblNum;
    // print the double value as int - wrong result
    printf("\t%d\n", *num_ptr);
    // print the address - correct, it still an address
    printf("\t%x\n\n", num_ptr);

    // assign the address of an int variable by cast it to double pointer
    dblNum_ptr = (double*)&num;
    // print the int value as double - wrong result
    printf("\t%.2f\n", *dblNum_ptr);
    // print the address - correct, it still an address
    printf("\t%x\n\n", dblNum_ptr);
    system("PAUSE");
}

The result will be:

Download:
The file pointer_practice_001.c of this practice is available at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/C_Pointer

Reference:
http://www.cplusplus.com/doc/tutorial/pointers/

Thursday, February 9, 2012

Ant Practice: Encoding Message Bundles by Ant

As we mentioned at JSTL Practice: I18N (Internationalization) practice, Locale, Bundle and Message.,
to create the message bundles for i18n, we have to run native2ascii in command line,
and may move the files as need or type very long path.

Now we know we can do these tasks by Ant (see Ant Introduction and First Try),
we will do this practice as below:

Write build file

For encoding message resource (from specific folder)
to message properties (and put to specific folder),
we have to write the build file as below:

<project name="genMessageBundles" default="encodeMessage" basedir=".">

    <!-- path property
        name denotes the property name
        location denotes the path
        the ${basedir} is the root of the project -->
    <property name="message.resource.path" location="${basedir}/src/test/jstl/i18n/resources"/>
    <property name="message.properties.path" location="${basedir}/src/test/jstl/i18n/properties"/>

    <!-- clear old files
        this will delete all *.properties
        under /src/test/jstl/i18n/properties -->
    <target name="clean">
        <delete dir="${message.properties.path}" includes="**/*.properties" />
    </target>

    <!-- encoding msgs
        this will encode all *.resource
        under /src/test/jstl/i18n/resources 
        rename the encoded files to *.properties
        and put them to /src/test/jstl/i18n/properties
        encoding is UTF-8 -->
    <target name="encodeMessage" depends="clean">
        <echo message="begin"/>
            <native2ascii src="${message.resource.path}" encoding="UTF-8"
                includes="**/*.resource" dest="${message.properties.path}" ext=".properties" />
        <echo message="end"/>
    </target>
</project>

Modify Resource Files

Then we modify the message resource files as below:



Run Ant Build

After we change the message resource files,
we can run Ant Build to encode them to message properties files.



Test the result

Then we can run the web project and see the new messages:



Download:
The full project is at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JSTLPractice

File of this practice:
ant.encodeMessages.xml

Tuesday, February 7, 2012

Ant Introduction and First Try

Introduction:

Ant is a Java-based build tool. In theory, it is kind of like Make, without Make's wrinkles and with the full portability of pure Java code.

To run ant build, several steps as below (with eclipse):

Step 1: Check the runtime environment:

Open Window -> Preferences


There should a tools.jar under Ant -> Runtime -> Global Entries



Step 2: Write a build file

Create a file named ant.firsttry.xml under root directory of a Project,
the code is as below:

<!-- The project entry, execute target firstTry at first -->
<project name="antTest" default="firstTry">
    <target name="preSet">
        <echo message="Preset of First Try"/>
    </target>
    <!-- Echo message, will run the target preSet before it self -->
    <target name="firstTry" depends="preSet">
        <echo message="Ant First Try"/>
    </target>
</project>

The default attribute of project tag denotes the default target to execute,
the depends attribute of target tag denotes the target that should be executed before.

In the case above, it will run target 'preSet' then 'firstTry'

Step 3: Run the ant build

Right click file ant.firsttry.xml, Run As -> Ant Build


The result will be



Download:
The full project is at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JSTLPractice

File of this practice:
ant.firsttry.xml

Reference:
http://ant.apache.org/

Sunday, February 5, 2012

JSTL Practice: I18N (Internationalization) practice, Locale, Bundle and Message.

We sometimes want to display a message in several different language,
i.e., I18N,Internationalization,
we can achieve this with JSTL by the steps below:

Step 1: Prepare the resource of message bundle.

For easy management, we create a package 'test.jstl.i18n.resources' and create four '.resource' file as below:

i18n_test_en_US.resource

i18n.coffee=coffee

i18n_test_fr_FR.resource

i18n.coffee=café

i18n_test_ja_JP.resource

i18n.coffee=コーヒー

i18n_test.resource

i18n.coffee=coffee default

actually you can put these files at any location, and use any sub name '.whatever',
because we do not use these files directly, they are just the resource file to generate the real bundle file.

Make sure to change their encoding to 'UTF-8', you can change their encoding as below:
Right click on file then click properties

Change Text file encoding to UTF-8 if it is not default



Step 2: Generate the message bundle from resource files

After the resource files prepared, we copy them to a tmp folder such like C:/tmp,
and use the native2ascii under jdk/bin to generate message bundle as below:

c:\Program Files\Java\jdk1.6.0_24\bin>native2ascii -encoding UTF-8 c:\tmp\i18n_test_en_US.resource c:\tmp\i18n_test_en_US.properties

c:\Program Files\Java\jdk1.6.0_24\bin>native2ascii -encoding UTF-8 c:\tmp\i18n_test_ja_JP.resource c:\tmp\i18n_test_ja_JP.properties

c:\Program Files\Java\jdk1.6.0_24\bin>native2ascii -encoding UTF-8 c:\tmp\i18n_test_fr_FR.resource c:\tmp\i18n_test_fr_FR.properties

c:\Program Files\Java\jdk1.6.0_24\bin>native2ascii -encoding UTF-8 c:\tmp\i18n_test.resource c:\tmp\i18n_test.properties

after the message bundle generated, we create a new package 'test.jstl.i18n.properties' and put the bundles into the package.

Step 3. Use 'setBundle' tag to load bundle then use 'message' tag to display message

Assume we have a page as below:

practice_three__internationalization.jsp

<%@ page isErrorPage="true" language="java"
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- This is the uri for JSTL 1.2 -->
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- EL is required -->
<%@ page isELIgnored ="false" %>
<!-- This page practice the setBundle message tag -->
<html>
    <head>
        <meta http-equiv="Content-Type" 
            content="text/html; charset=UTF-8"/>
        <title>practice three: I18N (Internationalization)</title>
        <script type="text/javascript" src="js/practice_three.js"></script>
    </head>
    <body>
        <!-- load bundle if it is null (without locale setting) -->
        <c:if test="${testBUndle == null}">
            <fmt:setBundle basename="test.jstl.i18n.properties.i18n_test"
                var="testBundle" scope="session"/>
        </c:if>
        <!-- The language select menu, call javascript to change locale when changed -->
        <select id="langVal" onChange="i18n.changeLocale(this.value, '${currentLocale}');" selectedIndex="1">
            <!-- The first option display the current language -->
            <option value="${currentLocale}">${currentLanguage}</option>
            <option value="en_US">English</option>
            <option value="ja_JP">日本語</option>
            <option value="fr_FR">Français</option>
            <option value="de_DE">Deutsch</option>
        </select>

        <!-- out put the message with respect to the key 'i18n.coffee' -->
        <fmt:message key="i18n.coffee"
                bundle="${testBundle}"/>
    </body>
</html>

The result will be


There is no locale setting, it will use the default setting from your browser, in this case is en_US,

The setBundle tag will load bundle which file nam
is [basename+locale].properties,
i.e., test.jstl.i18n.properties.i18n_test_en_US.properties

If it can not find such a file, it will use the default bundle,
which named [basename].properties,
i.e., test.jstl.i18n.properties.i18n_test.properties

The message tag will display the value of the key in the bundle,
i.e., coffee,
which is the value of the key 'i18n.coffee' in bundle test.jstl.i18n.properties.i18n_test.properties

The first option of select element is
based on the variabl currentLocale and currentLanguage in the session scope.
after you select a locale in the selectbox,
an Ajax request will post to another page to change locale.

Step 4: Use Ajax to post change locale request.

The Javascript file used to send change-locale request in the page before is as below:

practice_three.js

if (!window.i18n)
    i18n = {};
i18n.changeLocale = function (locale, current) {
    var request;
    // do nothing if not changed
    if (locale == current)
        return;

    // get a request
    if (request = this.getXmlHttpRequest()) {
        // do post and bring locale value as param['lang']
        request.open('POST', 'practice_three__internationalization_lang_page.jsp?lang='+locale);
        request.send(null);
    }
    // refresh document after request success
    request.onreadystatechange = function() {
        if(request.readyState === 4 && request.status === 200)
            document.location.href = document.location.href;
    };
};

//get the XmlHttpRequest object
i18n.getXmlHttpRequest = function () {
    if (window.XMLHttpRequest
        && (window.location.protocol !== 'file:' 
        || !window.ActiveXObject))
        return new XMLHttpRequest();
    try {
        return new ActiveXObject('Microsoft.XMLHTTP');
    } catch(e) {
        throw new Error('XMLHttpRequest not supported');
    }
};

The function 'i18n.changeLocale' will check whether the locale is changed first, if it is changed,
post a request to page 'practice_three__internationalization_lang_page.jsp'
and bring the new locale value with param name 'lang'

After the request success, it will reload current page to display the message with new locale.

Step 5: Use 'setLocale' tag to change locale and use 'setBundle' to reload appropriate bundle

The page that receive the change locale request and change locale is as below

practice_three__internationalization_lang_page.jsp

<%@ page isErrorPage="true" language="java"
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- This is the uri for JSTL 1.2 -->
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- EL is required -->
<%@ page isELIgnored ="false" %>
<!-- This page practice setLocale and setBundle tag -->
<html>
    <head>
        <meta http-equiv="Content-Type" 
            content="text/html; charset=UTF-8"/>
        <title>practice three: I18N (Internationalization)</title>
    </head>
    <body>
        <!-- Set the locale by the value of parameter 'lang' -->
        <fmt:setLocale value="${param['lang']}" scope="session" />
        <!-- Should load bundle again with the new locale -->
        <fmt:setBundle basename="test.jstl.i18n.properties.i18n_test"
            var="testBundle" scope="session"/>
        
        <!-- set the value of currentLocale -->
        <c:set var="currentLocale" value="${param['lang']}" scope="session" />

        <!-- Set the value of currentLanguage -->
        <c:choose>
            <c:when test="${param['lang'] eq 'ja_JP'}">
                <c:set var="currentLanguage" value="日本語" scope="session" />
            </c:when>
            <c:when test="${param['lang'] eq 'fr_FR'}">
                <c:set var="currentLanguage" value="Français" scope="session" />
            </c:when>
            <c:when test="${param['lang'] eq 'de_DE'}">
                <c:set var="currentLanguage" value="Deutsch" scope="session" />
            </c:when>
            <c:otherwise>
                <c:set var="currentLanguage" value="English" scope="session" />
            </c:otherwise>
        </c:choose>
    </body>
</html>

It set the locale to the value of parameter 'lang' by setLocale tag,
then reload bundle to change to different bundle.

It also store two variable currentLocale and currentLanguage into session scope.

Finally we can display the 'coffee' in different language, note we do not have the bundle of locale de_DE,
it will display the message in default bundle (value is coffee default) when we select Deutsch:





Download:

You can download the full project at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JSTLPractice

The files of this practice:
src/test.jstl.i18n.properties.*
src/test.jstl.i18n.resources.*
WebContent/practice_three_*
WebContent/js/practice_three.js

References:
http://java.sun.com/developer/technicalArticles/J2SE/locale/
http://www.tutorialspoint.com/jsp/jsp_standard_tag_library.htm

Wednesday, February 1, 2012

JSTL Practice: Number and Date Formatting Tags

In this post, we will practice the Number and Date Formatting Tags

setLocale, formatNumber, formatDate, parseDate,
parseNumber, setTimeZone, timeZone

NOTE: The test result may different since the real test time and timezone / locale

The setLocale tag

The setLocale tag is used to set the locale,
assume we have the fragment below

<!-- set the locale to 'en_US' in session scope -->
<fmt:setLocale value="${'en_US'}" scope="session" /><br />
<!-- currency, locale setting will change currency format -->
<fmt:formatNumber type="currency" value="${1234.5678}" /><br />
<!-- set the locale to 'fr_FR' in session scope -->
<fmt:setLocale value="${'fr_FR'}" scope="session" /><br />
<!-- currency, locale setting will change currency format -->
<fmt:formatNumber type="currency" value="${1234.5678}" /><br /><br />

The result will be:


The 'en_US' and  'fr_FR' is the combination of language code and country code,
for more information, please refer to the official document:
http://java.sun.com/developer/technicalArticles/J2SE/locale/

The formatNumber tag

The formatNumber tag can format number as 'number', 'percent' or 'currency' and set format pattern,
assume we have the fragment below:

<!-- number -->
<fmt:formatNumber type="number" value="${1234.5678}" /><br />
<!-- using pattern format number, # denotes 0-n digital, 0 denotes one digital -->
<fmt:formatNumber type="number" value="${1234.5678}" pattern="#0.00 pound" /><br />
<!-- currency, locale setting will change currency format -->
<fmt:formatNumber type="currency" value="${1234.5678}" /><br />

<!-- percentage -->
<fmt:formatNumber type="percent" value="${1234.5678}" /><br />
<!-- percentage with maximum integer/fraction digits -->
<fmt:formatNumber type="percent" value="${1234.5678}"
    maxIntegerDigits="10" maxFractionDigits="10" /><br />
<!-- percentage with max/min integer/fraction digits -->
<fmt:formatNumber type="percent" value="${1234.5678}"
    maxIntegerDigits="10" maxFractionDigits="10"
    minIntegerDigits="8" minFractionDigits="4" /><br /><br />

The result will be


The parseNumber  tag

The parseNumber tag can parse String to number,
assume we have the fragment below:

<!-- parse string to number -->
<fmt:parseNumber var="parsedNumber" type="number" value="${'1,234.56'}" />
<c:out value="${parsedNumber + 3}" /><br /><br />

The result will be



The formatDate tag

The formatDate tag can format a date object with specific format pattern,
assume we have the fragment below

<!-- date, init type=date, using java.util.Date -->
<fmt:formatDate value="${theDate}" /><br />
<!-- date, type=both for show all, date for ymd, time for hms -->
<fmt:formatDate type="both" value="${theDate}" /><br />
<fmt:formatDate type="date" value="${theDate}" /><br />
<fmt:formatDate type="time" value="${theDate}" /><br />
<!-- date with pattern -->
<fmt:formatDate pattern="yyyy-MM-dd" value="${theDate}" /><br />
<!-- date with pattern -->
<fmt:formatDate pattern="HH:mm:ss" value="${theDate}" /><br /><br />

The result will be



The parseDate  tag

The parseDate tag can parse string to date,
assume we have the fragment below:

<fmt:parseDate var="parsedDate" value="${'12-12-2011'}" 
    pattern="dd-MM-yyyy" />
<c:out value="${parsedDate}" /><br /><br />

The result will be


The timeZone  tag

The timeZone  tag apply all its body content to specific timezone,
assume we have the fragment below:

<fmt:timeZone value="${'GMT+3'}">
    <!-- date, init type=date, using java.util.Date -->
    <fmt:formatDate type="both" value="${theDate}" /><br />
</fmt:timeZone>
<fmt:timeZone value="${'GMT+5'}">
    <!-- date, init type=date, using java.util.Date -->
    <fmt:formatDate type="both" value="${theDate}" /><br />
</fmt:timeZone>

The result will be


The setTimeZone  tag

The setTimeZone  tag set the timezone of the content after it,
assume we have the fragment below:

<!-- change time zone of page -->
<fmt:setTimeZone value="GMT+4" />
<!-- date, init type=date, using java.util.Date -->
<fmt:formatDate type="both" value="${theDate}" /><br />
<!-- apply timezone to body content -->
<fmt:timeZone value="${'GMT+3'}">
    <!-- date, init type=date, using java.util.Date -->
    <fmt:formatDate type="both" value="${theDate}" /><br />
</fmt:timeZone>
<fmt:formatDate type="both" value="${theDate}" /><br />
<!-- change time zone of page -->
<fmt:setTimeZone value="GMT+5" />
<!-- date, init type=date, using java.util.Date -->
<fmt:formatDate type="both" value="${theDate}" /><br />

The result will be


Download:
The full project of this practice is at github:
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/JSTLPractice

Files of this practice:
src/test.jstl.filters.PracticeTwoFormatData.java
WebContent/practice_two__format_data.jsp

References:
http://www.tutorialspoint.com/jsp/jsp_standard_tag_library.htm