1. web.xml

关于Servlet

Servlet是一个特殊的Java类,Servlet可以输出HTML标签作为表现层使用,但自从MVC规范出来以后,明确了Servlet的指责仅作为控制器使用,不再生成页面标签,也不再作为视图层角色使用。

Servlet类继承自HttpServlet类,包含了常用处理浏览器请求的方法如doGet, doPost, doPut, doDelete, init, destroy等。

一个典型Servlet接受客户端请求的场景如

 @WebServlet(name="firstServlet", urlPatterns={"/firstServlet"})
public class FirstServlet extends HttpServlet
{
  public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException
  {
String name = request.getParameterValues("name");
PrintStream out = new PrintStream(response.getOutputStream);
out.println("name="+name+"<br/);
  }
}

1.1配置文件介绍

web.xml是servlet2.5以前java web必须包含的配置文件,web.xml作为一个web应用的入口,将被web容器(例如tomcat的Context容器)解析并初始化。

web.xml主要用来配置以下信息

  • 配置JSP,以及JSP属性
  • 配置Servlet
  • 配置Listener
  • 配置Filter
  • 配置标签库
  • 配置和管理JAAS授权认证
  • 配置和管理资源引用
  • 配置应用首页:<welcom-file-list>

1.2.web.xml 配置文件内容

1.2.1 配置Servlet

一个Servlet配置项由<servlet>和<servlet-mapping>两个子元素组成。

其中<servlet>用来配置Servlet的名称,处理Servlet的类,初始化参数等。

<servlet-mapping>用来配置Servlet的URL,这项为可选。

下面这个例子是在J2EE WEB中集成SSH时的web.xml配置,其中配置了一个

 <servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

1.3.web容器与Servlet的关系及Servlet工作原理

1.3.1 web容器与Servlet的关系

Tomcat 的容器等级中,Servlet将被包装成Wrapper容器,而Tomcat的 Context 容器是直接管理Wrapper,如下图。

一个 Context 对应一个 Web 工程,在 Tomcat 的配置文件中可以很容易发现这一点,如下:<Context path="/projectOne " docBase="D:\projects\projectOne" reloadable="true" />

1.3.2 Servlet工作原理

a)Tomcat容器启动过程

  • 在Tomcat中新增一个Context容器
  • 关键一步:使用ContextConfig解析web应用的配置文件,包括创建ClassLoader加载web应用 class字节码文件,获取ServletContext并设置参数,初始化“load on startup”的 Servlet等等。
  • 最后将Context容器添加到Tomcat Host中,并启动Tomcat

b)Web应用初始化过程

Web 应用的初始化工作是在 ContextConfig 的 configureStart 方法中实现的,WebXml 对象中的属性设置到 Context 容器中,这里包括创建 Servlet 对象、filter、listener 等等

初始化web应用的过程就是一个将 Servlet 包装成 Context 容器中的 StandardWrapper的过程。

c)创建Servlet实例

1)创建Servlet对象

前面已经完成了 Servlet 的解析工作,并且被包装成 StandardWrapper 添加在 Context 容器中,但是它仍然不能为我们工作,它还没有被实例化。下面我们将介绍 Servlet 对象是如何创建的,以及如何被初始化的.

首先是对于load-on-startup类型的Servlet,在Context 容器启动的时候就会被实例化。

对于非load-on-startup的创建 Servlet 实例的方法是从 Wrapper. loadServlet 开始的。loadServlet 方法要完成的就是获取 servletClass 然后把它交给 InstanceManager 去创建一个基于 servletClass.class 的对象。

2)初始化Servlet对象

初始化 Servlet 在 StandardWrapper 的 initServlet 方法中,这个方法很简单就是调用 Servlet 的 init 的方法,同时把包装了 StandardWrapper 对象的 StandardWrapperFacade 作为 ServletConfig 传给 Servlet

如果该 Servlet 关联的是一个 jsp 文件,那么前面初始化的就是 JspServlet,接下去会模拟一次简单请求,请求调用这个 jsp 文件,以便编译这个 jsp 文件为 class,并初始化这个 class。这样 Servlet 对象就初始化完成了

d)Servlet工作原理

我们已经清楚了 Servlet 是如何被加载的、Servlet 是如何被初始化的,以及 Servlet 的体系结构,现在的问题就是它是如何被调用的

当用户从浏览器向服务器发起一个请求,通常会包含如下信息:http://hostname: port /contextpath/servletpath,hostname 和 port 是用来与服务器建立 TCP 连接,而后面的 URL 才是用来选择服务器中那个子容器服务用户的请求。那服务器是如何根据这个 URL 来达到正确的 Servlet 容器中的呢?

Tomcat7.0 中这件事很容易解决,因为这种映射工作有专门一个类来完成的,这个就是 org.apache.tomcat.util.http.mapper,这个类保存了 Tomcat 的 Container 容器中的所有子容器的信息,当 org.apache.catalina.connector. Request 类在进入 Container 容器之前,mapper 将会根据这次请求的 hostnane 和 contextpath 将 host 和 context 容器设置到 Request 的 mappingData 属性中。所以当 Request 进入 Container 容器之前,它要访问那个子容器这时就已经确定了。

1.4 Servlet生命周期

前面已经说了创建Servlet有两个时机,对于load-on-startip这种Servlet,在web容器(例如tomcat里的context容器)被初始化候就会创建一个Servlet实例,而其他类型的Servlet要等到客户端第一次请求时候才创建。

Servlet生命周期如下

1)创建Servlet实例

2)Web容器调用Servet的init方法初始化Servlet实例

3)被初始化后的Servlet实例将一直存在于Web容器中,用来响应客户端请求

4)当Web容器决定销毁Servlet实例时,会先调用Servlet的destroy方法,通常在关闭web容器前会先销毁Servlet。

1.5 Servlet中的filter

Filter有点类似加强版的Servlet,Servlet只是响应请求,而Filter会在响应请求前后添加新功能。

javax.servlet.Filter中定义了一个重要的方法doFilter,因此重写这个方法可以对每个请求前后添加额外功能。例如添加日志,或者权限检查(根据参数 HttpSession)等。

通过Filter,可以在请求前后进行处理,添加新功能,甚至决定阻止请求等。

下面是一个典型例子,用来检查用户权限,例子中一个Filter可以对应多个URL

 <filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.cathaypacific.member.controller.filter.MemberLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/profile/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/request/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/account/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/miles/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

1.6 Servlet中的listener

Listener是Servlet API中用来监听各种事件(例如Web应用启动、停止,用户Session开始,用户Session结束,用户请求到达等),

通过实现各种Listener的方法,可以在特定事件发生时进行特定操作,例如用户登录session产生时候,可以将session存入application范围内的map中,从而实现统计当前用户数的功能。

通过自定义一个Listener实现类,并在web.xml中配置,就可以监听各种事件。

常见配置在web.xml中的监听器,

 <listener>
<listener-class>com.cathaypacific.framework.session.SessionListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.cathaypacific.member.controller.listener.TransactionManagerBootstrapListener</listener-class>
</listener>

常用Web事件监听接口:

ServletContextListener:用来监听Web应用的启动和关闭

ServletContextAttributeListener:用来监听ServletContext范围内(即application范围)的属性的改变

ServletRequestAttributeListener:用来监听ServletRequest范围内(即request范围)的属性的改变

ServletRequestListener:监听用户请求

HttpSessionListener:监听用户session开始和结束

目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、 ServletRequestListener、HttpSessionAttributeListener 和 2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。如下图所示:

1.7 Servlet容器的类加载器加载顺序

我们注意到Tomcat的安装目录下也有一个lib目录,这个与Web应用中的lib目录的区别在于:
Tomcat的lib子目录:存放的JAR文件不仅能被Tomcat访问,还能被所有在Tomcat中发布的JavaWeb应用访问。
JavaWeb应用的lib子目录:存放的JAR文件只能被当前JavaWeb应用访问。
假如Tomcat类加载器要加载一个MyClass的类,它会按照以下先后顺序到各个目录中去查找MyClass的class文件,直到找到为止,如果所有目录中都不存在MyClass.class的文件,则会抛出异常:
1、在JavaWeb应用的WEB-INF/classes中查找MyClass.class文件。
2、在JavaWeb应用的 WEB-INF/lib目录下的JAR文件中查找MyClass.class文件。
3、在Tomcat的lib子目录下直接查找MyClass.class文件。

4、在Tomcat的lib子目录下JAR的文件中查找MyClass.class文件。

1.8 Servlet中各种配置项的加载顺序

  1. 启动web项目后,web容器首先回去找web.xml文件,读取这个文件。
  2. 容器会创建一个 ServletContext ( servlet 上下文),整个 web 项目的所有部分都将共享这个上下文。
  3. 容器将web.xml转换为键值对,并交给 servletContext
  4. 容器创建web.xml中的类实例,创建Listener监听器。
  5. 容器加载filter,创建过滤器, 要注意对应的filter-mapping一定要放在filter的后面。
  6. 容器加载servlet,加载顺序按照 Load-on-startup 来执行,Load-on-startup大于0的servlet将在web容器创建之后立即实例化,否则要在用到servlet时候才实例化

因此它的完整加载顺序就是 :ServletContext -> context-param -> listener-> filter -> servlet

不过有一点需要注意的是: spring容器的加载要在servlet之后,因此在有些过滤器当中需要提前用到spring bean的时候,就需要改成 Listener 的方式

有关Servlet的内容参考自  https://www.ibm.com/developerworks/cn/java/j-lo-servlet/

1.9 Servlet线程安全问题

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet 容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有 多个线程在使用这个实例。Servlet容器会自动使用线程池等技术来支持系统的运行

这样,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。

例如下面这个典型的例子,

 public class ConcurrentTest extends HttpServlet {
PrintWriter output;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username;
response.setContentType("text/html;charset=gb2312");
username=request.getParameter("username");
output=response.getWriter();
try {
//为了突出并发问题,在这设置一个延时
Thread.sleep(5000);
output.println("用户名:"+username+"<BR>");
} catch (Exception e) {
e.printStackTrace();
}
}
}

如果同时有两个访客(线程)恰好使用的是Servlet线程池中的同一个Servlet实例, 如果时间足够短, 第二个访客很可能覆盖第一个访客的output变量,导致第一个访客对应线程,将数据输入到第二个访客的页面中去,

具体例子参考自:http://www.cnblogs.com/gw811/archive/2012/09/07/2674859.html

要解决这个问题, 通常是建议尽量避免使用实例变量。

2.struts.xml

此文件用来配置Action和request之间的映射关系,通常放在类加载目录,即WEB-INF/classes下。

另外,struts.xml还可以用来配置常量,配置bean,导入其他配置等。

2.1配置Action

通常Action总是跟interceptor一起配置到一个package中,interceptor将会在action前后执行,顺序由配置的位置决定?

一个典型的action+interceptor组合配置如下,自定义的interceptor中可以指定实现类,action中也可以指定处理类和处理方法,以及结果(可以是数据或者页面)

 <struts>
<package name="test"extends="struts-default">
<interceptors>
<interceptor name="abc"class ="ceshi.AuthorizationInterceptor"/>
</interceptors>
<action name="TestLogger"class="vaannila.TestLoggerAction">
<interceptor-refnameinterceptor-refname="abc"/>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>

2.1配置常量

例如

struts.local, 默认值en_US

struts.i18n.encoding,默认值UTF-8

struts.objectFactory.spring.autoWire, 默认是name

2.2配置包含其他文件

struts2默认加载class路径下的struts.xml, default-struts.xml, struts-plugin.xml 文件。

也可以在struts.xml中使用include导入其他配置文件,例如<include file="struts-part1.xml"/>

3.

基于SSH的J2EE Web系统配置文件的更多相关文章

  1. 如何实现基于ssh框架的投票系统的的质量属性

    如何实现基于ssh框架的投票系统的的质量属性: 项目 :网上考试系统 我做的是网上考试系统,因为标准化的考试越来越重要,而通过计算机进行标准化判卷,系统会自动判卷出成绩,组织考试的人不用组织人员打印试 ...

  2. 基于springboot搭建的web系统架构

    从接触springboot开始,便深深的被它的简洁性深深的折服了,精简的配置,方便的集成,使我再也不想用传统的ssm框架来搭建项目,一大堆的配置文件,维护起来很不方便,集成的时候也要费力不少.从第一次 ...

  3. 基于ssh开发彩票购买系统的设计与实现毕业设计

    开发环境: Windows操作系统开发工具: MyEclipse+Jdk+Tomcat+MYSQL数据库 运行效果图: 源码及原文地址:http://javadao.xyz/forum.php?mod ...

  4. 实现基于SSH的门票管理系统开发的质量属性

    我要做的是一个基于SSH的门票售卖系统,在系统中常见的质量属性有:可用性.可修改性.性能.安全性.易用性. 可用性方面: 可用性是指系统正常运行时间的比例,是通过两次故障之间的时间长度或在系统崩溃情况 ...

  5. 基于Spring、SpringMVC、MyBatis、Druid、Shrio构建web系统

    源码下载地址:https://github.com/shuaijunlan/Autumn-Framework 在线Demo:http://autumn.shuaijunlan.cn 项目介绍 Autu ...

  6. 基于SSH的高校网上选课系统的质量属性的实现

    我对于基于SSH的高校网上选课系统的质量属性的实现是从可用性.性能.安全性.可维护性.易用性五个方面进行的实现. 可用性方面: 实现方式:(1)当系统试图超出限制范围来进行课程查询或选课时必须进行错误 ...

  7. 基于ssh框架的在线考试系统开发的质量属性

    我做的系统是基于ssh框架的在线考试系统.在线考试系统有以下几点特性:(1)系统响应时间需要非常快,可以迅速的出题,答题.(2)系统的负载量也需要非常大,可以支持多人在线考试(3)还有系统的安全性也需 ...

  8. 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(1)-Web前端页面

    本 Web 系统框架基于C# EF6+MVC+WebApi的快速应用开发平台.本节主要介绍Web前端页面设计与实现.Web前端页面主要分为普通列表页面.树状导航列表页面.普通编辑页面.数据导入页面.向 ...

  9. 基于SSH框架的在线考勤系统开发的质量属性

    我要开发的是一个基于SSH框架的在线考勤系统. 质量属性是指影响质量的相关因素,下面我将分别从6个系统质量属性(可用性,易用性,可修改性,性能,安全性,可测试性)来分析我的系统,以及如何实现这些质量属 ...

随机推荐

  1. Openfire 配置连接SQL SERVER(非默认实例)

    安装好Openfire之后,紧接着进行配置. 连接数据库的时候遇上问题. 打算用我本机上的一个SQL SERVER做为数据库.但是,我本机装了几个SQL SERVER实例,现在我打算使用的是那个非默认 ...

  2. expect安装测试-自动登陆脚本

    安装: yum list | grep expect yum install expect 参考:http://www.cnblogs.com/iloveyoucc/archive/2012/05/1 ...

  3. Pointcut is not well-formed: expecting &#39;name pattern&#39; at character position 36

  4. 支付宝即时到帐接口的python实现,演示样例採用django框架

    因工作须要研究了支付宝即时到帐接口.并成功应用到站点上,把过程拿出来分享. 即时到帐仅仅是支付宝众多商家服务中的一个,表示客户付款,客户用支付宝付款.支付宝收到款项后,立即通知你,而且此笔款项与交易脱 ...

  5. luogu2154 [SDOI2009] 虔诚的墓主人 离散化 树状数组 扫描线

    题目大意 公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.一块墓地的虔诚度是指以这块墓地为中心的十字架的数目,一个十字架可以看成中间是墓地,墓地的正上.正 ...

  6. C# winform窗体在桌面右下角显示(任务栏上方)

    问题描述: 有一个主窗口程序,需要给该程序添加一个通知子窗口.子窗口的位置为右下角. 解决方法: 在子窗口frmPopMsg的代码文件中添加如下代码: public frmPopMsg() { Ini ...

  7. E20170815-mk

    frame  n. 框架; 边框; 眼镜框; 组织;

  8. [Apple开发者帐户帮助]一、开始(1)关于您的开发者帐户

    Apple开发人员网站提供了为Apple平台制作出色应用所需的工具和信息.如果您不熟悉Apple平台上的开发,可以免费使用.只需接受Apple开发者协议,即可为您创建一个帐户.使用此帐户下载测试版软件 ...

  9. C/C++中的绝对值函数

    --------开始-------- 对于不同类型的数据对应的绝对值函数也不相同,在c和c++中分别在头文件math.h 和 cmath 中. int : x = abs( n ) double : ...

  10. Python 38 sql基础

    数据库服务器中存放的是 库(文件加)  .表(文件) .表里面是记录(一行数据) 增     删     改     查 1.库相关 创建------------------create databa ...