`

Annotation与Tapestry4.0页面拦截

阅读更多

<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();         
}
分享到:
评论
9 楼 iRoyce 2007-02-13  
完整版已贴上去!!!!!

注:Tapesty 5 的URL已出现层次目录,可以通过Filter更容易的拦截页面权限.
8 楼 iRoyce 2006-12-26  
忙...
稍后给与答复...
7 楼 iRoyce 2006-12-26  
你可以在浏览器中的页面源代码中找到这个tasks,应该会有<input type="hidden" name="xxx" value="tasks"/>的语句(request.getParameter("xxx") )...解决办法同linksubmit....


T4的源码还有待研究...目前我也只能做到这种简洁一点的办法了!
6 楼 pppppp 2006-12-25  
我这里还有一种情况也是获得不了的。
<form jwcid="taskForm@Form"  clientValidationEnabled="true"  >
<input jwcid="tasks@Submit" value="add"  listener="listener:addTask" />
这个时候也是获得不了的。因为有时候一个form里面有多个submit每个submit帮定的方法都是不同的,这个时候就不给form帮定方法了,而是给submit直接帮定。
另外:有时候在写成sucessful="listener:addTask"或者action="listener:addTask"这个时候也是获得不了的
5 楼 iRoyce 2006-12-22  
这周工作太忙...见谅.

确实存在这个问题.简单的解决办法就是
在String componentName = this.getRequestCycle().getParameter("component");后加上以下代码:
String submitname = this.getRequestCycle().getParameter("submitname");
if (submitname!=null && !"".equals(submitname))
  componentName = submitname;
4 楼 pppppp 2006-12-21  
我使用的是在html中<form jwcid="pageform@Form"> <input name="pageNum" type="text" class="inputGO" jwcid="pagenum"/>页&nbsp;&nbsp;<a jwcid="go">go</a></form>
配置文件:
<component id="pagenum" type="TextField">         <binding name="value" value="pageNum"/>
   </component>
   <component id="go" type="LinkSubmit">
<binding name="listener" value="listener:onPage"/>
<binding name="tag" value="pageNum"/>
<binding name="selected" value="selectedPage"/>
</component>
java代码:
public abstract int getPageNum();
    public void onPage(IRequestCycle objCycle)
{
System.out.println(getPageNum());
}
通过你提供的方法我这里面提交后组件ID是pageform,而监听方法是帮定在go这个元素上的,
lmb = (ListenerMethodBinding)this.getComponent(componentName).getBindings().get("listener");
lmb得到的null
3 楼 iRoyce 2006-12-21  
如果你提交表单时,URL带有该Form组件对应的名字(id)时,就能在服务端能获得该组件名字对应的监听方法名(服务端就是通过这个URL获取用户触发了哪个组件,T4运行时环境有配置信息来记录组件名与监听方法名的对应).

一句话就是:请求中的URL如果带有组件名(id)信息,就能在服务端获得对应的监听方法名.

不太清楚你所描述的情况...不知可不可以让我看看你的页面与页面类代码???
2 楼 pppppp 2006-12-20  
你好,我用你的方法试了一下,但是好像不行,lmb = (ListenerMethodBinding)this.getComponent(componentName).getBindings().get("listener");获得不到内容。我的一个链接在form中的时候,获得的component是form对象,而form的linstener并没有触发,不知道你遇到这种问题没有。
1 楼 pppppp 2006-12-20  

相关推荐

    springboot aspect通过@annotation进行拦截的实例代码详解

    "springboot aspect通过@annotation进行拦截的实例代码详解" 本篇文章主要介绍了springboot aspect通过@annotation进行拦截的方法,通过实例代码详细地介绍了如何使用@annotation来进行拦截。下面是相关知识点的...

    annotation-framework-4.0.jar

    官方版本,亲测可用

    拦截器与冲突解决

    4. **AOP切面问题**:如果同时使用了基于注解的切面(@Aspect),可能会与拦截器产生竞争。确保切面的顺序配置正确,或者避免重复的功能实现。 解决这个问题的方法通常包括: - **显式配置拦截器**:通过`...

    annotation-framework-4.0-sources.jar

    官方版本,亲测可用

    struts 拦截器,扩展,以及java annotation

    3. **Java注解(Annotation)**: - Java注解是元数据的一种形式,用于提供有关代码的信息,而这些信息可以被编译器或运行时环境用来执行某些操作。在Struts2中,注解广泛用于简化配置,如`@Action`、`@Result`、`@...

    springboot aspect通过 annotation进行拦截.docx

    1. **注解(Annotation)**:注解是Java语言的一个重要特性,它允许元数据(metadata)与代码直接关联。在Spring AOP中,我们可以通过自定义注解来标记需要进行特殊处理的方法。例如,创建一个名为`@RepeatSubmit`的...

    jakarta.annotation-api-1.3.5-API文档-中文版.zip

    赠送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...

    javax.annotation-api-1.2-API文档-中文版.zip

    赠送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;...

    jakarta.annotation-api-1.3.5-API文档-中英对照版.zip

    赠送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...

    SpringMVC 4.0

    2. **注解驱动开发(Annotation-based Development)**:SpringMVC 4.0大力推广注解的使用,如@Controller、@RequestMapping、@Service、@Repository等,使开发者能快速构建控制器、服务和数据访问层,减少XML配置...

    javax.annotation-api-1.3.2-API文档-中文版.zip

    赠送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 配置的小例子

    在Struts2中,Annotation允许开发者无需XML配置文件就能定义Action、结果类型、拦截器等。 在"struts2 使用Annotation 配置的小例子"中,我们可能会看到以下几个核心的Annotation: 1. `@Action`: 这个Annotation...

    用Annotation简化Java程序的开发(PDF)

    1. **代码耦合度:** Annotation与代码紧密耦合,而XML配置文件则通常与代码分离。 2. **维护难度:** Annotation易于维护,因为它们与代码一起存在于源文件中,而XML文件则需要单独维护。 3. **配置的灵活性:** ...

    sshFrame(struts2.3.4+spring3.1+heibernate4.0+annotation零配置

    在这个"sshFrame(struts2.3.4+spring3.1+heibernate4.0+annotation零配置"项目中,我们看到作者使用的是Struts2的3.4版本,Spring的3.1版本以及Hibernate的4.0版本,这些都是成熟且广泛使用的开源库。 **Struts2** ...

    Annotation手册

    7. **元Annotation**:元Annotation是用于定义其他Annotation的Annotation,例如`@Retention`定义Annotation的生命周期(编译时、类加载时或运行时),`@Target`指定Annotation可以应用到哪些程序元素,`@Documented...

    Annotation技术

    Annotation与Javadoc Tag相似,但有所不同。如果一个标记对Java文档有影响或者用于生成Java文档,那么它应该作为一个Javadoc Tag。否则,它应该作为Annotation。 6. **枚举在Annotation中的应用** 枚举可以作为...

    annotation-1.1.0.jar

    @androidx.annotation.NonNull 缺失的兼容、androidx.annotation兼容包

    使用Annotation和拦截器实现访问控制 (2010年)

    针对这些问题,结合网络教学系统的开发,提出了一种基于Annotation和拦截器实现访问控制的实现方法。Annotation是在JDK1.5之后的版本中出现的新的用于标注元数据的类型。Interceptor(拦截器)是Struts2的一个强有力的...

    Annotation与Javadoc比较1

    标题"Annotation与Javadoc比较1"暗示了我们将对比两种在Java编程中常见的注解形式——Javadoc和Annotation。Javadoc主要用于生成程序的文档,而Annotation则是从JDK5开始引入的元数据特性,它为编译器和运行时环境...

Global site tag (gtag.js) - Google Analytics