Saturday, December 29, 2007

Extjs Calendar

After fought for 2 weeks, extjs calendar Beta0.1 is released today. It has the following features:
  • create/delete/change entries (one click for create new entry; double click for edit and delete entry)
  • drag and drop to shift entries
  • edit entries in a window (double click)
  • resize the entry in south direction
This design is based on the EXTJS ajax framework. To view the demo, please see the following link:

http://www.feyasoft.com -> click 'My Calendar' icon on the desktop.

Sunday, December 02, 2007

Ajax based (EXTJS) application authentication

For Ajax based authentication, it's not a whole lot different than providing a traditional web infrastructure. What we're aiming for is to guarantee our session is secure and there is an established and persistent authentication object for all requests. There are a number of ways to accomplish this.

First is to secure the wire. This means whatever we do, make sure the user can never get to the website via regular HTTP and always uses HTTPS. It's pretty simple to setup Apache to do this.

Next is the authentication mechanism. The objective here is to generate and cache a session object that is guaranteed to be correct between the web server and the web browser for the duration of that web browser's session or until a session timeout occurs. This can easily be provided in one of two ways: HTTP authentication or HTTP sessions.

The positives of HTTP authentication is that it's standards based and provides transparent authentication after an initial authentication is complete. We get headers for the username, password, and realm for every invocation to the web service after this is completed. This includes invocations with our embedded ajax components. The negatives is that it's not secure, so we absolutely need to push it over HTTPS if you're going to use it. In addition, there's no authorization mechanism built in, so we need to roll own for authorization levels. And finally, we can't log out if using HTTP authentication. Once a user is authenticated, there's no means to unauthenticate them other than closing the browser and starting over.

Session-based authentication provides similar functionality to HTTP authentication, but we need to manage the session information. It does not provide a means to do authorization levels either, requiring we to roll our authorization levels. The benefit of session-based authentication is that we can log out from a session by removing the session variable at the web server. The disadvantages of using session-based authentication is that we have to figure out a mechanism to store passwords in other than cleartext format. This is because we're not sent the username/password combo in the headers, but instead we get a sessionid for the established session.

A basic rule of thumb, provided we're not doing persistent cookie session information, is that until a user establishes a known authentication session with web server, there are no credentials available with which to guarantee their access. Typically the ONLY place I need to make absolutely certain that authentication has happened is on the server, since that's where all of the data will be housed. The browser is just a window into that data.

From a technical perspective, here's how a session-based authentication would work:
  • User starts a brand new browser and connects to ajax-enabled app.
  • Application then posts some type of dialog box requiring a login to the server
  • The user enters their username/password into that dialog and clicks the login button
  • Javascript should hook the login button and send an ajax request to whatever login script/service/servlet/whatever is running on the server side
  • The server takes the parameters and passes them through whatever authentication system using on the server.
  • If the credentials work, the server creates a sessionid storage area for this new sessionid and returns a positive response to the ajax client. Part of the http headers for this response is the sessionid for maintaining session information between the client and the server. In the sessionid storage area on the server, we can store whatever variables we want to store.
  • The HTTP stack in the browser maintains the sessionid for each successive invocation to the web server that it's talking to and ONLY for that web server. As long as the browser is running, the sessionid is maintained. Once the browser goes away, the sessionid goes away with it. There are known session hijacking hacks out there, but they can be averted by providing a bit more information within the variables attached to the sessionid on the server.
  • Each of the successive xmlhttprequest objects that ask for data from the server pass the sessionid with it. In our application on the server, the first thing we need do for EVERY invocation is validate that the sessionid is still valid. There are mechanisms in most server application frameworks to provide session expiration by a variety of means. We just need to validate their sessionid with whatever framework you're using.

Monday, November 26, 2007

Friday, October 26, 2007

Light J2EE Application High Level Architecture Diagram


For Web Application, industry are pretty close agree to use light J2EE (Spring + hibernate) loose coupling concepts in business logic tier. However, there are not clear blueprint for presentation tie. Do we still need use thin-client or rich-client? I believe it is time to move (at least think) rich client. In here, I introduce a model for thick client:

1: Download Client-side application to user browser. (For example: extjs)
2: Client-side logic flow
3: Data exchange through AJAX in JSON format (client-server event driver)

For thin client, we can not respect "data" exchange between client and server. Maybe it just a kind of "String" exchange. For thick client, it is real data (JSON).

Reference
:
1: Put JSF to work -- Build a real-world Web application with JavaServer Faces, the Spring Framework, and Hibernate; Derek Yang Shen, JavaWorld.com;

Tuesday, September 18, 2007

Improve pages performance - 2 cents

  • Reduces the number of HTTP requests - Reducing the number of components to be downloaded.
  • Moving stylesheets to the document HEAD - makes pages load faster.
  • Move scripts from the top to as low in the page as possible - enable progressive rendering.
  • Avoid CSS expression.
  • Reduce DNS lookup.
  • Avoid page redirect.
  • Clean Scripts code - remove duplicate code.

Sunday, August 19, 2007

Javascript files Directory Structure

Currently there does not exist any standard structure for javascript files directory. In here, I just follow the Java file structure and create a similar file structure for javascript.

As you see, I create a dir 'javascript' which is used to hold all of JS files. And I also create a project related dir 'FEYA' which is used to hold all of my JS file. Any 3rd-party JS lib are parallel to this dir.

Under 'FEYA' dir, 'FEYA.js' is used to define namespace. Any other my JS file will call it to define package. And here comes my example html code to include those JS files:





Tuesday, July 24, 2007

Javascript package/public/private method

Perhaps a very uncommon approach to developing web applications that require JavaScript is namespacing your scripts. And how to define a scope (public/private) to the method and variable. This blog introduces a simple singleton pattern for achieving this discipline.

First I define a base JS class which will be included in any page to define a package (or you can call it 'namespace'). See right figure for detail source code.

Second, I will call this method in any JS class - define the package just like java class.
/**
* Copyright(c) 2006-2007 ...
*/
package("FEYA.util");

/**
* This JS is used to define a bunch of util class
*
* @author fzhuang
* @Date July 26, 2007
*/
FEYA.util.common = function(){
// private variable/function. Not accessible from outside
var count = 0;
var increaseCount = function(){count++;};

// Priviledged method. Can be called from outside
return {
formatDate: function(value){
return value ? value.dateFormat('D, M d Y') : '';
}
}
}();
Third, I can call following public functions from any JS class.
FEYA.util.common.formatDate

Saturday, June 16, 2007

YUI-Ext tutorial for List, create, update, delete

Today I posted the following tutorial in YUI-EXT, please see the link:

Using Ext grid + form + dialog to achieve paging list, create, edit, delete function

This tutorial mainly focus on using EXT grid/form/dialog functions to achieve general paging action (list, create, update, delete). It provides a different pattern to build page instead of J2EE MVC pattern.

Thursday, May 10, 2007

Web 2.0 application: Ajax replace MVC framework

We have played Struts/JSF/Spring/hibernate for Enterprise application, doing transaction etc for a while. Now it is time move to web 2.0 (readable) and face AJAX.

In web application, Struts/JSF MVC framework are pretty popular. However, Ajax-based web application can make this process simpler. As the following figure shows, Ajax based application only need a simple servelet to transfer data. Compare with MVC framework, this is a small job. At the same time, a good Ajax Util framework will create rich GUI in the client browser with simple javascript/html code. In general Ajax can be separated as 3 parts:


First part is client-side Ajax, such as animation, drag-and-drop, rich editor etc. YUI, dojo, rico provide lots of great examples.

Second part is the bridge between browser side and Java server side, like bunch of RPC frameworks, DWR, prototype, YUI etc.

Third part is general Ajax Util framework (templates) which can be applied to most applications, such as search function, paging function, CRUD/List function etc. We can think them as glue tool between browser and server, and it will dramatically reduce code by using those utils. YUI extension provides great example for this.

Sunday, April 29, 2007

JSON speed up Ajax

The JavaScript Object Notation, or JSON, is a lightweight syntax for representing data. JSON has structure with nesting of data elements, just as XML does. JSON is also text-based and use Unicode. It is just as readable by humans as XML is. Here comes a simple example for Json:
{"totalCount":2,
"results":[{"bh":"100","sm":"hello"},{"bh":"101","sm":"me" }]}
The big different about JSON and XML is that JSON is a subset of JavaScript. I can use JavaScript's own compiler to do just that by calling eval. Parsing JSON is a one-liner! Moreover, navigating an object synthesized from JSON is identical to navigating any JavaScript object. It's far easier than navigating through the DOM tree.

To create a JSON object in server side with Java. We can use the lib in "json.org". It provides a quick API to parse POJO and list etc. See the following example code:
public JSONObject toJSONObject() throws Exception {
JSONObject json = new JSONObject();
json.put("totalCount", totalCount);

JSONArray jsonItems = new JSONArray();
for (Iterator iter = results.iterator(); iter.hasNext();) {
jsonItems.put(iter.next().toJSONObject());
}
json.put("results", jsonItems);

return json;
}
To parse JSON data from JS in serve side, please see the following example:
JSONArray jsonArray = JsonUtil.getJsonArray(jsonString);
// JsonUtil.getJsonArray(jsonString) just do this ->
// jsonArray = new JSONArray(jsonString);

// loop through - get from json and update
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
}

Saturday, April 28, 2007

YUI extension

Jack Slocum launch YUI extension 1.0 recently in extjs.com. It provides a strong framework for Ajax project. YUI extension has the following interesting functions:
  • Online Grid editor (really convenience one - JSON)
  • Dialogs (Message dialog, progress dialog etc)
  • Menu (drop menu)
  • Tree
  • Resizable
  • Layout
EXTJS.com is very well documented and follows great OO principles and GUI design patterns. Furthermore, it provides really great example to show those functions. Although, the example is never enough for cover every cases.

Here comes one of my examples:

Monday, April 16, 2007

Ajax Request Compare

Currently, there exists several non-commercial AJAX frameworks for request during the development of a dynamic call-center application.
  • Prototype
  • Dojo
  • Direct Web Remoting (DWR)
  • Yahoo! User Interface (YUI) Toolkit
  • EXT JS
  • Google Web Toolkit (GWT)
Prototype is one of the most popular AJAX frameworks around.
postMsg : function(url, actId) {
var myAjax = new Ajax.Request(url,{
method: 'post',
parameters: 'actId='+escape(actId),
onComplete:handlerResult
});
},

Dojo is a popular, complete open source framework with broad support not only for Web widgets but also other important aspects of Web
application development such as interaction with backend systems.

dojo.io.bind({
url: url,
method: "post",
content: {actId: "123456"},
load: function(type, data, evt){/* callback code */ },
error: function(type, error){/* error handling callback */ },
mimetype: "text/plain"
});

DWR focus is making browser client/server interaction as simple and natural as possible.
public class PhoneService {
public String getCallerName(int callerNumber){...}
}
..script.. type="text/javascript" src="SVProvider/dwr/interface/PhoneService.js ..script..
PhoneService.getCallerName(18003456700, processPBXResponse)

YUI is an extremely rich, well documented, stable, and lush framework for AJAX-based development. YUI code is really professor feeling.
var requestFromObject = YAHOO.util.Connect.asynRequest('post', uri ,
callback , postData);
var callback = {
success: handleSuccess
failure: handleFailure
argument: {callerName: "N/A"}
};
Ext JS is another very popular Ajax framework. It also provides a XHR wrapper allowing quickly and efficiently perform AJAX requests.
Ext.Ajax.request({
url : '../listActivity.do' ,
params : { action : 'loadData' },
method: 'GET',
success: function ( result, request ) {
Ext.MessageBox.alert('Success', 'Data return from the server: '+ result.responseText);
},
failure: function ( result, request) {
Ext.MessageBox.alert('Failed', 'Successfully posted form: '+action.date);
}
});

Monday, April 02, 2007

JSF, Spring, iBatis integrate

Recently I created an application with JSF, Spring and iBatis. It seems pretty easy to integrate them together. Following list the system environment:
  • Tomcat - 5.5.23
  • Java - 1.5
  • JSF - 1.2
  • Spring - 2.0.3
  • iBatis - 2.3.0
  • database - Oracle
The system includes 3 simple configure file: applicationContext.xml, face-config.xml and sql-config.xml.



JSF have the following different features:
  • Swing-like object-oriented Web application development
  • Backing-bean management
  • Extensible UI component model
  • Flexible rendering model
  • Extensible conversion and validation model
However, one JSF thing that I really do not like is its huge configure file. For a big project, it huge configure file will make maintanance pretty hard.

A serviceLocator class is created in system to glue the JSF with Spring.



Like other persistence layers, iBATIS strives to ease the development of data-driven applications by abstracting the low-level details involved in database communication, as well as providing higher-level ORM capabilities. iBatis SQL Maps is a straightforward data access tool, working at the SQL level like JDBC code, but externalizing SQL statements and their result and parameter mappings into an XML file. Above figure shows the simple example for iBatis.

Thursday, March 01, 2007

Open JMS with Tomcat

In a loosely coupled and asynchronous communication, an application sends a message, and then continues program execution without waiting for a response. The sending program might not even know where or what the recipient is, because the communication between software components takes place via messaging. The Java Messaging Service (JMS) is the only messaging API supported by J2EE.

OpenJMS, a SourceForge project, is a free open source implementation of Sun Microsystems' JMS API specification.

Tuesday, February 06, 2007

iBATIS vs Hibernate

iBATIS works well when you need to integrate with an existing database.
Hibernate works well when you control the data model.

iBATIS maps Java Objects to the results of SQL Queries, whereas Hibernate maps Java Objects directly to database tables, traditional Object-Relational Mapping. The benefits of Hibernate are that it automatically generates all the SQL for your and the cache invalidation can be more fine grained. iBATIS is more flexible especially if you are a strong SQL query writer. You have control over exactly how the SQL queries are written.

Compared with Hibernate, iBATIS is more flexible, has a shorter learning curve, but can take more time to develop and maintain, since you have to write all your queries and if your object model changes you have to go through all your queries and make sure to make all the necessary changes to reflect the changes in your object model.

Tuesday, January 30, 2007

DWR integrate with Spring

DWR is a Java open source library which allows you to write Ajax web sites.

DWR consists of two main parts:

  • A Java Servlet running on the server that processes requests and sends responses back to the browser.
  • JavaScript running in the browser that sends requests and can dynamically update the webpage.
Why DWR:
  • mostly used Ajax framework
  • integrate best with Spring
  • RPC style Ajax
  • Java <--> Javascript marshalling (using Javascript objects)
  • Support most browser

Saturday, January 06, 2007

Yahoo YUI Calendar

Recently I start to look Yahoo YUI for rich UI. One feature is about Calendar. In general, YUI works pretty well with my application. However, one bug related to IE took me 2 days to figure it out.

When I click any date in Calendar. It subscribe to YUI render:
YAHOO.example.calendar.cal1.selectEvent.subscribe(mySelectDate, YAHOO.example.calendar.cal1, true);
YAHOO.example.calendar.cal1.addRenderer(txtDate1.value, YAHOO.example.calendar.cal1.renderCellStyleHighlight2);
YAHOO.example.calendar.cal1.render();
In my application, I need send new request to the server and get result for this specific date. It works well in Firefox, however, it does not always work in IE6. After dig for a while, there exist this code in YUI calendar.js:
YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell)
Exist: javascript:void(null) in href
IE does not pass javascript:void(null) in href.

href="javascript: ", onclick="javascript:" There is no such thing as a JavaScript protocol on the web. Links use protocols to connect documents.

Tuesday, January 02, 2007

Authentication and authorization - Acegi and More

Most of our web application are based on the form-based authorization and authentication - role based access control. Form-based authentication is the most popular web authentication mechanism in use. It provides us with the greatest control over the look and fell of the “login screen”.

Acegi provides a quick/simple/good solution for this. However, acegi also have some limitation:

1: Authentication

Acegi uses AuthenticationProcessingFilter. The AuthenticationProcessingFilter handles the Authentication Request Check (“logging into the application”). It uses the AuthenticationManager to do its work. One dsiadvantage is that we need create our login table based on the Acegi's wishes. And we also need access DB directly using SQL code.

2: Authorization

Acegi is based on the URL authorization. Secure URLs by role with regular expressions or ant-style pattern. First, role can not be added dynamically. Some actions (view and edit) use the same URLs, this bring problem for authorization.

To fix the above problem, we can build self simple security system.

Following list the tables relationship:



For each customer, it can create its own role and assign account to this role. For each service, there includes many features. And for each feature, it can be different privilege (verb: CRUD List etc). We can assign role to different privilege.

In each button/link field, we need add a parameter "privilegeCode", for example: privilegeCode=editAccount. We just need write a filter, this filter will check privilegeCode and login user privilege. If login user has this privilege, continue. Otherwise, permission deny.

Simple, easy and quick to fix the authorization issue in Acegi