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中。

模块化的资源构成:

<webModule>.jar  Web模块是jar包,结构如下:
|—— 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:

<?xml version="1.0" encoding="UTF-8"?>  
<web-fragment id="WebFragment_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">  
<display-name>beforemodule</display-name>   
 <!-- 指定该Web模块的唯一标识 -->  
 <name>beforemodule</name>   
 <listener>  
     <listener-class>Web.listener.OnlineListener</listener-class>  
 </listener>  
 <welcome-file-list>  
     <welcome-file>/Web/jsp/online.jsp</welcome-file>  
 </welcome-file-list>  
 <ordering>  
     <!-- 用于配置该Web模块必须位于哪些模块之前加载 -->  
     <before>  
         <!-- 用于指定于其他所有模块之前加载 -->  
         <others/>  
     </before>  
 </ordering>  
 </web-fragment>  

OnlineListener.java:

public class OnlineListener implements ServletContextListener  
{  
    //模拟保存用户名和最近的访问时间  
    public static Map<String,Long> map = new HashMap<String,Long>();  
      
    //超过该时间(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<String> keys = map.keySet();  
                String username = "";  
                Iterator<String> 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.*" %>  
<!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=UTF-8">  
<title>在线用户</title>  
</head>  
<body>  
<table>  
<%  
Set<String> keys = OnlineListener.map.keySet();  
String username = "";  
Iterator<String> iter = keys.iterator();  
while(iter.hasNext())  
{  
    username = iter.next();  
      
%>  
<tr><td>用户名</td><td><%=username==null?"游客":username %></td><td>时间</td><td><%=OnlineListener.map.get(username) %></td></tr>  
<%  
}  
%>  
</table>  
</body>  
</html>  


config.properties
username=lyndon  

编译成Jar包后,放到一个已经存在的Web项目中的WEB-INF/lib文件夹下,(大家可以放在/ROOT/WEB-INF/lib工程下)

2、一个aftermodule模块,它提供了用户登录页面,监听用户请求的功能。在这个模块中有3个文件:
web-fragment.xml:

<?xml version="1.0" encoding="UTF-8"?>  
<web-fragment id="WebFragment_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">  
<display-name>aftermodule</display-name>   
 <name>aftermodule</name>  
 <listener>  
     <listener-class>org.after.listener.RequestListener</listener-class>  
 </listener>  
 <ordering>  
     <!-- 用于配置该模块位于那个模块后加载 -->  
     <after>  
         <!-- 指定该模块是位于beforemodule配置后加载 -->  
         <name>beforemodule</name>  
     </after>  
 </ordering>  
 </web-fragment> 
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"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<title>访问页面</title>  
</head>  
<body>  
    <%  
        String username = request.getParameter("username");  
        if (null != username)  
        {  
            session.setAttribute("username", username);  
        }  
        if (null == session.getAttribute("username"))  
        {  
    %>  
    <FORM action="/app/request.jsp" method="post">  
        <INPUT type="text" id="username" name="username" value="" /> <INPUT  
            type="submit" value="提交" />  
    </FORM>  
    <%  
        }  
        else  
        {  
    %>  
    <span><%=session.getAttribute("username")%>,你好</span>  
    <%  
        }  
    %>  
</body>  
</html>  

编译成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基本知识。

源码下载:

链接:https://pan.baidu.com/s/1WOd-8ne8myR2E7D3s_RIxQ 密码:i978

原文地址:http://lyndon-lin.iteye.com/blog/1879609













作者:星辰 时间:2018-05-22 浏览 2891评论 0 赞 0砸 0 标签: servlet
评论
还可以再输入500个字

请您注意

·自觉遵守:爱国、守法、自律、真实、文明的原则
·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规
·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品
·承担一切因您的行为而直接或间接导致的民事或刑事法律责任
·您在NoteShare上发表的作品,NoteShare有权在网站内保留、转载、引用或者删除
·参与本评论即表明您已经阅读并接受上述条款