`

Servlet3.0 新特性之模块化实践

    博客分类:
  • J2EE
 
阅读更多

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

分享到:
评论
2 楼 luxing44530 2013-09-16  
请问, jsp页面如果在 META-INF 中, 改怎么访问?
1 楼 你不是好人 2013-08-30  
学习了

相关推荐

    Servlet 3.0jar包和source包

    4. **微容器**:Servlet 3.0引入了微容器的概念,允许在没有完整web应用部署的情况下运行部分组件,提高了模块化和部署灵活性。 5. **WebSocket支持**:虽然Servlet 3.0本身不直接支持WebSocket,但它是WebSocket ...

    servlet3.0模块实现demo

    在这个"Servlet 3.0模块实现demo"中,我们将探讨如何利用这些新特性实现一个模块化的Web项目,以及如何通过Maven进行依赖管理。 一、Servlet 3.0的主要特性 1. **注解驱动的Servlet**:在Servlet 3.0中,我们不再...

    servlet3.0 jar \ doc \pdf 相关文档资料

    Servlet 3.0引入了微容器概念,使得应用程序可以在不依赖全局web.xml的情况下运行,实现了模块化和可插拔的部署。 6. **Pluggable Contexts**: 开发者可以自定义Web应用程序上下文(ServletContext),实现更...

    test-servlet3-without-webxml.rar

    综上所述,`test-servlet3-without-webxml.rar`文件提供了关于Servlet 3.0无web.xml配置的实践案例,通过学习和分析这个项目,开发者可以深入理解Servlet 3.0的新特性和优势,提升Java Web开发技能。

    Java程序开发教学课件:15-Servlet高级编程.ppt

    在实际开发中,理解并熟练运用这些Servlet 3.0的特性,能够帮助开发者编写出更高效、更易于维护的Web应用。同时,配合MVC框架如Spring MVC,可以进一步提升开发效率和应用的可扩展性。在学习过程中,可以参考Java...

    servlet简单实现的MVC框架

    在IT行业中,MVC(Model-View-Controller)框架是一种广泛应用的设计模式,它将应用程序的业务逻辑、数据处理和用户界面分离,使得开发更加模块化和易于维护。Servlet是Java Web开发中的一个重要组件,用于接收和...

    Spring3.0源代码

    Spring3.0是Java开发领域中的一个里程碑,它是一个开源的应用框架,主要用于简化...同时,这也是学习设计模式和最佳实践的好机会,因为Spring框架本身就是一个优秀的示例,展示了如何优雅地实现松耦合和模块化设计。

    OSGi崁入Servlet的配置步驟

    OSGi(Open Services Gateway Initiative)是一种模块化系统和Java...理解并实践这些步骤,你将能够在OSGi环境中享受到模块化、动态性和灵活性带来的优势。同时,这也是深入学习OSGi框架和Java Web开发的一个好途径。

    EJB 3.0 在 WAS V7 上开发部署的最佳实践

    首先,为了保持代码的模块化和可重用性,建议在创建工程时,将EJB客户端接口和业务对象(Business Objects)放在独立的JAR模块中。这样不仅方便在不同项目间共享,还能提高代码的可维护性。在IBM Rational ...

    springMVC3.0

    Spring 3.0 MVC 引入了许多新特性,如对Java 5的支持,包括注解配置、泛型、注解以及可变参数等。此外,Spring Expression Language (SpEL) 提供了一种强大且灵活的表达式语法,可用于XML和注解配置。Spring 3.0还...

    java安全之java-web1

    动态注册API(如`addServlet`、`addFilter`和`addListener`)允许开发者在应用启动时动态添加Servlet、Filter和Listener,提高了代码的灵活性和模块化。 Servlet 3.0及以后的版本引入了注解配置,使得不再需要在`...

    spring3.0MVC中文教程.doc

    Spring3.0引入了一些重要的新特性: 1. 支持Java 5,包括注解配置、泛型和可变参数等功能。 2. 引入了Spring Expression Language (SpEL),可以在XML和注解配置中使用。 3. 支持RESTful Web服务的构建。 4. 提供了...

    Servlet与JSP核心编程(第1卷 第2版).rar

    8. **Servlet 3.0及以上版本的特性**:包括注解配置、异步处理、微容器支持等,这些新特性简化了Servlet的使用,提升了性能,并促进了模块化开发。 9. **JSP的四种动作标签**:`jsp:include`用于动态包含页面,`jsp...

    Spring3.0就这么简单源码

    、chapter7**: 这些目录分别代表书中的不同章节,每个章节可能包含源代码示例、配置文件等,帮助读者理解和实践Spring 3.0的各种特性,例如IoC(控制反转)、AOP(面向切面编程)、数据访问、事务管理等。...

    JAVA6高级编程代码4

    对于Web开发部分,可能会包含使用Servlet 3.0特性来构建动态Web应用的代码,如异步处理和注解配置。 总之,"JAVA6高级编程代码4"涵盖了Java 6中的核心开发技术,包括JDBC的高效数据库操作,MVC模式在Web应用中的...

    EJB3.0入门教程

    EJB3.0是Java EE(J2EE)5规范的一部分,它引入了许多新的特性和改进,旨在提高开发效率和代码的可读性。EJB3.0的核心变化包括: - **注解驱动(Annotation-Based)**:EJB3.0大量使用注解,如`@Entity`, `@...

    spring-frameword3.0源码

    Spring框架作为Java领域中最广泛应用的轻量级框架,其3.0版本在设计模式、模块化和性能优化上都有显著提升。本资料集合了Spring框架3.0的核心源码,为开发者提供了一个深入了解Spring内部机制的窗口。 一、核心模块...

    Spring注解驱动开发实战-servlet

    这些注解使得我们的代码更加简洁且模块化,同时也支持热部署和更好的测试性。 对于异步请求处理,Servlet 3.0引入了一个强大的特性,使得服务器可以处理大量并发请求,而无需阻塞线程。Spring框架很好地支持了这一...

    pring3.0中文文档

    Spring框架是Java开发领域中的一个核心组件,以其模块化、松耦合的特性深受开发者喜爱。Spring 3.0版本是其发展史上的一个重要里程碑,引入了许多新特性,提升了性能和易用性。Spring Security是Spring框架的一个子...

Global site tag (gtag.js) - Google Analytics