Wednesday, September 28, 2011

How to model RESTful Web Service

I see somebody lost way when he/she tries to model RESTful Web service. The issues I noticed are,
  • Not always keep in mind that RESTful Web Service is CRUD on "resources".
  • Put verbs in URI. Therefore, the concept about resources is messy up. 
  • Not think that URI is a hierarchy structure to help on organizing "resources"
 So, I made below picture to help on modeling RESTful Web Service.



Simplicity should be one of major reasons for us to adopt RESTful Web service. So, I think it is unnecessary to make RESTful model to be complicate. Another major reason to use RESTful Web Service is that the motivation of project is to "share resources" over the Internet/Intranet (or should say in Cloud? :) ). With these concepts in mind, we can divide the modeling process into four steps as below,
  1. Tell myself that I am going to make software to share "resource" as sharing HTML pages.
  2. Making a sheet to list/add resources into it.
  3. Check each resource and see if it need to be further categorized, Or, we will think if we need to have a reserved category for future. These categories will be mapped into URL. 
  4. For each classified resource, we can do CRUD operations, which maps to HTTP verbs POST, GET, PUT, or DELETE.
Using the Customer in above picture as an example, it is a kind of Resource. Customers are under different categories, silver and gold. For each customer, we can do CRUD operation. Then, the URI for getting a customer may like this: /resources/customer/silver/customerID/

It is better to avoid putting verbs in URI because we are going to share resource and verbs (operation) will be indicated by HTML verbs. Of course, it will still work if we put verbs in URI. It is just string. There is no standard spec for RESTful Web Service. We can define our own languge/protocl in URI. But, what I introduce here should be helpful for organizing analysts' thoughts and make models to be neat and SIMPLE.

Sunday, September 18, 2011

Ext JS 4 password strength meter

One of my friends wants me to help him on putting a password strength meter on his registration page. Inspired by a post on Ext JS 1.x forum, I created a Ext JS 4 compatible one as shown below,


To do this, what you need is 1) the following Ext JS widget extends from Ext.form.field.Text. 2) do not forget the CSS file and images used in CSS. To change the appearance of password meter, you can simply change images used in CSS.

JavaScript code:
Ext.define('yiyu.util.PasswordMeter',
    {
     extend : 'Ext.form.field.Text',
     alias : 'widget.passwordMeter',
     inputType : 'password',

     reset : function() {
      this.callParent();
      this.updateMeter(this);
     },
     
     //private
     onRender : function(container, position) {
      var me = this;
      me.callParent(arguments);
      this.objMeter = me.el.createChild({
       tag : "div",
       'class' : "strengthMeter"
      });
      me.objMeter.setWidth(me.el.getWidth(true) - 17);
      me.scoreBar = me.objMeter.createChild({
       tag : "div",
       'class' : "scoreBar"
      });
      me.scoreBar.setWidth(me.objMeter.getWidth(true));

      if (Ext.isIE6) { // Fix style for IE6
       this.objMeter.setStyle('margin-left', '3px');
      }
     },

     // private
     initEvents : function() {
      var me = this, el = me.inputEl;
      me.callParent();
      me.mon(el, {
       scope : me,
       keyup : me.updateMeter
      });
     },
     /**
      * Sets the width of the meter, based on the score
      * 
      * @param {Object} e
      * Private function 
      */
     updateMeter : function() {
      var score, p, maxWidth, nScore, scoreWidth;
      score = 0;
      p = this.getValue();
      
      maxWidth = this.objMeter.getWidth() - 2;

      nScore = this.calcStrength(p);

      scoreWidth = maxWidth - (maxWidth / 100) * nScore;
      
      this.scoreBar.setWidth(scoreWidth, true);
     },

     /**
      * Calculates the strength of a password
      * 
      * @param {Object} p
      *   The password that needs to be calculated
      * @return {int} intScore The strength score of the password
      */
     calcStrength : function(p) {
      var intScore = 0;

      // PASSWORD LENGTH
      intScore += p.length;

      if (p.length > 0 && p.length <= 4) { // length 4 or
                // less
       intScore += p.length;
      } else if (p.length >= 5 && p.length <= 7) { 
       // length between 5 and 7
       intScore += 6;
      } else if (p.length >= 8 && p.length <= 15) { 
       // length between 8 and 15
       intScore += 12;       
      } else if (p.length >= 16) { // length 16 or more
       intScore += 18;       
      }

      // LETTERS (Not exactly implemented as dictacted above
      // because of my limited understanding of Regex)
      if (p.match(/[a-z]/)) { 
       // [verified] at least one lower case letter
       intScore += 1;
      }
      if (p.match(/[A-Z]/)) { // [verified] at least one upper
            // case letter
       intScore += 5;
      }
      // NUMBERS
      if (p.match(/\d/)) { // [verified] at least one
            // number
       intScore += 5;
      }
      if (p.match(new RegExp(".*\\d.*\\d.*\\d"))) {
       // [verified] at least three numbers
       intScore += 5;
      }

      // SPECIAL CHAR
      if (p.match(new RegExp("[!,@,#,$,%,^,&,*,?,_,~]"))) {
       // [verified] at least one special character
       intScore += 5;
      }
      // [verified] at least two special characters
      if (p.match(new RegExp(
          ".*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]"
        ))) {
       intScore += 5;
      }

      // COMBOS
      if (p.match(new RegExp("(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both upper and lower case
       intScore += 2;
      }
      if (p.match(new RegExp(
        "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both letters and numbers
       intScore += 2;
      }
      // [verified] letters, numbers, and special characters
      if (p
        .match(new RegExp(
          "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])"
          ))) {
       intScore += 2;
      }

      var nRound = Math.round(intScore * 2);

      if (nRound > 100) {
       nRound = 100;
      }

      return nRound;
     }
    })


CSS code:
.strengthMeter {
 border: 1px solid #B5B8C8;
 margin: 3px 0 3px 0;
 background-image: url(images/meter.gif);
 height: 10px;
 background-size: 100%; 
}

.scoreBar {
 background-image: url(images/meter_background.gif);
 height: 10px;
 background-size: 100%; 
 line-height: 1px;
 font-size: 1px;
 float: right;
}


Edit: Here is a better implementation crated by osnoek.

Friday, September 9, 2011

A simple tutorial about creating Jersey RESTful web service in Netbean 7.0

I believe that new technologies should make things simpler instead of more complex. RESTful Web service is one of them. But, it seems there is no very simple tutorial about how to create RESTful Web service in Netbean. So, here is a extremely simple tutorial about how to create a Servlet based only RESTful web service in Netbeans 7.0.

There are several different RESTful web service frameworks on the market. Jersey is one of them. Jersey is reference implementation of JSR 311: JAX-RS: The JavaTM API for RESTful Web Services . The follows steps will show how easy it is to create a RESTful Web Service in Netbeans 7.0.

1)Create a Web application






2) Create our first RESTful Web service in Netbeans 7.0 with Jersey.








3) Test it.

Once we successfully did above steps, we see a new Restful Web Service folder in project as shown below.

We modify and add hello world string into GenericResource.java as shown below,
/**
* Retrieves representation of an instance of jia.blog.rest.GenericResource
* @return an instance of java.lang.String
*/
@GET
@Produces("text/html")
public String getHtml() {
   //TODO return proper representation object
   return "

Hello World!

"; }

Then we compile and deploy the project. Once we successful deployed it. We can test our hello world example by using the following URL:

http://localhost:8080/jerseyRest/firstREST/generic

I purposely use different string "jerseyRest", "fristREST", "generic" in URL as this way can help you to map string in URL into the place where we input in netbeans 7.0.

Also, this simple hello world example has been successfully tested on JDK 1.5 and Tomcat 6.0 environment. So, it works on i5/OS V5R4 platform too.

Here is the link to source code jiaRest.zip