在Seam中自定义interceptor拦截器

我这里的Seam项目使用war方式部署,所以seam的action是POJO而不是EJB。
下面是最终的使用效果,在类上添加自定义的@MySeam, 在需要控制的Field上添加自定义的@SuperString

@Name("productAction")
@MySeam
public class ProductAction {
	
	@SuperString
	String name;
	
	@SuperString(postfix="-product")
	String product;

	... ...
}
 

下面说说具体怎么做,先写一个Interceptor如下例

import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.security.SecurityInterceptor;
import org.jboss.seam.core.EventInterceptor;
import org.jboss.seam.core.MethodContextInterceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
import org.jboss.seam.util.Reflections;

/**
 * MySeamInterceptor will be invoke
 * before MethodContextInterceptor, EventInterceptor
 * after SecurityInterceptor
 */
@Interceptor(around = {
        MethodContextInterceptor.class,
        EventInterceptor.class,
        },
		within = SecurityInterceptor.class
)
public class MySeamInterceptor extends AbstractInterceptor {

	private static final long serialVersionUID = -3064515871691261357L;
	
	private static final LogProvider log = Logging.getLogProvider(MySeamInterceptor.class);
	
	private boolean reentrant; //OK, since all Seam components are single-threaded

	@AroundInvoke
	public Object aroundInvoke(InvocationContext invocation) throws Exception {
		if (reentrant) {
			if (log.isTraceEnabled()) {
				log.trace("reentrant call to component: " + getComponent().getName());
			}
			return invocation.proceed();
			
		} else {

			reentrant = true;
			try {
				//Component component = getComponent();

				changeStringValue(invocation.getTarget());
				
				// you can add more method in here.
				
				return invocation.proceed();

			} finally {
				reentrant = false;
			}
		}
	}

	private void changeStringValue(Object target) {
		Field[] fieldArray = target.getClass().getDeclaredFields();
		for (Field field : fieldArray) {
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}
			if (field.isAnnotationPresent(SuperString.class)) {
				SuperString superStr = field.getAnnotation(SuperString.class);
				String newValue = System.currentTimeMillis() + superStr.postfix();
				setFieldValue(field, target, newValue);
			}
		}
	}

	/**
	 * Set field value.
	 * @param field		The value will be set for this field
	 * @param target	The field belongs to this object
	 * @param value		The field's value
	 */
	private void setFieldValue(Field field, Object target, Object value) {
		try {
			Reflections.set(field, target, value);
		} catch (Exception e) {
			throw new IllegalArgumentException("MySeamInterceptor.setFieldValue(): " + 
					target.getClass() + "; field: " + field.getName(), e);
		}
	}
}
 

继承AbstractInterceptor是比较容易的方式,@AroundInvoke是必须的。
这里的逻辑很简单:在所有标注了@MySeam的类中,寻找标注了@SuperString的Field,并给其赋值。

 

为了使用MySeamInterceptor,我们需要为它定义一个Annotation,如下:

import org.jboss.seam.annotations.intercept.Interceptors;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Interceptors(MySeamInterceptor.class)
public @interface MySeam {

}

 

最后是@SuperString,这个就不多说了。

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD)
public @interface SuperString {

	String postfix() default "-super";
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值