Hongliang's profileHongliang's notebookPhotosBlogGuestbookMore ![]() | Help |
Hongliang's notebook |
|||||||||||||||||||||||
|
Thanks for visiting!
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 ProxiesTo 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 useThe 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 /** * 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
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&characterEncoding=UTF-8&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.
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
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 ControllerMultiActionController 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
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 OSCacheSpring Modules and its caching moduleSpring 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.
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
|
||||||||||||||||||||||
|
|