日期:2014-05-16  浏览次数:20431 次

jsp 内置对象使用

? 这是第一次在JavaEye中写文章,以前都是在CSDN中写,不过觉得JavaEye中高手多,可能以后会慢慢转过来了。今天来写一下项目开发过程中的一个问题解决:

? 先来说一下需求:有很多页面都要显示一些数据,如果是每个action都设置属性的时候,我觉得是很麻烦的,而且这些数据“全局”的味道,所以为了解决上面的两个问题,我觉得自定义一个Interceptor再显示页面之前进行一些操作,下面是我最开始做的,思路是手动往ValueStack中加值:

	HttpServletRequest request = (HttpServletRequest) ActionContext
				.getContext().get(StrutsStatics.HTTP_REQUEST);
		OgnlValueStack stack = (OgnlValueStack) request
				.getAttribute("struts.valueStack");

              String result=invocation.invoke();

		/**
		 * Set the properties
		 */
		List<Category> cityList = systemService.getCategorySortList("city");
		stack.set("cityList", cityList);

		EhcacheVindicatorProxy proxy = new EhcacheVindicatorProxy("menu");
		List<FrontMenu> frontMenuList = (List) proxy.get(FrontMenu.class,
				"frontmenus", "menus.xml");
		stack.set("frontMenuList", frontMenuList);

              return result;

?

?? 拦截器的顺序是这样的:

?

<!-- 配置系统默认拦截器栈 -->
		<interceptors>
			<interceptor name="properties"
				class="com.zuwoba.presentation.interceptor.PropertiesInterceptor" />
			<interceptor-stack name="group">
				<!--引用默认拦截器-->
				<interceptor-ref name="properties" />
				<interceptor-ref name="defaultStack" />

			</interceptor-stack>
		</interceptors>
		<!-- 将自定义拦截器栈定义为默认拦截器栈 -->
		<default-interceptor-ref name="group" />

?

这里上面两段代码红色部分要特别注意,顺序如果没配好,不是页面显示不了值,就是表单提交的数据无法得到,当然我也以为我配好了,但是最后的时候却出错了,我用的是SiteMesh来装饰,装饰页面可以取得值,被装饰页面却不能取得,所以我上面的这个是有问题的,问题的原因我觉得就是ValueStack是由Struts2自动维护的,如果是手动维护,而没对原理有充分理解的话,是会出问题的,所以建议不是很深入理解Struts2的人不要最后不要去动ValueStack。

?

?? 好了出问题了,解决不了,就要找其他方法呗,往session、application中直接设值然后在jsp页面取这种做法我是不会用的,无意中用<s:debug/>的时候看到了下面的Stack Context中的一些对象,Struts2叫做命名对象,其实也就是放置jsp内置对象的容器,既然jsp页面可以取到request的值,那么为何我不用request来传递数据呢?况且用jsp、servlet的时候不是经常这样干吗?request这么好的载体为什么不用?于是,就用request了,代码如下:

ActionContext context = invocation.getInvocationContext();
		HttpServletRequest request = (HttpServletRequest) context
				.get(ServletActionContext.HTTP_REQUEST);

		List<Category> cityList = systemService.getCategorySortList("city");
		request.setAttribute("cityList", cityList);

		EhcacheVindicatorProxy proxy = new EhcacheVindicatorProxy("menu");
		List<FrontMenu> frontMenuList = (List) proxy.get(FrontMenu.class,
				"frontmenus", "menus.xml");
		request.setAttribute("frontMenuList", frontMenuList);

		return invocation.invoke();

?

其实我在操作ValueStack的时候,总是会想这种方法是不是太偏了,因为对Struts2 维护ValueStack也不是太熟,所以心里面总是毛毛的,这会不会错啊,不是很肯定,我觉得有时候还是用传统一点的方法比较好,如果自己写得太偏了,这时候你就要问问自己,是不是还有比较常规一点的方法,说来说去也就那点东西,想想总是会想到的。