Hongliang's profileHongliang's notebookPhotosBlogGuestbookMore Tools Help

Hongliang's notebook

Hongliang Li

Occupation
Location
Photo 1 of 23

Thanks for visiting!

Please wait...
Sorry, the comment you entered is too long. Please shorten it.
You didn't enter anything. Please try again.
Sorry, we can't add your comment right now. Please try again later.
To add a comment, you need permission from your parent. Ask for permission
Your parent has turned off comments.
Sorry, we can't delete your comment right now. Please try again later.
You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
Complete the security check below to finish leaving your comment.
The characters you type in the security check must match the characters in the picture or audio.
Abdulwrote:
Hi great space, Thought you might be interested to know there is a new game out on the iphone / ipod thouch called Sentinel This Friday
 
It will be available on iTunes. Check out the screen shots here http://www.iphonegamesreview.co.uk/news.php
 
Thanks
Feb. 24
May 11

Spring Security (3) Implementation of Proxies

To create an  AOP proxy in Spring, you should use the ProxyFactoryBean. This gives complete control over the pointcuts and advice that will apply, and their ordering. However, there are simpler options that are preferable if you don't need such control. Within the ProxyFactoryBean, you need to provide some property values.

proxyInterfaces – where you specify which interface you would like to create proxy for

interceptorNames – a list of inceptor names. The interceptor will be used to do some business before and after running the method.

target – A reference to the implementation class

<bean id="documentViewService" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces"

            value="com.hongliang.DocumentViewService"/>

    <property name="interceptorNames">

        <list>

             <value>documentViewServiceInterceptor</value>

        </list>

    </property>

    <property name="target">

        <ref bean="documentViewServiceImpl"/>

    </property>

</bean>

 

Then you can specify your interceptor class with the logic that you would like to add to the method while accessing, such as security check.

 

<bean id="documentViewServiceInterceptor"

class="com.hongliang.DocumentViewServiceInterceptor">

    <property name="documentViewAccessDecisionManager">

        <ref local="documentViewAccessDecisionManager"/>

    </property>

    <property name="accessDecisionManager">

        <ref local="documentViewAccessDecisionManager"/>

</property>

<property name="exemptMethods">

     <set>

            <value>getIssues</value>

        </set>

    </property>

</bean>

 

The interceptor class has predefined some properties, which includes the name of the method that should be excluded to apply the logic specified by the interceptor. In order to prevent some redundant work, you might want to exclude those methods before invoking them. To do this, you need to specify it inside the beforeInvocation() method.

 

public class DocumentViewServiceInterceptor extends MethodSecurityInterceptor implements Serializable {

private DocumentViewAccessDecisionManager documentViewAccessDecisionManager;

public InterceptorStatusToken beforeInvocation(Object object) {

            //skip the exempt methods

}

public Object afterInvocation(InterceptorStatusToken token, Object returnedObject) {

Authentication authenticated = SecurityContextHolder.getContext().getAuthentication();

try {

    this.documentViewAccessDecisionManager.decide(authenticated, returnedObject, null);

} catch (InsufficientAuthenticationException e) {

               //your solution if user not authorised 

}

}                                          

}

 

As you can see from the preceding code, we use documentViewAccessDecisionManager which implements AccessDecisionManager to decide whether user have the authorisation to access the current method. If user does not authorised to access, an InsufficientAuthenticationException will be thrown. If such an exception is caught in the interceptor class, you can specify your solution in the catch clause.

 

Reference:

http://static.springframework.org/spring/docs/1.2.x/reference/aop.html

http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-proxying

May 06

Anotations basic use

The official summary of annotation is as follow: As of release JDK 5.0, the platform has a general purpose annotation (also known as metadata) facility that permits you to define and use your own annotation types.

 

Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the interface keyword. Each method declaration defines an element of the annotation type. Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. Methods can have default values. Here is an example annotation type declaration.

 

/**

 * Describes the Request-For-Enhancement(RFE) that led

 * to the presence of the annotated API element.

 */

public @interface RequestForEnhancement {

    int    id();

    String synopsis();

    String engineer() default "[unassigned]";

    String date();    default "[unimplemented]";

}

 

In annotations with a single element, the element should be named value, as shown below:

/**

 * Associates a copyright notice with the annotated API element.

 */

public @interface Copyright {

    String value();

}

 

Applying Annotation with other framework

Annotation has been extensively used in Spring and other frameworks. In this note, I am only introducing very small portion based on a unit test demonstration.

 

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"/test-datasources.xml", "/ioc/app-config.xml"})

public abstract class AbstractAnnotationDaoTest {

    @Autowired

    public SessionFactory sessionFactory;

}

 

·          @RunWith  When a class is annotated with @RunWith or extends a class annotated with @ RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit.

 

·          @ContextConfiguration defines class-level metadata which can be used to instruct client code with regard to how to load and configure an ApplicationContext. Variable “locations” specifies where to load it

 

·          @Autowired more details are explained later. Basically, BeanFactory will be autowired into a field, constructor argument, or method parameter that is expecting the BeanFactory type as long as the field, constructor, or method in question carries the @Autowired annotation. in the preceding example, the value of sessionFactory will injected, based on its definition in the app-config.xml file. (This property is just for demonstration purpose and not used in the following sub class)

 

public class NewsDaoTest extends AbstractAnnotationDaoTest {

    @Resource

    private NewsDao newsDao;

 

    @Test

    public void getLastMonthNews () {

        List<Document> list = this.newsDao.getLastMonthNews();

        assertNotNull(list);

    }

}

 

·          @Resource is from Java annotation, you can replace with @autowired from spring framework as introduced above.  I couldn’t see the virtual difference between the two. The description of @Resource from its official JavaDoc is as follow: The Resource annotation marks a resource that is needed by the application.  This annotation may be applied to an application component class, or to fields or methods of the component class.  When the annotation is applied to a field or method, the container will inject an instance of the requested resource into the application component when the component is initialized.

·          @Test tells JUnit that the public void method to which it is attached can be run as a test case. To run the method, JUnit first constructs a fresh instance of the class then invokes the annotated method.

 

 

 

 

 

Autowiring collaborators explanation on Spring framework site

The Spring container is able to autowire relationships between collaborating beans. This means that it is possible to automatically let Spring resolve collaborators (other beans) for your bean by inspecting the contents of the BeanFactory. The autowiring functionality has five modes. Autowiring is specified per bean and can thus be enabled for some beans, while other beans will not be autowired

 

Mode

Explanation

no

No autowiring at all. Bean references must be defined via a ref element. This is the default, and changing this is discouraged for larger deployments, since explicitly specifying collaborators gives greater control and clarity. To some extent, it is a form of documentation about the structure of a system.

byName

Autowiring by property name. This option will inspect the container and look for a bean named exactly the same as the property which needs to be autowired. For example, if you have a bean definition which is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring will look for a bean definition named master, and use it to set the property.

byType

Allows a property to be autowired if there is exactly one bean of the property type in the container. If there is more than one, a fatal exception is thrown, and this indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set. If this is not desirable, setting the dependency-check="objects" attribute value specifies that an error should be thrown in this case.

constructor

This is analogous to byType, but applies to constructor arguments. If there isn't exactly one bean of the constructor argument type in the container, a fatal error is raised.

autodetect

Chooses constructor or byType through introspection of the bean class. If a default constructor is found, the byType mode will be applied.

 

Note that explicit dependencies in property and constructor-arg settings always override autowiring. Please also note that it is not currently possible to autowire so-called simple properties such as primitives, Strings, and Classes (and arrays of such simple properties).

 

Reference

http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation  

http://static.springframework.org/spring/docs/2.5.x/reference/metadata.html

http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html

 

April 29

Spring Hibernate Fundamental Review (1)

Having been working with spring hibernate for a quite a while. After few projects in practise, it looks quite different from what it was first met.

 

Data source

 

<bean id=" dataSource " class="org.springframework.jdbc.datasource.DriverManagerDataSource">

   <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

   <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>

   <property name="connection.username">admin</property>

   <property name="connection.password"> admin</property>

</bean>

 

The preceding is an Oracle connection. For MySql

 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

    <property name="url" value="jdbc:mysql://mysql.hongliang.com:3306/myschema?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"/>

    <property name="username" value="admin"/>

    <property name="password" value="admin"/>

</bean>

 

For a JNDI

 

<bean id=" dataSource " class="org.springframework.jndi.JndiObjectFactoryBean">

    <property name="jndiName" value="java:comp/env/jdbc/myds"/>

</bean>

 

Hibernate SessionFactory

Application objects that need to access resources just receive references to such pre-defined instances via bean references. This could be configured in your hibernate.cfg.xml file or your spring configuration file.

 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource " ref=" dataSource "/>

    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>

    <property name="mappingResources">

        <list>

            <value>/sql/NewsDaoSql.hbm.xml</value>

        </list>

    </property>

    <property name="eventListeners">

        <map>

            <entry key="merge">

                <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>

            </entry>

        </map>

    </property>

    <property name="entityInterceptor">       

        <bean class="com.hongliang.AuditInterceptor"/>

    </property>

</bean>

 

This is quite straightforward configuration.

  • configLocation tells where hibernate configuration file (hibernate.cfg.xml) located;
  • mappingResources indicate where  the additional resource that not specified in the file located in the  configLocation. (This is very helpful especially when the configuration file is read only, such like from a library file)
  • eventListeners which ensure that when merge happens the persistent object always keep its id.
  • entityInterceptor  enables you to audit the operations on the database access (especially on failure), such as save and delete. Your AuditInterceptor class should extends org.hibernate.EmptyInterceptor.

 

Using Named Query

In the previous note “Call SQL procedure and function with JDBC and Hibernate“ demonstrated how to run the native procedure. to run the native Sql, it is a lot easier by replacing the procedure call to SQL query

 

<sql-query name="get_document" read-only="true">

        <return alias="document" class="com.hongliang.Document"/>

                SELECT d.* from document d

                WHERE d.id=:documentID

</sql-query>

 

Document document = (Document) getSession().getNamedQuery(“get_document”).

setParameter(“documentID”, documentID).uniqueResult();

 

Using Criteria

This is a simplified API for retrieving entities by composing Criterion objects. This is a very convenient approach for functionality like "search" screens where there is a variable number of conditions to be placed upon the result set.

 

public List<Document> getLastMonthDocuments(String metadataType){

     Criteria documentCriteria = this.getSession().createCriteria(Document.class);

     documentCriteria.add(Expression.eq("recordStatus", RecordStatus.ACTIVE));

     documentCriteria.add(Expression.sql("{alias}.publish _date >=  DATE_ADD(now(), INTERVAL -30 DAY)"));

 

     Criteria docMetadataCriteria = documentCriteria.createCriteria("documentMetadata");

     Criteria metadataCriteria = docMetadataCriteria.createCriteria("metadata");

     metadataCriteria.add(Restrictions.eq("metadataType", metadataType));

 

     documentCriteria.addOrder(Order.desc("createdAt")).addOrder(Order.desc("updatedAt"));

     return documentCriteria.list();

}

 

This DAO method trying to fetch the list of document published in the last 30 days. Since the return type is Document, the criteria will be built based on Document this.getSession().createCriteria(Document.class), and then we can add the criteria on top of it.

 

Class Expression is extended form Restriction, which has its own method sql(). In the preceding example, the criteria applied a constraint expressed in SQL. Any occurrences of {alias} will be replaced by the table alias (‘Document’ table in this case).

 

We can also build the sub criteria base on the properties of return type. In the preceding example, Document has a documentMetadata property, which is a class that has a metadata property. We can built the sub criteria on the metadata’s property metadataType by metadataCriteria.add(Restrictions.eq("metadataType", metadataType))

When you try to add the sort order, you have to be aware which criteria you want to apply (root or sub criteria). Once the criteria is set, you can use it to your result (unique or list).

 

When the Hibernate Criteria API is not appropriate

  • Externalised queries can be audited and optimised if necessary by the DBA
  • Named queries stored in the Hibernate mapping files are easier to maintain than queries scattered through the Java code
  • Hibernate Named Queries are easy to cache if necessary

Reference:

http://static.springframework.org/spring/docs/1.2.9/reference/orm.html

http://www.javalobby.org/articles/hibernatequery102/?source=archives

 

 

 

April 28

Another two handy Spring MVC Controller

MultiActionController VS ParameterizableViewController

 

Have discussed “Validation with Spring MVC SimpleFormController” in the earlier note, which demonstrated you how handy it is to duel with forms. In this note, I would like to introduce another two handy controllers: MultiActionController and ParameterizableViewController.

 

ParameterizableViewController

The official JavaDoc introduced: “This controller offers an alternative to sending a request straight to a view such as a JSP. The advantage here is that the client is not exposed to the concrete view technology but rather just to the controller URL”. (Which controller is not?)  The advantage for using this controller is that you can simply set the view page straight away in the configuration rather than doing any coding in the controller.

 

MultiActionController is a bit more complex to configure, but would save you loads of time from writing many controllers that have common functions individually. multi-action controller with which you aggregate multiple actions into one controller, grouping functionality together.

 

There are two features offered by MutliActionController

Feature

Explanation

delegate

there are two usage-scenarios for the MultiActionController. Either you subclass the MultiActionController and specify the methods that will be resolved by the MethodNameResolver on the subclass (in which case you don't need to set the delegate), or you define a delegate object, on which methods resolved by the Resolver will be invoked. If you choose this scenario, you will have to define the delegate using this configuration parameter as a collaborator.

methodNameResolver

somehow the MultiActionController will need to resolve the method it has to invoke, based on the request that came in. You can define a resolver that is capable of doing that using this configuration parameter.

 

The following example demonstrates how to apply the methodNameResolver feature.

 

 

<bean id=" multiTestController " class="com.hongliang.MultiTestController">

    <property name="methodNameResolver">

        <bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">

            <property name="methodParamNames">

                <list>

                    <value>viewBooks</value>

                    <value>viewArticles</value>

                </list>

            </property>

            <property name="logicalMappings">

                <props>

                    <prop key=" viewBooks ">displayBooks</prop>

                    <prop key="viewArticles">displayArticles</prop>

                </props>

            </property>

            <property name="defaultMethodName">

                <value> displayBooks </value>

            </property>

        </bean>

    </property>

</bean>

 

The MethodNameResolver is supposed to resolve method names based on the request coming in. There are three resolvers at your disposal, but of course you can implement more of them yourself if you want to. The explanation from spring official reference is as below

·         ParameterMethodNameResolver - capable of resolving a request parameter and using that as the method name (http://www.sf.net/index.view?testParam=testIt will result in a method testIt(HttpServletRequest, HttpServletResponse) being called). The paramName configuration parameter specifies the parameter that is inspected).

·         InternalPathMethodNameResolver - retrieves the filename from the path and uses that as the method name (http://www.sf.net/testing.view will result in a method testing(HttpServletRequest, HttpServletResponse) being called).

·         PropertiesMethodNameResolver - uses a user-defined properties object with request URLs mapped to methodnames. When the properties contain /index/welcome.html=doIt and a request to /index/welcome.html comes in, the doIt(HttpServletRequest, HttpServletResponse) method is called. This method name resolver works with the PathMatcher, so if the properties contained /**/welcom?.html, it would also have worked!

The preceding example applied ParameterMethodNameResolver. In practice, when my controller called it will check the reqest url. If it includes the parameter viewBooks, then displayBooks() method will be called; If viewArticles is included, then displayArticles() will be called; If neither is included, the default (displayBook()) will be called.

 

public class SpecialReportsController extends MultiActionController {

public ModelAndView displayBooks (HttpServletRequest request, HttpServletResponse response) throws Exception {

                this.commonFunction();

return new ModelAndView(“book.jsp”);

                }

public ModelAndView displayArticles (HttpServletRequest request, HttpServletResponse response) throws Exception {

                this.commonFunction();

                                 return new ModelAndView(“article.jsp”);

                }

 

                private void commonFunction(){

                                …..

}

}

 

Reference:

http://static.springframework.org/spring/docs/1.2.9/reference/mvc.html

http://blog.csdn.net/xxxatt/archive/2007/09/11/1781025.aspx 

 

April 24

Spring Modules OSCache

Spring Modules and its caching module

Spring Modules is a collection of tools, add-ons and modules to extend the Spring Framework. The core goal of Spring Modules is to facilitate integration between Spring and other projects without cluttering or expanding the Spring core.Spring Modules is a collection of tools, add-ons and modules to extend the Spring Framework. The core goal of Spring Modules is to facilitate integration between Spring and other projects without cluttering or expanding the Spring core. The Caching Module provides a consistent abstraction for performing caching, delivering the following benefits.

  • Provides a consistent programming model across different caching APIs such as EHCache, JBoss Cache, Java Caching System (JCS) and OSCache.
  • Provides a unified, simpler, easier to use, API for programmatic use of caching services than most of these previously mentioned APIs.
  • Supports different strategies for declarative caching services.
  • The Caching Module may be easily extended to support additional cache providers.

 

Open Symphony  OSCache

OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can allow your site to have graceful error tolerance (eg if an error occurs like your db goes down, you can serve the cached content so people can still surf the site almost without knowing).

 

Implementation

The magic behind OSCache is it intercepts all the calls to the targeted interface. (ie, the PublicationDao) If any methods that being specified in the cachingModels list (ie. Key=”get*” means any methods that have a name start with “get”), A caching model will be applied to it, if there is no existing one applied. You can set up your caching model by configuring its length of the caching period (refreshPeriod), group and cronExpression.

 

 <bean id="publicationDaoTarget" class="com.hongliang.PublicationDaoImpl" scope="singleton">

        <property name="sessionFactory" ref="sessionFactory"/>

  </bean>

 

<bean id="publicationDao"

   class="org.springmodules.cache.interceptor.proxy.CacheProxyFactoryBean">

<!-- Sets the cache provider facade for the interceptors -->

<property name="cacheProviderFacade" ref="cacheProviderFacade"/>

    <property name="cachingModels">

        <map>

            <entry key="get*">

                <bean class="org.springmodules.cache.provider.oscache.OsCacheCachingModel">

                    <property name="refreshPeriod" value="5000"/>

                    <property name="groups" value="LONG_CACHE"/>

                </bean>

            </entry>

        </map>

    </property>

<property name="proxyInterfaces" value="com.hongliang.PublicationDao"/>

    <property name="target" ref="publicationDaoTarget"/>

</bean>

 

cacheProviderFacade is used to set the cache provider facade for the interceptors. 

 

<!-- Singleton FactoryBean that constructs and exposes a OSCache à

<bean id="cacheManager"

class="org.springmodules.cache.provider.oscache.OsCacheManagerFactoryBean">

         <property name="configLocation" value="classpath:oscache.properties" />

</bean>

 

<bean id="cacheProviderFacade"

class="org.springmodules.cache.provider.oscache.OsCacheFacade">

        <property name="cacheManager" ref="cacheManager"/>

        <property name="failQuietlyEnabled" value="false"/>

    </bean>

If no config location is specified, a GeneralCacheAdministrator will be configured from "oscache.properties" in the root of the class path. Here is an example of oscache.properties

 

# oscache.properties file being introduced to counter the memory issues on tomcat 4

# setting cache.memory to false if the memory cache continues to exhaust the application's memory

cache.memory=true

# setting to 10000

cache.capacity=10000

# LRUCache is the default where cache capacity is set

cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache

# no need to limit the amount of cache on disk.

cache.unlimited.disk=false

# Indicates whether the persistence should only happen once the memory cache capacity has been reached.

# The default value is false for backwards compatibility but the recommended value is true when the memory cache

# is enabled. This property drastically changes the behavior of the cache in that the persisted cache will now be

# different then what is in memory.

# note surely this is irrelevant when cache.memory = true

cache.persistence.overflow.only=true

 

Spring Modules for Maven

There is one more thing needs to note here for Nexus users, as the Nexus may block your download for the dependency files automatically. Since all those dependencies are optional, you can have them excluded by declaring within your POM file.

 

<dependency>

            <groupId>org.springmodules</groupId>

              <artifactId>spring-modules-cache</artifactId>

              <version>0.8a</version>

            <exclusions>

                <exclusion>

                    <groupId>commons-logging</groupId>

                    <artifactId>commons-logging</artifactId>

                </exclusion>

                  ……..

                  ……..

  </exclusions>

</dependency>     

 

Reference:

https://springmodules.dev.java.net/docs/reference/0.8/html/cache.html