<o:p> </o:p>
在Tapestry+Spring+Hibernate的框架中,安全控制可以直接采用Spring的拦截机制实现整个系统的安全,这一机制主要在页面层调用服务层方法时才会起作用, 为了实现页面级的安全控制,如用户点某个链接,服务端马上就可以在页面层实现拦截,用以解决类似如下的问题:<o:p></o:p>
用户点击[新增定单]—>定单添加页面—>[定单提交],假如用户没有新增定单的权限,因为点击[新增定单]没有调用服务层方法,所以第一时间没有被拦住,而只有在[定单提交]调用新增定单的服务层方法时才会被拦下来,影响用户的体验。<o:p></o:p>
实现中,主要要在你想拦截的方法声明前配置一个annotation,不想拦截的可以不配置,本实现可以重用已配置好的针对服务层拦截的权限数据。代码在Tapesty4.0上测试通过,以下是核心代码。<o:p></o:p>
//以下为页面基类
package com.demo.tapestry;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IRender;
import org.apache.tapestry.binding.ListenerMethodBinding;
import org.apache.tapestry.event.PageEvent;
import org.apache.tapestry.event.PageValidateListener;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.form.Form;
import org.apache.tapestry.services.ServiceConstants;
import com.demo.annotation.Security;
/**
*
* 功能描述:带权限验证的页面基类
*
* @author iroyce
* Created on d2007-1-20
*/
public abstract class DemoProtectedBasePage extends DemoBasePage implements
PageValidateListener {
/**
* 页面校验方法
*/
public void pageValidate(PageEvent event) {
DemoVisit visit = (DemoVisit) getDemoVisit();
//=====================以下为页面层权限校验==================================================
String securityAnnotation = getMethodAnnotation();
log.info("securityAnnotation=" + securityAnnotation);
//以下是权限校验及相关处理....
//if ( !checkPermission(securityAnnotation, permission) ) 页面相关跳转;
}
/**
*方法用途和描述:得到页面类中方法所绑定的安全数据
*@return方法所绑定的安全数据字符串,如com.demo.service.IMemberManager.addMemberMsg
*/
private String getMethodAnnotation(){
String componentName = this.getRequestCycle().getParameter(ServiceConstants.COMPONENT);
if(componentName==null || "".equals(componentName))
return null;
String methodName = null;
if(componentName!=null && this.getRequest().getAttribute("isChecked")==null){
try{
ListenerMethodBinding lmb = (ListenerMethodBinding)this.getComponent(componentName).getBinding("listener");
if(lmb!=null)
methodName = this.getMethodName(lmb.toString());
else
methodName = getMethodName(getBindingString(componentName));
this.getRequest().setAttribute("isChecked", new StringBuffer("T"));
}catch(ApplicationRuntimeException e){
log.error(":::::::ApplicationRuntimeException from class#" + this.getClass() + " method#pageValidate :::::::");
}
}
if(methodName!=null){
Method[] ms = this.getClass().getMethods();
Method mm = null;
for (int i=0; i<ms.length; i++){
if (ms[i].getName().equals(methodName)){
mm = ms[i];
break;
}
}
Security security = mm.getAnnotation(Security.class);
//得到方法相应的配置数据
if(security!=null)
return security.methodName();
}
return null;
}
/**
* 方法用途和描述: 得到绑定的监听类描述串,其中含有监听方法名部份,T4中并未把监听方法名暴露给编程人员访问
* @author iroyce
*/
private String getBindingString(String formid){
if (formid==null) return null;
IComponent ic = this.getComponent(formid);
if(!(ic instanceof Form)) return null;
Form ff = (Form)ic;
IRender[] ir = ff.getBody();
if(ir==null) return null;
ListenerMethodBinding lmb = null;
for (int i=ir.length-1; i>=0; i--){
if (ir[i] instanceof AbstractFormComponent ){
AbstractFormComponent afc = (AbstractFormComponent)ir[i];
lmb = (ListenerMethodBinding)afc.getBinding("listener");
if (lmb!=null) break;
}
}
//<form jwcid="@Form" success="listener:foo"/>等情况
if (lmb==null) return ic.getBindings().toString();
return lmb.toString();
}
/**
* 方法用途和描述: 得到监听方法名
* @author iroyce
*/
private String getMethodName(String methodSource){
if(methodSource==null) return null;
String methodName = methodSource.toString();
int start = methodName.indexOf("methodName=");
if(start==-1) return null;
start += 11;
methodName = methodName.substring(start);
methodName = methodName.substring(0, methodName.indexOf(","));
//methodName = this.getPage().getSpecification().getComponentClassName() + "." + methodName;
log.info("methodName=" + methodName);
return methodName;
}
/**
* 方法用途和描述: 判断当前要执行前台的权限是否可以执行
* 方法的实现逻辑描述:将当前要执行前台的权限和缓存里保存当前前台角色所拥有的权限一一比较,如果有匹配的就返回true,否则返回false
* @param methodName 当前要执行前台的权限
* @return 返回结果true--用户具有该权限 false--用户不具有该权限
* @exception IOException 异常信息描述(如果此方法会throws 异常)
* @author iroyce
*/
private boolean checkPermission(String methodName, List permission){
return true;
}
}
<o:p></o:p>
//以下为页面类中的一个监听方法
/**
*方法用途和描述:回复短消息
*服务层方法com.demo.service.IMemberManager.addMemberMsg与该监听
*方法绑定,访问该监听方法必须具有访问
*com.demo.service.IMemberManager.addMemberMsg的权限
*/
@Security(methodName="com.demo.service.IMemberManager.addMemberMsg")
public IPage answerMessage(String msgID) {
//......
}
//以下为自定义的Annotation
package com.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 功能描述: 页面类安全代码配置
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Security {
String methodName();
}
分享到:
- 2006-12-05 17:45
- 浏览 4551
- 评论(9)
- 论坛回复 / 浏览 (9 / 5575)
- 查看更多
相关推荐
"springboot aspect通过@annotation进行拦截的实例代码详解" 本篇文章主要介绍了springboot aspect通过@annotation进行拦截的方法,通过实例代码详细地介绍了如何使用@annotation来进行拦截。下面是相关知识点的...
官方版本,亲测可用
4. **AOP切面问题**:如果同时使用了基于注解的切面(@Aspect),可能会与拦截器产生竞争。确保切面的顺序配置正确,或者避免重复的功能实现。 解决这个问题的方法通常包括: - **显式配置拦截器**:通过`...
官方版本,亲测可用
3. **Java注解(Annotation)**: - Java注解是元数据的一种形式,用于提供有关代码的信息,而这些信息可以被编译器或运行时环境用来执行某些操作。在Struts2中,注解广泛用于简化配置,如`@Action`、`@Result`、`@...
1. **注解(Annotation)**:注解是Java语言的一个重要特性,它允许元数据(metadata)与代码直接关联。在Spring AOP中,我们可以通过自定义注解来标记需要进行特殊处理的方法。例如,创建一个名为`@RepeatSubmit`的...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
赠送jar包:javax.annotation-api-1.2.jar; 赠送原API文档:javax.annotation-api-1.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom;...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
2. **注解驱动开发(Annotation-based Development)**:SpringMVC 4.0大力推广注解的使用,如@Controller、@RequestMapping、@Service、@Repository等,使开发者能快速构建控制器、服务和数据访问层,减少XML配置...
赠送jar包:javax.annotation-api-1.3.2.jar; 赠送原API文档:javax.annotation-api-1.3.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.3.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-...
在Struts2中,Annotation允许开发者无需XML配置文件就能定义Action、结果类型、拦截器等。 在"struts2 使用Annotation 配置的小例子"中,我们可能会看到以下几个核心的Annotation: 1. `@Action`: 这个Annotation...
1. **代码耦合度:** Annotation与代码紧密耦合,而XML配置文件则通常与代码分离。 2. **维护难度:** Annotation易于维护,因为它们与代码一起存在于源文件中,而XML文件则需要单独维护。 3. **配置的灵活性:** ...
在这个"sshFrame(struts2.3.4+spring3.1+heibernate4.0+annotation零配置"项目中,我们看到作者使用的是Struts2的3.4版本,Spring的3.1版本以及Hibernate的4.0版本,这些都是成熟且广泛使用的开源库。 **Struts2** ...
7. **元Annotation**:元Annotation是用于定义其他Annotation的Annotation,例如`@Retention`定义Annotation的生命周期(编译时、类加载时或运行时),`@Target`指定Annotation可以应用到哪些程序元素,`@Documented...
Annotation与Javadoc Tag相似,但有所不同。如果一个标记对Java文档有影响或者用于生成Java文档,那么它应该作为一个Javadoc Tag。否则,它应该作为Annotation。 6. **枚举在Annotation中的应用** 枚举可以作为...
@androidx.annotation.NonNull 缺失的兼容、androidx.annotation兼容包
针对这些问题,结合网络教学系统的开发,提出了一种基于Annotation和拦截器实现访问控制的实现方法。Annotation是在JDK1.5之后的版本中出现的新的用于标注元数据的类型。Interceptor(拦截器)是Struts2的一个强有力的...
标题"Annotation与Javadoc比较1"暗示了我们将对比两种在Java编程中常见的注解形式——Javadoc和Annotation。Javadoc主要用于生成程序的文档,而Annotation则是从JDK5开始引入的元数据特性,它为编译器和运行时环境...