《struts2权威指南》学习笔记之struts2+jsf+spring+sitemesh集成开发

本文介绍如何在Struts2框架中整合Sitemesh页面装饰器,通过配置过滤器和装饰器配置文件实现页面布局统一化。同时展示了具体的XML配置示例及装饰器页面示例。

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

1.安装sitemesh插件

与整合其他框架类似,struts2与sitemesh框架的整合也使用了插件方式进行管理。将struts2-sitemesh-plugin-2.0.6.jar文件复制到WEB-INF/lib下,为了整合sitemesh框架,必须在web.xml中配置sitemesh过滤器,让该核心过滤器来过滤所有的用户请求。但我们知道,struts2的所有值一旦访问该stack context或ValueStack后,里面对应的数值将会被清除掉,如果先使用了struts2的FilterDispather来过滤用户请求,则sitemesh的过滤器将无法取得Stack context或者ValueStack中的数据
为了解决这个问题,struts2提供了ActionContextCleanUp类,在struts2的架构中,标准的过滤器一般以ActionContextCleanUp开始,后面跟着其他需要的过滤器,最后,由FilterDispatcher来处理请求,FilterDispatcher通常是将请求传递给ActionMapper
ActionContextCleanUp的一个重要作用是整合sitemesh页面装饰器,它通知FilterDispatcher在正确的时间清除ActionContext中的请求数据,所以正确的排序如下:
(1)ActionContextCleanUp过滤器
(2)SiteMesh核心过滤器
(3)FilterDispatcher过滤器

web.xml

<? xmlversion="1.0"encoding="GBK" ?>
< web-app id ="jsf" version ="2.4"
xmlns
="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
<!-- ��struts2�ܹ��У���׼�Ĺ�����tһ����ActionContextCleanUp��ʼ���������������Ҫ�Ĺ����������FilterDispatcher�������� -->
< filter >
< filter-name > struts-cleanup </ filter-name >
< filter-class > org.apache.struts2.dispatcher.ActionContextCleanUp </ filter-class >
</ filter >
< filter >
< filter-name > sitemesh </ filter-name >
< filter-class > com.opensymphony.module.sitemesh.filter.PageFilter </ filter-class >
</ filter >
< filter >
< filter-name > struts </ filter-name >
< filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class >
</ filter >

< filter-mapping >
< filter-name > struts-cleanup </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > sitemesh </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > struts </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >

< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >

< listener >
< listener-class > org.apache.myfaces.webapp.StartupServletContextListener </ listener-class >
</ listener >

<!-- JavaServerFacesServletConfiguration,notuseddirectly -->
< servlet >
< servlet-name > faces </ servlet-name >
< servlet-class > javax.faces.webapp.FacesServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >

<!-- JavaServerFacesServletMapping,notcalleddirectly -->
< servlet-mapping >
< servlet-name > faces </ servlet-name >
< url-pattern > *.action </ url-pattern >
</ servlet-mapping >

</ web-app >

spring配置文件

<? xmlversion="1.0"encoding="GBK" ?>
<!-- 指定Spring配置文件的Schema信息 -->
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd" >

< bean id ="bs" class ="lee.service.BookService" />

</ beans >

sitemesh装饰配置文件

<? xmlversion="1.0"encoding="GBK" ?>

< decorators defaultdir ="/decorators" >
<!-- 在excludes元素下指定的页面将不会由SiteMesh来装饰 -->
< excludes >
< pattern > /exclude.jsp </ pattern >
< pattern > /exclude/* </ pattern >
</ excludes >

<!-- 创建一个名为main的装饰器,该装饰器页面为main.jsp,
用于装饰pattern指定的URL的所有页面
-->
< decorator name ="main" page ="main.jsp" >
< pattern > /* </ pattern >
</ decorator >

<!-- 定义一个装饰器,但该装饰器默认不装饰任何页面 -->
< decorator name ="panel" page ="panel.jsp" />
</ decorators >

装饰器decorators/main.jsp

<% ... @pagecontentType="text/html;charset=GBK" %>
<% ... @tagliburi="http://www.opensymphony.com/sitemesh/decorator"prefix="decorator" %>
<% ... @tagliburi="http://www.opensymphony.com/sitemesh/page"prefix="page" %>
< html >
< head >
< title >< decorator:title default ="SiteMesh的装饰器页" /></ title >
< link href ="decorators/main.css" rel ="stylesheet" type ="text/css" >
< decorator:head />
</ head >
< body >
< table width ="100%" height ="100%" >
< tr >
< td valign ="top" >
<!-- 引入一个页面,临时指定所用的装饰器 -->
< page:applyDecorator page ="/book.html" name ="panel" />
< page:applyDecorator page ="/link.html" name ="panel" />
</ td >
< td width ="100%" >
< table width ="100%" height ="100%" >
< tr >
< td id ="pageTitle" >
< decorator:title />
</ td >
</ tr >
< tr >
< td valign ="top" height ="100%" >
< decorator:body />
</ td >
</ tr >
< tr >
< td id ="footer" >
< b > 被包含的内容 </ b >< br >
SithMesh提供页面装饰支持
</ td >
</ tr >
</ table >
</ td >
</ tr >
</ table >
</ body >
</ html >

装饰器decorators/panel.jsp

<% ... @pagecontentType="text/html;charset=GBK" %>
<% ... @tagliburi="http://www.opensymphony.com/sitemesh/decorator"prefix="decorator" %>
< p >
< table width =250 border =0 cellpadding =0 cellspacing =0 >
< tr >
< th class ="panelTitle" >
< decorator:title default ="小面板页面" />
</ th >
</ tr >
< tr >
< td class ="panelBody" >
< decorator:body />
</ td >
</ tr >
</ table >
</ p >

装饰器样式decorators/main.css

body,td,p{
font:normalx-smallverdana,arial,helvetica,sans-serif;
}

.panelTitle{
background-color:#003399;
color:#eeeeee;
font-weight:bold;
border-color:#3366ff#000033#000033#3366ff;
border-width:1;
border-style:solid;
padding:1;
}

.panelBody{
background-color:#eeeeee;
border-color:black;
border-width:0111;
border-style:solid;
padding:2;
}

#pageTitle{
background-color:#003399;
color:#eeeeee;
font-weight:bold;
font-size:large;
border-color:#3366ff#000033#000033#3366ff;
border-width:1;
border-style:solid;
padding:1;
text-align:center;
}

#footer{
background-color:#eeeeee;
font-size:9pt;
text-align:center;
color:black;
border-color:#666666#cccccc#cccccc#666666;
border-width:1;
border-style:solid;
padding:1;
}

被装饰页面book.html

< html >
< head >
< title > 作者图书 </ title >
</ head >
< body >
< center >
Spring2.0宝典
< br >
轻量级J2EE企业应用实战
< br >
基于J2EE的Ajax宝典
</ center >
</ body >
</ html >

被装饰页面link.html

< html >
< head >
< title > 友情链接 </ title >
</ head >
< body >
< center >
< a href ="http://www.nit-pro.org" > NIT-PRO考试中心 </ a >< br >
< a href ="http://www.oneedu.cn" > 新东方IT培训中心 </ a >< br >
< a href ="http://www.oneedu.cn" > 东方标准人才服务公司 </ a >< br >
</ center >
</ body >
</ html >

JSF功能页面list.jsp

<% ... @pagelanguage="java"contentType="text/html;charset=GBK" %>
<% ... @taglibprefix="f"uri="http://java.sun.com/jsf/core" %>
<% ... @taglibprefix="h"uri="http://java.sun.com/jsf/html" %>
< html >
< head >
< title > Struts2+MyFaces+Spring整合 </ title >
</ head >
< body >
< f:view >
< h3 > Struts2+MyFaces+Spring整合 </ h3 >
< h3 > 列出所有图书 </ h3 >
< h:dataTable value ="#{action.allBook}" var ="b" style ="text-align:center;width:500px" border ="1" >
< h:column >
< f:facet name ="header" >
< h:outputText value ="图书ID" />
</ f:facet >
< h:outputLink value ="edit.action" >
< f:param name ="editId" value ="#{b.id}" />
< h:outputText value ="#{b.id}" />
</ h:outputLink >
</ h:column >
< h:column >
< f:facet name ="header" >
< h:outputText value ="图书名" />
</ f:facet >
< h:outputText value ="#{b.name}" />
</ h:column >
< h:column >
< f:facet name ="header" >
< h:outputText value ="图书简介" />
</ f:facet >
< h:outputText value ="#{b.desc}" />
</ h:column >
</ h:dataTable >
< p >
< h:outputLink value ="edit.action" >
< h:outputText value ="新增图书" />
</ h:outputLink >
</ p >
</ f:view >
</ body >
</ html >

JSF功能页面edit.jsp

<% ... @pagelanguage="java"contentType="text/html;charset=GBK" %>
<% ... @taglibprefix="f"uri="http://java.sun.com/jsf/core" %>
<% ... @taglibprefix="h"uri="http://java.sun.com/jsf/html" %>
< html >
< head >
< title > Struts2+MyFaces+Spring整合 </ title >
</ head >
< body >
< f:view >
< h3 > Struts2+MyFaces+Spring整合 </ h3 >
< h3 > 修改/保存图书 </ h3 >
< h:form >
< h:inputHidden value ="#{action.editId}" />
< h:panelGrid columns ="3" >
< h:outputText value ="图书ID" />
< h:inputText id ="id" size ="5" value ="#{action.currentBook.id}" required ="true" />
< h:message for ="id" />
< h:outputText value ="图书名:" />
< h:inputText id ="name" size ="30" value ="#{action.currentBook.name}" required ="true" >
< f:validateLength minimum ="2" maximum ="100" />
</ h:inputText >
< h:message for ="name" />
< h:outputText value ="图书描述:" />
< h:inputText id ="desc" size ="30" value ="#{action.currentBook.desc}" required ="true" >
< f:validateLength minimum ="2" maximum ="100" />
</ h:inputText >
< h:message for ="desc" />
</ h:panelGrid >
< h:commandButton value ="保存" action ="#{action.save}" />
< br />
</ h:form >
</ f:view >
</ body >
</ html >

struts.xml

<? xmlversion="1.0"encoding="GBK" ?>
<! DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>

< struts >
< constant name ="struts.custom.i18n.resources" value ="messageResource" />
< constant name ="struts.i18n.encoding" value ="GBK" />

< package name ="jsf" extends ="jsf-default" >
< interceptors >
< interceptor-stack name ="jsfFullStack" >
< interceptor-ref name ="params" />
< interceptor-ref name ="basicStack" />
< interceptor-ref name ="jsfStack" />
</ interceptor-stack >
</ interceptors >
< default-interceptor-ref name ="jsfFullStack" />
</ package >

< package name ="lee" extends ="jsf" >
< action name ="list" class ="lee.action.BookAction" >
< result name ="success" type ="jsf" />
</ action >
< action name ="edit" class ="lee.action.BookAction" >
< result name ="success" type ="jsf" />
< result name ="list" type ="redirect" > list.action </ result >
</ action >
</ package >

</ struts >

BookService

package lee.service;

import java.util. * ;
import lee.model.Book;

public class BookService
... {
privateSet<Book>bookDb;

publicBookService()
...{
bookDb
=newHashSet<Book>();
bookDb.add(
newBook(1,"Spring2.0宝典","全面介绍了Spring各个知识点"));
bookDb.add(
newBook(2,"轻量级J2EE企业应用实战","介绍实际企业的J2EE开发过程"));
}


publicSet<Book>getAllBook()
...{
returnbookDb;
}


publicBookgetBookById(intid)
...{
for(Bookb:bookDb)
...{
if(b.getId()==id)
...{
returnb;
}

}

returnnull;
}



publicvoidaddBook(Bookb)
...{
bookDb.add(b);
}

}

Book

package lee.model;


public class Book
... {
privateintid;
privateStringname;
privateStringdesc;

publicBook()
...{
}


publicBook(intid,Stringname,Stringdesc)
...{
this.id=id;
this.name=name;
this.desc=desc;
}


publicvoidsetId(intid)
...{
this.id=id;
}

publicintgetId()
...{
returnthis.id;
}


publicvoidsetName(Stringname)
...{
this.name=name;
}

publicStringgetName()
...{
returnthis.name;
}


publicvoidsetDesc(Stringdesc)
...{
this.desc=desc;
}

publicStringgetDesc()
...{
returnthis.desc;
}


publicinthashCode()
...{
returnid;
}

publicbooleanequals(Objecttarget)
...{
if(targetinstanceofBook)
...{
Bookb
=(Book)target;
if(b.getId()==this.id)
...{
returntrue;
}

}

returnfalse;
}

}

BookAction

packagelee.action;

importcom.opensymphony.xwork2.ActionSupport;

importjava.util.*;
importlee.model.Book;
importlee.service.BookService;

publicclassBookActionextendsActionSupport
{
privateBookcurrentBook;
privateinteditId;

privateBookServicebs;
publicvoidsetBs(BookServicebs)
{
this.bs=bs;
}

publicvoidsetCurrentBook(BookcurrentBook)
{
this.currentBook=currentBook;
}
publicBookgetCurrentBook()
{
//如果editId请求参数不为空,则currentBook也不为空
if(editId!=0)
{
this.currentBook=bs.getBookById(editId);
}
elseif(currentBook==null)
{
currentBook=newBook();
}
returnthis.currentBook;
}

publicvoidsetEditId(inteditId)
{
this.editId=editId;
}
publicintgetEditId()
{
returnthis.editId;
}

publicList
< Book > getAllBook()
{
List
< Book > result=newArrayList < Book > ();
for(Bookb:bs.getAllBook())
{
result.add(b);
}
returnresult;
}

publicStringsave()
{
bs.addBook(currentBook);
return"list";
}

}

struts.properties

struts.i18n.encoding=gb2312
struts.objectFactory.spring.autoWire=type

如果web应用是test.,则运行

http://localhost:8080/test/list.action 则会出现如下被装饰过的页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值