Tuesday, November 13, 2012

Bug: Desktop and IDE freezes when debugging swing project

Desktop and IDE freezes and die when debugging swing project.

IDE: Intellij 11.1.4.
OS:  Redhat Enterprise 6.3.
JRE: Both 1.6 and 1.7.

Reason and solution:


The only reasonable solution to this problem is introducing the system property sun.awt.disablegrab which, if passed as the boolean value of true, effectively disables acquiring grabs on X11 platforms. If the user wishes to debug an application and sets a breakpoint in an event handler that gets fired while a popup window is opened (like a combobox popup), the user must specify this system property before debugging the application as follows:

   java -Dsun.awt.disablegrab=true ...<other_options>...

All known IDEs allow specifying the user-supplied command line options to the java command, making this solution easily adoptable. For instance, in Netbeans open the properties of the project, go to the Run section and type the text "-Dsun.awt.disablegrab=true" (w/o the quotes) into the VM Options editbox. Of course, the project must be configured to run with a JRE having the suggested fix in place.

Tuesday, October 16, 2012

Customise error message for missing parameter exception (400) when using Spring @Controller and @RequestParam.

I am working on a project which needs a REST resource to accept client request for sending emails.

The parameters required by this Resource are:
1) from: a valid email address to send mails.
2) subject: the subject of mail.
3) to: a valid email address the mail send to.
4) text: the content of mail.

Because our project is using Spring to do everything we need and it can do. So Spring Rest Controller is my best option to implement this Resource.

the declaration of my resource is:

 @RequestMapping ( method = { RequestMethod.POST, RequestMethod.GET } )  
 @ResponseStatus ( HttpStatus.OK )  
 public void sendEmail( @RequestParam ( value = "from" ) String from,  
                    @RequestParam ( value = "subject" ) String subject,  
                    @RequestParam ( value = "to" ) String to,  
                    @RequestParam ( value = "text" ) String text,  
                    final HttpServletResponse response ) throws Exception  

And I test it by using following url.

 url/subject=hello&to=sean@abc.com&text=this+is+hello+from+Sean  

Because the parameter from is missing and the system should return a 400 exception with the right error message:

 HTTP Status 400 - Required String parameter 'from' is not present  
 type Status report  
 message Required String parameter 'from' is not present  
 description The request sent by the client was syntactically incorrect (Required String parameter 'from' is not present).  
 Apache Tomcat/7.0.23  

however, what I get is:

 HTTP Status 400 -   
 type Status report  
 description The request sent by the client was syntactically incorrect ().  

So what I need is how to customise the error message.

Actually, Spring does provide an exception for this case, it called
MissingServletRequestParameterException and returned the correct error message that what exact we want. But for some reason, the client side did not get the correct error message, but only the right status code which is 400.

My Solution (Also the solution shared by people online already):

Create my own AnnotationMethodHandlerAdapter and override the method invokeHandlerMethod.

 public class AnnotationMethodExceptionHandlerAdapter extends  
         AnnotationMethodHandlerAdapter  
 {  
     @Override  
     protected ModelAndView invokeHandlerMethod( HttpServletRequest request,  
                           HttpServletResponse response, Object handler ) throws Exception  
     {  
         try  
         {  
             return super.invokeHandlerMethod( request, response, handler );  
         }  
         catch ( MissingServletRequestParameterException e )  
         {  
             request.setAttribute( "EXCEPTION_NAME", e.getClass().getName() );  
             response.sendError( HttpServletResponse.SC_BAD_REQUEST, e.getMessage() );  
             return null;  
         }  
         catch ( Exception e )  
         {  
             request.setAttribute( "EXCEPTION_NAME", e.getClass().getName() );  
             response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage() );  
             return null;  
         }  
     }  
 }  

I am not sure is there any exception which is not a MissingServletRequestParameterException can be thrown by  super.invokeHandlerMethod( request, response, handler ); and I do know what status should return in that case. So at here I just return 500.

And modify my servlet config.

 <!--To enable @RequestMapping process on type (class) level -->  
     <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
     <!--To enable @RequestMapping process on method level -->  
   <bean class="YourProjectPath.AnnotationMethodExceptionHandlerAdapter"/>  

Do not need use
 <mvc:annotation-driven/>  

Then you will get the correct error message.


As I mentioned before and you can seen below, Spring does return the correct error message, but I do not know why client can not get it.




Hope this is helpful to you if you are struggling with the same problem with I got.

Thursday, October 11, 2012

Spring – load property value using @Value


Spring – load multiple property based on utils properties code

pure utils:property, one location
With the utils namespace in Spring 3.0 you can load a property file and use the values in Spring EL expressions.
– Spring config File –
 <util:properties id="someProps" location="classpath:mybasic.properties" />  
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
     ...  
   <property name="url" value="jdbc:h2:tcp://localhost/~/DB/#{someProps['database.dbname']}" />  
   <property name="username" value="#{someProps['database.user']}" />  
   <property name="password" value="#{someProps['database.password']}" />  
     ...  
 </bean>  
To use the property values in Java classes use the the EL expression with the @Value annotation.
– Java code –
 ...  
 HINT:the name you use for someProps can not includes '-'(e.g. can not be  
 words like some-props)  
 String @Value("#{someProps['my.tmp.dir']}") tmpDir;  
 ...  
Multiple property files
Please visit author's page http://develop.nydi.ch/2010/12/spring-multiple-properties/

Wednesday, October 10, 2012

Set up JRebel on Intellij for Maven project.

What is JReble and what can it do for you?
http://en.wikipedia.org/wiki/JRebel

Step 1:

How to install JRebel plugin on your IDE (Intellij as example)?
http://zeroturnaround.com/software/jrebel/download/using-jrebel-with-intellij/

Step 2:

Configure JRebel for your maven project.



Add the following snippet to your parent pom.xml. The rebel.xml configuration file will be generated
for each individual sub-module of your maven project.

 <plugin>  
     <groupId>org.zeroturnaround</groupId>  
     <artifactId>jrebel-maven-plugin</artifactId>  
     <version>1.1.1</version>  
     <executions>  
         <execution>  
             <id>generate-rebel-xml</id>  
             <phase>process-resources</phase>  
             <goals>  
                 <goal>generate</goal>  
             </goals>  
         </execution>  
     </executions>  
 </plugin> 


      This will generate JRebel configuration file rebel.xml 
      automatically on every build. If you want to generate the rebel.xml 
      manually run mvn jrebel:generate -Drebel.xml.dir=OUTPUT_DIRECTORY 
      (by default OUTPUT_DIRECTORY is target/classes). 
      Adding -Drebel.generate.show=true will print out generated rebel.xml 
      at info level, so you can immediately see what was generated.
    

      By default, the generated rebel.xml contains absolute paths 
      to your workspace. However if you want to deploy the artifacts for your 
      team to use, you will need to make sure that the paths are relative 
      using a configurable custom property.


Step 3:

Set up JRebel for you tomcat.

Create a file startup-jrebel.sh in the dir of you TOMCAT_HOME/bin

and add following content into it.
 #!/bin/bash  
 export CATALINA_OPTS="-javaagent:/home/seaxio/.IdeaIC11/config/plugins/jr-ide-idea/lib/jrebel/jrebel.jar $CATALINA_OPTS"  
 `dirname $0`/catalina.sh $@  

Step 4:

Start debugging.

 Run sh startup-jrebel.sh jpda start  

Done. compaile your project (Itellij: ctrl + f9) after every code change.

Do not to redeploy your project and you can see the changes in the fly.

Thursday, September 27, 2012

svn: E165001: svn:eol-style related error

When we add a new file to svn and if this file type has not been configed for eol-style property, this error will returned when you try to commit.

How to fix it:

All we need to do is set eol-style property for this file type.

1) IDE: open the new added file and right click and select 'Subversion' then 'Set Property'.

2) edit your local subversion dir and edit the config file.
 cd ~/.subversion  
 open config and go to the bottom  
 add the following content (e.g. for .java file)  
 *.java = svn:eol-style=native  

Done.

Wednesday, September 26, 2012

Debugging a web application with IntelliJ IDEA

Step 1: go to your tomcat dir and run
             sh bin/catalina.sh jpda start
Step 2: find the port number tomcat is running on.
             ps aux |grep tomcat
             For me I got "address=8000"
Step 3:

 Open you project with IntelliJ IDEA, To do the following steps:
  1. Create a new Run/Debug configuration (click on the drop down list on the left of the green arrow icon) and "Edit configurations".
  2. Click on the '+' (plus) button and create a new "Maven" configuration.
  3. Give it a name.
  4. change the port number to what you get in Step 2.
  5. And you are good to go!
Step 4: just open you application normally. (not in the port number what you get in Step 2, just normal run port number.)

Wednesday, September 19, 2012

JAVA: use regex to validate date and time.

I tried to search correct regex for date and time on google and found that many of them are not working.

Finally, I found the correct one and the java methods shows below.
 /**  
  * Check that a date is formatted according to the following convention:  
  * DD/MM/YYYY OR DD.MM.YYYY OR DD-MM-YYYY  
  * @param dateStr a date string.  
  * @return true if the date text should be rejected  
  */  
  private boolean invalidDate(String dateStr) {  
  String regex = "^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\\d\\d$";  
  return !Pattern.matches(regex, dateStr);  
  }  
  /**  
  * Check that a time is formatted according to the following convention:  
  * HH:MM:SS AM/PM  
  * @param timeStr a time string.  
  * @return true if the time text should be rejected  
  */  
  private boolean invalidTime(String timeStr) {  
  String regex = "^(([0]?[1-9])|([1][0-2])):(([0-5][0-9])|([1-9])):([0-5][0-9]) [AP][M]$";  
  return !Pattern.matches(regex, timeStr);  
  }  

Friday, September 14, 2012

A very good article to explain what's the difference between "iterative vs incremental"

A very good article to explain what's the difference between  "iterative vs incremental"  (see http://gojko.net/2007/12/04/waterfall-trap/).

And plz read the comments, it gives you more practise examples and experience. 

Tuesday, September 4, 2012

subtree merge on GIT



Say merge a project A as a subtree to project B.
 git remote add -f b/a git+ssh://'git repo path'/a.git  
 git merge -s ours --no-commit b/a/master   
 git read-tree --prefix=b/a -u b/a/master   
 git commit -m "Subtree merged a"  

Friday, July 6, 2012

Share your keyboard and mouse among multiple Computer

Very useful to these people who have to work on different OS paralleled, forget about install VM of one OS on another OS.

Synergy lets you easily share your mouse and keyboard between multiple computers on your desk, and it's Free and Open Source. Just move your mouse off the edge of one computer's screen on to another. You can even share all of your clipboards. All you need is a network connection. Synergy is cross-platform (works on Windows, Mac OS X and Linux).

More info  

Wednesday, June 6, 2012

Jason Fung Blog: The letter analogy for REST vs. SOAP

Jason Fung Blog: The letter analogy for REST vs. SOAP: A nice analogy for REST vs. SOAP is mailing a letter: with SOAP, you're using an envelope; with REST, it's a postcard. Postcards are easie...

Tuesday, May 8, 2012

Bugs in the code which automatically generated by MyEclipse

Bugs in the code which automatically generated by MyEclipse.

The implementation of equals method to compare two Integers used by automatically generated code is integer1 == integer2, and this is wrong.

Integer is boxed type for primitive type int and Integers are objects, so logical equality check method equals should be used rather than identically comparison ==.

example.


import javax.persistence.Column;
import javax.persistence.Embeddable;

/**
 * AssetassetId entity. @author MyEclipse Persistence Tools
 */
@Embeddable
public class AssetassetId implements java.io.Serializable {

// Fields

private Integer assetid1;
private Integer assetid2;

// Constructors

/** default constructor */
public AssetassetId() {
}

/** full constructor */
public AssetassetId(Integer assetid1, Integer assetid2) {
this.assetid1 = assetid1;
this.assetid2 = assetid2;
}

// Property accessors

@Column(name = "assetid1", nullable = false)
public Integer getAssetid1() {
return this.assetid1;
}

public void setAssetid1(Integer assetid1) {
this.assetid1 = assetid1;
}

@Column(name = "assetid2", nullable = false)
public Integer getAssetid2() {
return this.assetid2;
}

public void setAssetid2(Integer assetid2) {
this.assetid2 = assetid2;
}

public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof AssetassetId))
return false;
AssetassetId castOther = (AssetassetId) other;

return ((this.getAssetid1().equals(castOther.getAssetid1())) || (this
.getAssetid1() != null
&& castOther.getAssetid1() != null && this.getAssetid1()
.equals(castOther.getAssetid1())))
&& ((this.getAssetid2().equals(castOther.getAssetid2())) || (this
.getAssetid2() != null
&& castOther.getAssetid2() != null && this
.getAssetid2().equals(castOther.getAssetid2())));
}

public int hashCode() {
int result = 17;

result = 37 * result
+ (getAssetid1() == null ? 0 : this.getAssetid1().hashCode());
result = 37 * result
+ (getAssetid2() == null ? 0 : this.getAssetid2().hashCode());
return result;
}

}

Friday, April 20, 2012

The beauty of Fluent Interface.

Recently I read "Fluent Interface" posted on Martin Fowler's blog and found that I really like it. It uses human readable syntax to implement Interfaces. Similar idea with Java Builder pattern.

Here I share this post Fluent Interface.

Monday, February 6, 2012

Generating a CSR and Installing an SSL Certificate in Tomcat 4.x/5.x/6.x

This article owned by GoDaddy and you can find the original one via http://support.godaddy.com/help/article/5239


When you request an SSL certificate, you must provide a Certificate Signing Request (CSR) from your server. The CSR includes your public key, and must contain the same details as the online request form in your account. After your request is vetted and your certificate is issued, download and install all of the provided files to complete the installation.
NOTE: These steps describe how to install a certificate using keytool, so you must have Java 2 SDK 1.2 or above installed on your server.

Generating a Keystore and CSR in Tomcat


Using Keytool, follow these steps to generate a keystore and CSR on your server.

To Generate a Keystore and CSR in Tomcat

  1. Enter the following command into keytool to create a keystore:
    keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore
  2. Enter a Password. The default is changeit.
  3. Enter Distinguished Information:
    • First and Last Name — The fully-qualified domain name, or URL, you're securing. If you are requesting a Wildcard certificate, add an asterisk (*) to the left of the common name where you want the wildcard, for example*.coolexample.com.
    • Organizational Unit — Optional. If applicable, you can enter the DBA name in this field.
    • Organization — The full legal name of your organization. The listed organization must be the legal registrant of the domain name in the certificate request. If you are enrolling as an individual, please enter the certificate requestor's name in Organization, and the DBA (doing business as) name in Organizational Unit.
    • City/Locality — Name of the city in which your organization is registered/located — do not abbreviate.
    • State/Province — Name of state or province where your organization is located — do not abbreviate.
    • Country Code — The two-letter International Organization for Standardization (ISO) format country code for where your organization is legally registered.
  4. Enter the following command into keytool to create a CSR:
    keytool -certreq -keyalg RSA -alias tomcat -file csr.csr -keystore tomcat.keystore
  5. Enter the Password you provided in Step 2.
  6. Open the CSR file, and copy all of the text
    (include ----BEGIN NEW CERTIFICATE REQUEST---- and ----END CERTIFICATE REQUEST----).
  7. Paste all of the text into the online request form and complete your application.
For more information about completing the online request form, see Requesting a Standard SSL Certificate.
After you submit the application, we begin vetting your request. You will receive an email with more information when this process is complete.
OR Generating your self signed ssl certificates based on the csr created.  

------------------------------------------------------------------------------------------------------------------------------------------------------------------
Generating private keys (in the format of p12 and pem) which may be used by Google AppEngine:

1) keytool -importkeystore -srckeystore keystore.jks(Or your keystrore in other formats like .keystore) -destkeystore intermediate.p12 -deststoretype PKCS12
2) openssl pkcs12 -in intermediate.p12 -out extracted.pem –nodes
 
------------------------------------------------------------------------------------------------------------------------------------------------------------------


Installing Your SSL in Tomcat


After the certificate is issued, download it from the Certificate Manager and place it in the same folder as your keystore.
You can also download the intermediate certificates from therepository.

To Install Your SSL in Tomcat

Using keytool, enter the following commands to install the certificates.
  1. Install the Root certificate:
    keytool -import -alias root -keystore tomcat.keystore -trustcacerts -file valicert_class2_root.crt
  2. Install the first intermediate (gd_cross_intermediate.crt):
    keytool -import -alias cross -keystore tomcat.keystore -trustcacerts -file gd_cross_intermediate.crt
  3. Install the second intermediate (gd_intermediate.crt):
    keytool -import -alias intermed -keystore tomcat.keystore -trustcacerts -file gd_intermediate.crt
  4. Install the issued certificate:
    keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts -file <name of your certificate>
After importing the certificates into the keystore, you need to update the server.xml file in the Tomcat directory with the correct keystore location.
NOTE: The HTTPS connector is commented out by default. Remove the comment tags to enable HTTPS.
Tomcat 4.x — Update the following elements in server.xml for Tomcat 4.x:
<Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
clientAuth="false"
protocol="TLS" keystoreFile="/etc/tomcat5/tomcat.keystore"
keystorePass="changeit" />
Tomcat 5.x, 6.x and 7.x — Update the following elements in server.xml for Tomcat 5.x, 6.x and 7.x:
<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> <!-- <Connector port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="path to your keystore file" keystorePass="changeit" clientAuth="false" sslProtocol="TLS"/>
After you save changes to server.xml, restart Tomcat to begin using your SSL.

Wednesday, January 4, 2012

XMLVM is to offer a flexible and extensible cross-compiler toolchain.

Really cool tool.


http://xmlvm.org/overview/


The goal of XMLVM is to offer a flexible and extensible cross-compiler toolchain. Instead of cross-compiling on a source code level, XMLVM cross-compiles byte code instructions from Sun Microsystem's virtual machine and Microsoft's Common Language Runtime. The benefit of this approach is that byte code instructions are easier to cross-compile and the difficult parsing of a high-level programming language is left to a regular compiler. In XMLVM, byte code-based programs are represented as XML documents. This allows manipulation and translation of XMLVM-based programs using advanced XML technologies such as XSLT, XQuery, and XPath.
XMLVM serves as an umbrella for several projects. For all projects, a Java class file or a .NET executable is first translated to an XML-document. Based on the XML-document generated by the front-end, various transformations are possible. The first transformation cross-compiles from .NET to JVM byte code. Another transformation enables Java or .NET applications to be cross-compiled to JavaScript so that they can run as AJAX applications in any browser. Yet another transformation allows to cross-compile a Java program to Objective-C to create a native iPhone application.

Tuesday, January 3, 2012

How to create a self-signed SSL Certificate ...


This tutorial is copied from http://www.akadia.com/services/ssh_test_certificate.html.



How to create a self-signed
 SSL Certificate ...

...  which can be used for testing purposes or internal usage

Overview
The following is an extremely simplified view of how SSL is implemented and what part the certificate plays in the entire process.
Normal web traffic is sent unencrypted over the Internet. That is, anyone with access to the right tools can snoop all of that traffic. Obviously, this can lead to problems, especially where security and privacy is necessary, such as in credit card data and bank transactions. The Secure Socket Layer is used to encrypt the data stream between the web server and the web client (the browser).
SSL makes use of what is known as asymmetric cryptography, commonly referred to as public key cryptography (PKI). With public key cryptography, two keys are created, one public, one private. Anything encrypted with either key can only be decrypted with its corresponding key. Thus if a message or data stream were encrypted with the server's private key, it can be decrypted only using its corresponding public key, ensuring that the data only could have come from the server.
If SSL utilizes public key cryptography to encrypt the data stream traveling over the Internet, why is a certificate necessary? The technical answer to that question is that a certificate is not really necessary - the data is secure and cannot easily be decrypted by a third party. However, certificates do serve a crucial role in the communication process. The certificate, signed by a trusted Certificate Authority (CA), ensures that the certificate holder is really who he claims to be. Without a trusted signed certificate, your data may be encrypted, however, the party you are communicating with may not be whom you think. Without certificates, impersonation attacks would be much more common.
Step 1: Generate a Private Key
The openssl toolkit is used to generate an RSA Private Key and CSR (Certificate Signing Request). It can also be used to generate self-signed certificates which can be used for testing purposes or internal usage.
The first step is to create your RSA Private Key. This key is a 1024 bit RSA key which is encrypted using Triple-DES and stored in a PEM format so that it is readable as ASCII text.
openssl genrsa -des3 -out server.key 1024
Generating RSA private key, 1024 bit long modulus
.........................................................++++++
........++++++
e is 65537 (0x10001)
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
Step 2: Generate a CSR (Certificate Signing Request)
Once the private key is generated a Certificate Signing Request can be generated. The CSR is then used in one of two ways. Ideally, the CSR will be sent to a Certificate Authority, such as Thawte or Verisign who will verify the identity of the requestor and issue a signed certificate. The second option is to self-sign the CSR, which will be demonstrated in the next section.
During the generation of the CSR, you will be prompted for several pieces of information. These are the X.509 attributes of the certificate. One of the prompts will be for "Common Name (e.g., YOUR name)". It is important that this field be filled in with the fully qualified domain name of the server to be protected by SSL. If the website to be protected will be https://public.akadia.com, then enter public.akadia.com at this prompt. The command to generate the CSR is as follows:
openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [GB]:CH
State or Province Name (full name) [Berkshire]:Bern
Locality Name (eg, city) [Newbury]:Oberdiessbach
Organization Name (eg, company) [My Company Ltd]:Akadia AG
Organizational Unit Name (eg, section) []:Information Technology
Common Name (eg, your name or your server's hostname) []:public.akadia.com
Email Address []:martin dot zahn at akadia dot ch
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Step 3: Remove Passphrase from Key
One unfortunate side-effect of the pass-phrased private key is that Apache will ask for the pass-phrase each time the web server is started. Obviously this is not necessarily convenient as someone will not always be around to type in the pass-phrase, such as after a reboot or crash. mod_ssl includes the ability to use an external program in place of the built-in pass-phrase dialog, however, this is not necessarily the most secure option either. It is possible to remove the Triple-DES encryption from the key, thereby no longer needing to type in a pass-phrase. If the private key is no longer encrypted, it is critical that this file only be readable by the root user! If your system is ever compromised and a third party obtains your unencrypted private key, the corresponding certificate will need to be revoked. With that being said, use the following command to remove the pass-phrase from the key:
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
The newly created server.key file has no more passphrase in it.
-rw-r--r-- 1 root root 745 Jun 29 12:19 server.csr
-rw-r--r-- 1 root root 891 Jun 29 13:22 server.key
-rw-r--r-- 1 root root 963 Jun 29 13:22 server.key.org
Step 4: Generating a Self-Signed Certificate
At this point you will need to generate a self-signed certificate because you either don't plan on having your certificate signed by a CA, or you wish to test your new SSL implementation while the CA is signing your certificate. This temporary certificate will generate an error in the client browser to the effect that the signing certificate authority is unknown and not trusted.
To generate a temporary certificate which is good for 365 days, issue the following command:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=/C=CH/ST=Bern/L=Oberdiessbach/O=Akadia AG/OU=Information
Technology/CN=public.akadia.com/Email=martin dot zahn at akadia dot ch
Getting Private key
Step 5: Installing the Private Key and Certificate
When Apache with mod_ssl is installed, it creates several directories in the Apache config directory. The location of this directory will differ depending on how Apache was compiled.
cp server.crt /usr/local/apache/conf/ssl.crt
cp server.key /usr/local/apache/conf/ssl.key
Step 6: Configuring SSL Enabled Virtual Hosts
SSLEngine on
SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
CustomLog logs/ssl_request_log \
   "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
Step 7: Restart Apache and Test
/etc/init.d/httpd stop
/etc/init.d/httpd stop
https://public.akadia.com

Sunday, January 1, 2012

Restlet 2.0x Tutorial

Copyright belong to Restlet.org  
This doc can also find at https://docs.google.com/document/pub?id=14ye-FoJoLe8hkAKfylwnSK9AVEfdoXofkmIwFBAw1n8


Restlet 2.0 - Tutorial

Table of contents

  1. Restlet overview
  2. Retrieving the content of a Web page
  3. Listening to Web browsers
  4. Overview of a REST architecture
  5. Components, virtual hosts and applications
  6. Serving static files
  7. Access logging
  8. Displaying error pages
  9. Guarding access to sensitive resources
  10. URI rewriting, attribute extraction and redirection
  11. Routers and hierarchical URIs
  12. Reaching target Resources
  13. Conclusion

1. Restlet overview

The Restlet framework is composed of two main parts. First, there is the "Restlet API", a neutral API supporting the concepts of REST and facilitating the handling of calls for both client-side and server-side applications. This API is backed by the Restlet Engine and both are now shipped in a single JAR ("org.restlet.jar").
Framework structure
This separation between the API and the implementation is similar to the one between the Servlet API and Web containers like Jetty or Tomcat, or between the JDBC API and concrete JDBC drivers.

2. Retrieving the content of a Web page

As we mentioned in the introduction paper, the Restlet framework is at the same time a client and a server framework. For example, Restlet can easily work with remote resources using its HTTP client connector. A connector in REST is a software element that enables the communication between components, typically by implementing one side of a network protocol. Restlet provides several implementations of client connectors based on existing open-source projects. The connectors section lists all available client and server connectors and explain how to use and configure them.
Here we will get the representation of an existing resource and output it in the JVM console:
  1. // Outputting the content of a Web page  
  2. new ClientResource("http://www.restlet.org").get().write(System.out);  
  3.      
Note that the example above uses a simplified way to issue calls via the ClientResource class. If you need multi-threading or more control it is still possible to manipulate use the Client connector class or the Request objects directly. The example below how to set some preferences in your client call, like a referrer URI. It could also be the languages and media types you prefer to receive as a response:
  1. // Create the client resource  
  2. ClientResource resource = new ClientResource("http://www.restlet.org");  
  3.   
  4. // Customize the referrer property  
  5. resource.setReferrerRef("http://www.mysite.org");  
  6.   
  7. // Write the response entity on the console  
  8. resource.get().write(System.out);  
  9.      

3. Listening to Web browsers

Now, we want to see how the Restlet framework can listen to client requests and reply to them. We will use the internal Restlet HTTP server connector (even though it is possible to switch to others such as the one based on Mortbay's Jetty) and return a simple string representation "hello, world" as plain text. Note that the Part03 class extends the base ServerResource class provided by Restlet:
  1. public class Part03 extends ServerResource {  
  2.   
  3.     public static void main(String[] args) throws Exception {  
  4.         // Create the HTTP server and listen on port 8182  
  5.         new Server(Protocol.HTTP, 8182, Part03.class).start();  
  6.     }  
  7.   
  8.     @Get  
  9.     public String toString() {  
  10.         return "hello, world";  
  11.     }  
  12.   
  13. }  
  14.      
If you run this code and launch your server, you can open a Web browser and hit the http://localhost:8182. Actually, any URI will work, try also http://localhost:8182/test/tutorial. Note that if you test your server from a different machine, you need to replace "localhost" by either the IP address of your server or its domain name if it has one defined.
So far, we have mostly showed you the highest level of abstraction in the Restlet API, with the ClientResource and ServerResource classes. But as we move forward, you will discover that those two classes are supported by a rich API, letting you manipulate all the REST artifacts.

4. Overview of a REST architecture

Let's step back a little and consider typical web architectures from a REST point of view. In the diagram below, ports represent the connector that enables the communication between components which are represented by the larger boxes. The links represents the particular protocol (HTTP, SMTP, etc.) used for the actual communication.
REST architecture
Note that the same component can have any number of client and server connectors attached to it. Web Server B, for example, has both a server connector to respond to requests from the User Agent component, and client connectors to send requests to Web Server A and the Mail Server.

5. Components, virtual hosts and applications

In addition to supporting the standard REST software architecture elements as presented before, the Restlet framework also provides a set of classes that greatly simplify the hosting of multiple applications within a single JVM. The goal is to provide a RESTful, portable and more flexible alternative to the existing Servlet API. In the diagram below, we can see the three types of Restlets that are provided in order to manage these complex cases. Components can manage several Virtual Hosts and Applications.
Virtual Hosts support flexible configuration where, for example, the same IP address is shared by several domain names, or where the same domain name is load-balanced across several IP addresses. Finally, we use Applications to manage a set of related Restlets, Resources and Representations. In addition, Applications are ensured to be portable and reconfigurable over different Restlet implementations and with different virtual hosts. In addition, they provide important services like access logging, automatic decoding of request entities, configurable status page setting and more!
Restlet components, virtual hosts and applications
In order to illustrate these classes, let's examine a simple example. Here we create a Component, then add an HTTP server connector to it, listening on port 8182. Then we create a simple trace Restlet and attach it to the defaut VirtualHost of the Component. This default host is catching any request that wasn't already routed to a declared VirtualHost (see the Component.hosts property for details). In a later example, we will also introduce the usage of the Application class. Note that for now you don't see any access log displayed in the console.
  1. public static void main(String[] args) throws Exception {  
  2.     // Create a new Restlet component and add a HTTP server connector to it  
  3.     Component component = new Component();  
  4.     component.getServers().add(Protocol.HTTP, 8182);  
  5.   
  6.     // Then attach it to the local host  
  7.     component.getDefaultHost().attach("/trace", Part05.class);  
  8.   
  9.     // Now, let's start the component!  
  10.     // Note that the HTTP server connector is also automatically started.  
  11.     component.start();  
  12. }  
  13.   
  14. @Get  
  15. public String toString() {  
  16.     // Print the requested URI path  
  17.     return "Resource URI  : " + getReference() + '\n' + "Root URI      : "  
  18.             + getRootRef() + '\n' + "Routed part   : "  
  19.             + getReference().getBaseRef() + '\n' + "Remaining part: "  
  20.             + getReference().getRemainingPart();  
  21. }  
  22.      
Now let's test it by entering http://localhost:8182/trace/abc/def?param=123 in a Web browser. Here is the result that you will get:
Resource URI  : http://localhost:8182/trace/abc/def?param=123
Root URI      : http://localhost:8182/trace
Routed part   : http://localhost:8182/trace
Remaining part: /abc/def?param=123
   

6. Serving static files

Do you have a part of your web application that serves static pages like Javadocs? Well, no need to setup an Apache server just for that, use instead the dedicated Directory class. See how simple it is to use it:
  1. // URI of the root directory.  
  2. public static final String ROOT_URI = "file:///c:/restlet/docs/api/";  
  3.   
  4. [...]  
  5.   
  6. // Create a component  
  7. Component component = new Component();  
  8. component.getServers().add(Protocol.HTTP, 8182);  
  9. component.getClients().add(Protocol.FILE);  
  10.   
  11. // Create an application  
  12. Application application = new Application() {  
  13.     @Override  
  14.     public Restlet createInboundRoot() {  
  15.             return new Directory(getContext(), ROOT_URI);  
  16.     }  
  17. };  
  18.   
  19. // Attach the application to the component and start it  
  20. component.getDefaultHost().attach(application);  
  21. component.start();  
  22.      
In order to run this example, you need to specify a valid value for ROOT_URI, In this case, it is set to "file:///c:/restlet/docs/api/". Note that no additional configuration is needed. If you want to customize the mapping between file extensions and metadata (media type, language or encoding) or if you want to specify a different index name, you can use the Application's "metadataService" property.

7. Access logging

Being able to properly log the activity of a Web application is a common requirement. Restlet Components know by default how to generate Apache-like logs or even custom ones. By taking advantage of the logging facility built in the JDK, the logger can be configured like any standard JDK log to filter messages, reformat them or specify where to send them. Rotation of logs is also supported; see the java.util.logging package for details.
Note that you can customize the logger name given to the java.util.logging framework by modifying the Component's "logService" property. In order to fully configure the logging, you need to declare a configuration file by setting a system property like:
  1. System.setProperty("java.util.logging.config.file",  
  2.         "/your/path/logging.config");  
  3.      
For details on the configuration file format, please check the JDK's LogManager class.
You can also have a look at the Restlet 2.0 logging documentation.

8. Displaying error pages

Another common requirement is the ability to customize the status pages returned when something didn't go as expected during the call handling. Maybe a resource was not found or an acceptable representation isn't available? In this case, or when any unhandled exception is be intercepted, the Application or the Component will automatically provide a default status page for you. This service is associated to the org.restlet.util.StatusService class, which is accessible as an Application and Component property called "statusService".
In order to customize the default messages, you will simply need to create a subclass of StatusService and override the getRepresentation(Status, Request, Response) method. Then just set an instance of your custom service to the appropriate "statusService" property.

9. Guarding access to sensitive resources

When you need to secure the access to some Restlets, several options are available. A common way is to rely on cookies to identify clients (or client sessions) and to check a given user ID or session ID against your application state to determine if access should be granted. Restlets natively support cookies via the Cookie andCookieSetting objects accessible from a Request or a Response.
There is another way based on the standard HTTP authentication mechanism. The Noelios Restlet Engine currently accepts credentials sent and received in the Basic HTTP scheme and also the credentials sent in the Amazon Web Services scheme.
When receiving a call, developers can use the parsed credentials available in Request.challengeResponse.identifier/secret via the ChallengeAuthenticator filter. Filters are specialized Restlets that can pre-process a call before invoking and attached Restlet or post-process a call after the attached Restlet returns it. If you are familiar with the Servlet API, the concept is similar to the Filter interface. See below how we would modify the previous example to secure the access to the Directory:
  1. // Create a simple password verifier  
  2. MapVerifier verifier = new MapVerifier();  
  3. verifier.getLocalSecrets().put("scott""tiger".toCharArray());  
  4.   
  5. // Create a Guard  
  6. ChallengeAuthenticator guard = new ChallengeAuthenticator(  
  7.                 getContext(), ChallengeScheme.HTTP_BASIC, "Tutorial");  
  8. guard.setVerifier(verifier);  
  9.   
  10. // Create a Directory able to return a deep hierarchy of files  
  11. Directory directory = new Directory(getContext(), ROOT_URI);  
  12. directory.setListingAllowed(true);  
  13. guard.setNext(directory);  
  14.   
  15. return guard;  
  16.      
Call handling flow
Note that the authentication and authorization decisions are clearly considered as distinct concerns and are fully customizable via dedicated filters that inherit from the Authenticator (such as ChallengeAuthenticator) and the Authorizer abstract classes. Here we simply hard-coded a single user and password couple. In order to test, let's use the client-side Restlet API:
  1. // Prepare the request  
  2. ClientResource resource = new ClientResource("http://localhost:8182/");  
  3.   
  4. // Add the client authentication to the call  
  5. ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;  
  6. ChallengeResponse authentication = new ChallengeResponse(scheme,  
  7.         "scott""tiger");  
  8. resource.setChallengeResponse(authentication);  
  9.   
  10. // Send the HTTP GET request  
  11. resource.get();  
  12.   
  13. if (resource.getStatus().isSuccess()) {  
  14.     // Output the response entity on the JVM console  
  15.     resource.getResponseEntity().write(System.out);  
  16. else if (resource.getStatus()  
  17.         .equals(Status.CLIENT_ERROR_UNAUTHORIZED)) {  
  18.     // Unauthorized access  
  19.     System.out  
  20.             .println("Access authorized by the server, check your credentials");  
  21. else {  
  22.     // Unexpected status  
  23.     System.out.println("An unexpected status was returned: "  
  24.             + resource.getStatus());  
  25. }  
  26.      
You can change the user ID or password sent by this test client in order to check the response returned by the server. Remember to launch the previous Restlet server before starting your client. Note that if you test your server from a different machine, you need to replace "localhost" by either the IP address of your server or its domain name when typing the URI in the browser. The server won't need any adjustment due to the usage of a VirtualHost which accepts all types of URIs by default.

10. URI rewriting and redirection

Another advantage of the Restlet framework is the built-in support for cool URIs. A good description of the importance of proper URI design is given by Jacob Nielsen in his AlertBox.
The first tool available is the Redirector, which allows the rewriting of a cool URI to another URI, followed by an automatic redirection. Several types of redirection are supported, the external redirection via the client/browser and the connector redirection for proxy-like behavior. In the example below, we will define a search service for our web site (named "mysite.org") based on Google. The "/search" relative URI identifies the search service, accepting some keywords via the "kwd" parameter:
  1. // Create a root router  
  2. Router router = new Router(getContext());  
  3.   
  4. // Create a Redirector to Google search service  
  5. String target = "http://www.google.com/search?q=site:mysite.org+{keywords}";  
  6. Redirector redirector = new Redirector(getContext(), target,  
  7.         Redirector.MODE_CLIENT_TEMPORARY);  
  8.   
  9. // While routing requests to the redirector, extract the "kwd" query  
  10. // parameter. For instance :  
  11. // http://localhost:8182/search?kwd=myKeyword1+myKeyword2  
  12. // will be routed to  
  13. // http://www.google.com/search?q=site:mysite.org+myKeyword1%20myKeyword2  
  14. Extractor extractor = new Extractor(getContext(), redirector);  
  15. extractor.extractQuery("keywords""kwd"true);  
  16.   
  17. // Attach the extractor to the router  
  18. router.attach("/search", extractor);  
  19.      
Note that the Redirector needs three parameters only. The first is the parent context, the second one defines how the URI rewriting should be done, based on a URI template. This template will be processed by the Templateclass. The third parameter defines the type of redirection; here we chose the client redirection, for simplicity purpose.
Also, we are relying on the Route class to extract the query parameter "kwd" from the initial request while the call is routed to the application. If the parameter is found, it is copied into the request attribute named "keywords", ready to be used by the Redirector when formatting its target URIs.

11. Routers and hierarchical URIs

In addition to the Redirector, we have another tool to manage cool URIs: Routers. They are specialized Restlets that can have other Restlets (Finders and Filters for example) attached to them and that can automatically delegate calls based on a URI template. In general, you will set a Router as the root of your Application.
Here we want to explain how to handle the following URI patterns:
  1. /docs/ to display static files
  2. /users/{user} to display a user account
  3. /users/{user}/orders to display the orders of a particular user
  4. /users/{user}/orders/{order} to display a specific order
The fact that these URIs contain variable parts (between accolades) and that no file extension is used makes it harder to handle them in a typical Web container. Here, you just need to attach target Restlets to a Router using the URI template. At runtime, the route that best matches the request URI will received the call and be able to invoke its attached Restlet. At the same time, the request's attributes map will be automatically updated with the value of the URI template variables!
Call handling flow
See the implementation code below. In a real application, you will probably want to create separate subclasses instead of the anonymous ones we use here:
  1. // Create a root router  
  2. Router router = new Router(getContext());  
  3.   
  4. // Attach a guard to secure access to the directory  
  5. Guard guard = new Guard(getContext(), ChallengeScheme.HTTP_BASIC,  
  6.         "Restlet tutorial");  
  7. guard.getSecrets().put("scott""tiger".toCharArray());  
  8. router.attach("/docs/", guard);  
  9.   
  10. // Create a directory able to expose a hierarchy of files  
  11. Directory directory = new Directory(getContext(), ROOT_URI);  
  12. guard.setNext(directory);  
  13.   
  14. // Create the account handler  
  15. Restlet account = new Restlet() {  
  16.     @Override  
  17.     public void handle(Request request, Response response) {  
  18.         // Print the requested URI path  
  19.         String message = "Account of user \""  
  20.                 + request.getAttributes().get("user") + "\"";  
  21.         response.setEntity(message, MediaType.TEXT_PLAIN);  
  22.     }  
  23. };  
  24.   
  25. // Create the orders handler  
  26. Restlet orders = new Restlet(getContext()) {  
  27.     @Override  
  28.     public void handle(Request request, Response response) {  
  29.         // Print the user name of the requested orders  
  30.         String message = "Orders of user \""  
  31.                 + request.getAttributes().get("user") + "\"";  
  32.         response.setEntity(message, MediaType.TEXT_PLAIN);  
  33.     }  
  34. };  
  35.   
  36. // Create the order handler  
  37. Restlet order = new Restlet(getContext()) {  
  38.     @Override  
  39.     public void handle(Request request, Response response) {  
  40.         // Print the user name of the requested orders  
  41.         String message = "Order \""  
  42.                 + request.getAttributes().get("order")  
  43.                 + "\" for user \""  
  44.                 + request.getAttributes().get("user") + "\"";  
  45.         response.setEntity(message, MediaType.TEXT_PLAIN);  
  46.     }  
  47. };  
  48.   
  49. // Attach the handlers to the root router  
  50. router.attach("/users/{user}", account);  
  51. router.attach("/users/{user}/orders", orders);  
  52. router.attach("/users/{user}/orders/{order}", order);  
  53.      
Note that the routing assumes that your request contains an absolute target URI that identifies a target resource. During the request processing the resource's base URI is continuously updated, for each level in the hierarchy of routers. This explains why the default behavior of routers is to match only the beginning of the remaining URI part and not the totality of it. In some cases, you might want to change this default mode, and this is easy to do via the "defaultMatchingMode" property on Router, or by modifying the "matchingMode" property of the template associated with the route created by the Router.attach() methods. For the modes, you can use the Template.MODE_EQUALS or Template.MODE_STARTS_WITH constants.
Please note that the values of the variables are directly extracted from the URI and are therefore not percent-decoded. In order to achieve such a task, have a look to the Reference#decode(String) method.

12. Reaching target Resources

In the previous example, we took advantage of the flexible routing features of the framework to route the requests while extracting interesting parts from the target URI. But, we didn't pay attention to the request method, nor to the client preferences regarding the response that he expects. Also, how do we connect our Restlet resources with the backend systems, the domain objects?
So far, we introduced features that go beyond the traditional Servlet API and introduced our support for REST that justify our Restlet name! If haven't done so already, you can learn more about the REST architecture style and the best practices to follow when applying it to a Web application. There is a related FAQ entry that will give you some starting pointers and we also maintain a REST search engine (based on Google) that can be useful. If you have some experience with a traditional MVC framework, you can read more about the relationship to Restlets in this other FAQ entry.
To summarize, a request contains an URI that identifies the target resource that is the subject of the call. This information is stored in the Request.resourceRef property and serves as the basis of the routing as we saw. So the first goal when handling a request is to find the target resource which is in the framework... an instance of the ServerResource class or more precisely one of its subclasses. To help us in this task, we can use the dedicated Finder, a subclass of Restlet, which takes a ServerResource class reference as an argument and which will automatically instantiate it when a request comes in. The resource will dynamically dispatch the call to either a matching annotated method or to a predefined method (get(), post(), put(), delete(), etc.). Of course, this behavior can be customized. There is even an attach() method on Router that can take two arguments, an URI template and a ServerResource class and that transparently creates the Finder for you. Now, let's have a look at this overall diagram, showing the relationship between the main framework classes involved in this example:
Component diagram
Back to the code, here is our refactored Application.createRoot() method. For simplicity purpose, we didn't keep the Directory serving static files as this part wouldn't change. You can notice the way that resource classes are directly attached to the router.
  1. // Create a router  
  2. Router router = new Router(getContext());  
  3.   
  4. // Attach the resources to the router  
  5. router.attach("/users/{user}", UserResource.class);  
  6. router.attach("/users/{user}/orders", OrdersResource.class);  
  7. router.attach("/users/{user}/orders/{order}", OrderResource.class);  
  8.      
We will finally review one of the resource classes, the UserResource class. This class derives from org.restlet.resource.ServerResource. We override the init() method to retrieve the attribute "user" that is automatically extracted from the "/users/{user}" URI template and store its value in a convenient member variable. At this point, in a full application, we would lookup our associated "user" domain object. Finally, we declare a toString() method that supports the GET method as indicated by the @Get annotation.
  1. public class UserResource extends ServerResource {  
  2.     String userName;  
  3.   
  4.     Object user;  
  5.   
  6.     @Override  
  7.     public void init() {  
  8.         this.userName = (String) getRequestAttributes().get("user");  
  9.         this.user = null// Could be a lookup to a domain object.  
  10.     }  
  11.   
  12.     @Get  
  13.     public String toString() {  
  14.         return "Account of user \"" + this.userName + "\"";  
  15.     }  
  16. }  
  17.      
You can have a look at the rest of the code in the tutorial package and test the application. You will obtain the same behavior as in Part11, with the difference that only GET requests will be accepted. If you want to enable PUT for example, you have to create a Java method in UserResource and annotate it with @Put. You can check the Javadocs for further details.

Conclusion

We have already covered many aspects of the framework. Before you move on by yourself, let's take a step back and look at two hierarchy diagrams showing the main concepts covered in this tutorial and their relationships:
Restlet hierarchy
Now, here is the hierarchy with the core Representation classes:
Resource and Representation hierarchy
Beside this tutorial, your best source of information will be the Javadocs available for the Restlet API, the Restlet Extensions and the Restlet. Have also a look at the connectors section that lists all available client and server connectors and explain how to use and configure them, and the integrations section for a list of all available extensions providing pluggable features such as integration with servlet containers, generation of dynamic representations, etc. You can also post your questions and help others in our discussion list.

Notes

  • We encourage you to run the examples. The full source code is available in the latest release.
  • Thanks to Jean-Paul Figer, Christian Jensen, Jim Ancona, Roger Menday, John D. Mitchell, Jérôme Bernard, Dave Pawson, Peter Murray, Alex Combs and Leonardo Maranhão for the feed-back on this tutorial.
  • Chinese translation is available via the Matrix.org.cn site.
Copyright © 2005-2011 Noelios Technologies