struts的tiles插件是非常实用的,从某些方面可以很好的增加页面的灵活性,记得以前外包到华为开发portalone项目,其自行代码构造了类似tiles的插件并与后台数据库结合,页面的风格和布局完全由数据库控制,当时在里面一直研究他的代码,到最后也看的八九不离十了,主要也就是将页面分为频道->窗口->列的父子关系然后基于struts的标签来完成的,虽然最后也同样实现titles的功能,但是在我看来没特殊需求那样做完全没必要...扯远了,开始配置tiles插件.
首先添加所需要的包
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>2.1.4</version>
</dependency>
然后在web.xml配置tiles监听
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
tiles对于action来说就是一个返回类型,也就是type,如"redirect"就是result的其中一个返回类型,我们配置重要的一步就是告诉struts有tiles这么一个类型,就可以说是注册一个类型,主要有两种方式
1.package直接继承"tiles-default"
<package name="crud-default" extends="tiles-default">
</package>
tiles-default是tiles提供默认的包,他本身已拥有tiles类型,来看看源配置
<struts>
<package name="tiles-default" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
</package>
</struts>
2.在包内手动注册tiles类型
<package name="crud-default" extends="struts-default">
<result-types>
<result-type name="tiles"
class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
</package>
配置好类型以后我们就要用tiles给我们的约定来创建页面了,我们在WEB-INF下创建tiles.xml
<tiles-definitions>
<definition name="hello" template="/WEB-INF/layout/layout.jsp">
<put-attribute name="title" value="tiles框架测试" />
<put-attribute name="leftmenu" value="/WEB-INF/layout/leftMenu.jsp" />
<put-attribute name="head" value="/WEB-INF/layout/head.jsp" />
<put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" />
<put-attribute name="body" value="" />
</definition>
</tiles-definitions>
layout.jsp是我的一个模板页面,tiles框架测试我讲用他来作为页面的地址,leftMenu.jsp是我的左边菜单页面,head 和 footer 是我页面的头部和底部,在我的工程里大部分页面 这三个页面都是固定的,只有右边部分是需要动态改变的,所以重点就是<put-attribute name="body" value="" />这句,我们没有对body添加页面,因为它是动态的需要我们在代码里面对它进行赋值,我们再来看看layout.jsp里面的代码
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title><tiles:getAsString name="title"/></title>
</head>
<body>
<div class="head">
<tiles:insertAttribute name="head"/>
</div>
<div class="leftMenu">
<tiles:insertAttribute name="leftMenu"/>
</div>
<div class="body">
<tiles:insertAttribute name="body"/>
</div>
<div class="footer">
<tiles:insertAttribute name="footer"/>
</div>
</body>
</html>
只是一个简单的布局页面,美工可以尽情发挥,和程序员不干扰
最后就是编码过程中的使用了,看代码
public void setTemplate(String key,String path){
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
TilesContainer container = ServletUtil.getCurrentContainer(request, request.getSession().getServletContext());
AttributeContext context = container.startContext(request,response);
context.putAttribute(key, new Attribute("/WEB-INF/content/"+path));
}
这个是我提出的公共方法,一般放在action的父类里,这里方便起见我直接放在action里了,这个方法告诉tiles某key的值是什么,根据tiles.xml的配置,我们需要对body进行赋值,看代码
@Namespace("/test")
@Results({@Result(name = "onePage", location = "hello", type = "tiles")})
public class HelloAction extends ActionSupport {
public String say(){
this.setTemplate("body", "/hello.jsp");
return "onePage";
}
public void setTemplate(String key,String path){
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
TilesContainer container = ServletUtil.getCurrentContainer(request, request.getSession().getServletContext());
AttributeContext context = container.startContext(request,response);
context.putAttribute(key, new Attribute("/WEB-INF/content/"+path));
}
}
先添加了一个result,指定的local为tiles里配置的definition的name,然后我在say方法里对body进行赋值/hello.jsp,return"onPage"这个result,这样tiles监听会自动找到layout.jsp组装过后来返回了...
其实配置方式非常简单,只不过想说细一点而已....
补充struts的json插件,原理跟tiles几乎一致
首先欠佳jar包
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.2.1</version>
</dependency>
为package配置result类型
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult" />
</result-types>
java代码
private List<Object> result = new ArrayList<Object>();
@Action(value = "syaByJson", results = { @Result(name = "json", type = "json", params = {
"root", "result" }) })
public String sayByJson() {
result.add(true);
return "json";
}
result为返回的模型,json-plugin会自动帮我们转成json格式的数据,注意配置result时,parames中root 配置的参数名称 要与 list的名称一致 也就是result,并且result必须生成get set方法