Web模块支持为模块化开发、框架使用提供了巨大的方便,例如需要在Web应用中使用Web框架,这就只要将该框架的JAR包复制到Web应用中即可。因为这个Jar包的META—INF目录下可以通过web-fragment.xml文件来配置该框架所需要的服务和资源等,从而避免修改已经有的应用。Web模块支持对于模块化开发也有很大的帮助,开发都可以将不同模块的Web组件部署在不同的模块中,从而避免所有模块的配置、部署信息都写在Web.xml文件中,这对以后的升级、维护将更加方便。
模块化的3大特点:
1、允许在没有框架配置的情况下使用框架
—— 为您的应用程序保留Web.xml
—— 将框架配置工作放在框架这边
2、允许框架将它们的Web.xml存储在自己的JAR中
—— 在应用程序启动期间合并它们
3、Web.xml的分段概念
从上面的3大特点,我们可以看出,Servlet3.0模块化,就是把Web.xml分段,然后把分段的web-fragment.xml配置和资源打成Jar包,
然后在Web容器在启动时,动态加载这个模块的web-fragment.xml到web.xml中。
模块化的资源构成:
|—— META-INF
|—— web-fragment.xml
|—— resources (可选,可呈现的资源,例如:jsp,图片等,在这里还可以再建子目录,这个目前相当于父项目的webapp目录,如果出现同目录同文件的情况,会显示父目录的文件,所以大家要注意这方面,注意文件名和目录的命名)
|—— Java代码
|—— 模块功能的相关配置文件
在这里我不去介绍web-fragment.xml的结构,因为这个文件与Web.xml几乎是一样的,下面在给出例子的时候,会在例子中的web-fragment.xml中
添加了说明,到时一看就明了。
下面我们以一个实践来举例说明,当然我们的例子是最简单的,重点的讲解Web模块的知识:
1、在这里我们需要创建2个Web模块,一个是beforemodule,它提供了查看在线用户的功能,区别登录用户或者游客,在这个模块中有4个文件:
web-fragmemnt.xml:
beforemodule beforemodule Web.listener.OnlineListener /Web/jsp/online.jsp
OnlineListener.java:
public class OnlineListener implements ServletContextListener
{
//模拟保存用户名和最近的访问时间
public static Map map = new HashMap();
//超过该时间(10分钟)没有访问本站即认为用户已经离线
public final int MAX_MILLIS = 10 * 60 * 1000;
//这里只是一个加载配置文件的示例,只是为了说明配置文件应该放在那个目录
private Properties properties = new Properties();
@Override
public void contextInitialized(ServletContextEvent arg0)
{
try
{
//使用当前的Class的ResourceAsStream即可得到该文件
properties.load(this.getClass().getResourceAsStream("/config.properties"));
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
//第5秒检查一次
new javax.swing.Timer(1000 * 5, new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
System.out.println(properties.getProperty("username")+"==================");
Set keys = map.keySet();
String username = "";
Iterator iter = keys.iterator();
while(iter.hasNext())
{
username = iter.next();
//如果距离上交访问时间超过了指定时间
if(System.currentTimeMillis() - map.get(username) > MAX_MILLIS)
{
//则超过的用户删除
map.remove(username);
}
}
}
}).start();
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
// TODO Auto-generated method stub
}
}
online.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="Web.listener.OnlineListener,java.util.*" %>
在线用户
<%
Set keys = OnlineListener.map.keySet();
String username = "";
Iterator iter = keys.iterator();
while(iter.hasNext())
{
username = iter.next();
%>
用户名 <%=username==null?"游客":username %> 时间 <%=OnlineListener.map.get(username) %>
<%
}
%>
config.properties
username=lyndon
编译成Jar包后,放到一个已经存在的Web项目中的WEB-INF/lib文件夹下,(大家可以放在/ROOT/WEB-INF/lib工程下)
2、一个aftermodule模块,它提供了用户登录页面,监听用户请求的功能。在这个模块中有3个文件:
web-fragment.xml:
aftermodule aftermodule org.after.listener.RequestListener beforemodule
RequestListener.java:
public class RequestListener implements ServletRequestListener
{
@Override
public void requestInitialized(ServletRequestEvent arg0)
{
HttpServletRequest request = (HttpServletRequest)arg0.getServletRequest();
HttpSession session = request.getSession();
//从Session获取Username,如果存在,则是登录用户,为Null则为游客
String username = (String) session.getAttribute("username");
System.out.println(username);
//每访问一次,更新一次访问时间
OnlineListener.map.put(username, System.currentTimeMillis());
}
@Override
public void requestDestroyed(ServletRequestEvent arg0)
{
// TODO Auto-generated method stub
}
}
request.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
访问页面
<%
String username = request.getParameter("username");
if (null != username)
{
session.setAttribute("username", username);
}
if (null == session.getAttribute("username"))
{
%>
<%
}
else
{
%>
<%=session.getAttribute("username")%>,你好
<%
}
%>
编译成Jar包后,放到一个已经存在的Web项目中的WEB-INF/lib文件夹下
要注意上面2个的顺序,因为在web-fragment.xml中指定的前后顺序,先放beforemodule,再放aftermodule,重启Web容器,即可。
如果查看效果,不断打开IE,然后访问requst.jsp,然后关闭浏览器,再打开再做重复的动作,因为在这里我们是用session来判断不同的用户的,所以当多次登录后,
然后再打开online.jsp页面,就会看到在线用户了,过了10分钟后,再查看online.jsp,就会看到一些用户过时了。
最近把代码传上,因为我是使用Maven创建的项目,所以目录是按Maven的要求的文档目录放的,但是POM.xml编译后,打成Jar包后,结构是正确的,如果想自己
编译,需要同学会Maven基本知识。