Struts2 的 Preparable, ModelDriven 接口方法里无法获得参数,理解 拦截器与责任链

动作类实现了 Preparable,ModelDriven 这两个接口,但是却无法在其方法 prapare 和 getModel 方法里获得 其它参数,进而无法根据其它参数来查询数据库。

在 prapare,getModel 这两个方法都断点了,显示执行顺序为 prapare——》 getModel,但是其它参数(如 categoryId (有对应的get / set 方法)JSP 页面上已确定没有写错。

一、业务场景:

自己想要的结果是:先根据 参数 categoryId 来查询数据库,

public void prepare() throws Exception {
		// 前端传递了参数,表示 需要 查看详细属性
		if( categoryId !=null ) {
			//查询数据库 该类对应的 Java 类名,因为 不同种类的属性差异很大,必须获得 对应的 类
			String detailsClassName = categoryService.getDetailsClassName(categoryId);
			// 安全起见:只允许加载 com.jian.vo 包下的 类
			if(detailsClassName !=null && detailsClassName.startsWith("com.jian.vo") ) {
				try {
					itemInfo = Class.forName(detailsClassName).newInstance();
					logger.info("顾客需要浏览商品详情:" + itemInfo.getClass().getName() );
				} catch (InstantiationException | IllegalAccessException
						| ClassNotFoundException e) {
					logger.error("没有对应的 VO 类:" + detailsClassName );
					e.printStackTrace();
				}
			}
		}else {
			itemInfo = new ItemBaseInfoVO();
		}
	}
	@Override
	public Object getModel() {
		// 让模型 去接收 前端传递过来的 参数,最后保存这个模型即可
		return itemInfo;
	}
但是 categoryId 的值却为 null,这就导致 查询数据库失败,后者无法查到正确值。

Struts2 的 Preparable, ModelDriven 接口方法里无法获得参数,理解 拦截器与责任链_第1张图片


二、分析:

(1)因为方法执行顺序为:prapare——》getModel,并且参数没有获得,所以拦截器执行的执行顺序为:prapare——》modelDriven——》params。

默认的拦截器栈为 defaultStack( 因为 struts2 配置文件里 的 package 设置 extends="struts-default" ,在 struts-core.jar 包下的 struts-default.xml 配置文件里有 设置

  )。

defaultStack 中拦截器的 设置信息为:


                
                
                
                
                
                
                
                
                
                
                
                
                
                
                    dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*
                
                
                
                    input,back,cancel,browse
                
                
                    input,back,cancel,browse
                
                
            


这里验证了 拦截器的先后顺序为:prepare——》modelDriven——》params,所以方法的先后顺序为:prapare——》getModel——》setXXX(属性),所以 categoryId 为空值

(2)解决之道:

调整 拦截器的先后顺序:params——》prepare——》modelDrive,去 struts-core.jar 里的 struts-default.xml 搜索 符合这要求得 拦截器执行栈,(*^__^*) 嘻嘻……还真发现了有这一执行栈: paramsPrepareParamsStack

	
                
                
                
                
                
                
                    dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*
                
                
                
                
                
                
                
                
                
                    dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*
                
                
                
                    input,back,cancel,browse
                
                
                    input,back,cancel,browse
                
            
最后在 自个的 struts.xml 配置文件里的 引用这个 执行栈: paramsPrepareParamsStack


	
	
		
		
		
		
		
		
			/jsp/home/HomeLayout.jsp
		

最后:

感知到了 Struts2 的优良设计,把一些功能模块划分成拦截器,也渐渐理解了 责任链模式的 解耦合,谢谢Struts2 作者 的无私奉献!!!

你可能感兴趣的:(Struts2)