Annotation与Tapestry4.0页面拦截

本文介绍如何在Tapestry框架中实现页面级权限控制,利用Spring的拦截机制结合自定义注解,确保用户只能访问其拥有权限的功能,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<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();         
}
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值