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
< 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/j2ee http://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 >
<!-- JavaServer Faces Servlet Configuration, not used directly -->
< servlet >
< servlet-name > faces </ servlet-name >
< servlet-class > javax.faces.webapp.FacesServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >
<!-- JavaServer Faces Servlet Mapping, not called directly -->
< servlet-mapping >
< servlet-name > faces </ servlet-name >
< url-pattern > *.action </ url-pattern >
</ servlet-mapping >
</ web-app >
spring配置文件
<!-- 指定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/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
< bean id ="bs" class ="lee.service.BookService" />
</ beans >
sitemesh装饰配置文件
< 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
<% ... @ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<% ... @ taglib uri="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
<% ... @ taglib uri="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
font: normal x-small verdana, 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: 0 1 1 1;
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
< head >
< title > 作者图书 </ title >
</ head >
< body >
< center >
Spring2.0宝典 < br >
轻量级J2EE企业应用实战 < br >
基于J2EE的Ajax宝典
</ center >
</ body >
</ html >
被装饰页面link.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
<% ... @ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<% ... @ taglib prefix="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
<% ... @ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<% ... @ taglib prefix="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
<! DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.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
import java.util. * ;
import lee.model.Book;
public class BookService
... {
private Set<Book> bookDb;
public BookService()
...{
bookDb = new HashSet<Book>();
bookDb.add(new Book(1 , "Spring2.0宝典" , "全面介绍了Spring各个知识点"));
bookDb.add(new Book(2 , "轻量级J2EE企业应用实战" , "介绍实际企业的J2EE开发过程"));
}
public Set<Book> getAllBook()
...{
return bookDb;
}
public Book getBookById(int id)
...{
for (Book b : bookDb)
...{
if (b.getId() == id)
...{
return b;
}
}
return null;
}
public void addBook(Book b)
...{
bookDb.add(b);
}
}
Book
public class Book
... {
private int id;
private String name;
private String desc;
public Book()
...{
}
public Book(int id , String name ,String desc)
...{
this.id = id;
this.name = name;
this.desc = desc;
}
public void setId(int id)
...{
this.id = id;
}
public int getId()
...{
return this.id;
}
public void setName(String name)
...{
this.name = name;
}
public String getName()
...{
return this.name;
}
public void setDesc(String desc)
...{
this.desc = desc;
}
public String getDesc()
...{
return this.desc;
}
public int hashCode()
...{
return id;
}
public boolean equals(Object target)
...{
if (target instanceof Book)
...{
Book b = (Book)target;
if (b.getId() == this.id)
...{
return true;
}
}
return false;
}
}
BookAction
import com.opensymphony.xwork2.ActionSupport;
import java.util.*;
import lee.model.Book;
import lee.service.BookService;
public class BookAction extends ActionSupport
{
private Book currentBook;
private int editId;
private BookService bs;
public void setBs(BookService bs)
{
this.bs = bs;
}
public void setCurrentBook(Book currentBook)
{
this.currentBook = currentBook;
}
public Book getCurrentBook()
{
//如果editId请求参数不为空,则currentBook也不为空
if (editId != 0)
{
this.currentBook = bs.getBookById(editId);
}
else if (currentBook == null)
{
currentBook = new Book();
}
return this.currentBook;
}
public void setEditId(int editId)
{
this.editId = editId;
}
public int getEditId()
{
return this.editId;
}
public List < Book > getAllBook()
{
List < Book > result = new ArrayList < Book > ();
for (Book b : bs.getAllBook())
{
result.add(b);
}
return result;
}
public String save()
{
bs.addBook(currentBook);
return "list";
}
}
struts.properties
struts.i18n.encoding=gb2312
struts.objectFactory.spring.autoWire=type
如果web应用是test.,则运行
http://localhost:8080/test/list.action 则会出现如下被装饰过的页面