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. [ACM] POJ 1942 Paths on a Grid (组合)

    Paths on a Grid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21297   Accepted: 5212 ...

  2. ZendFramework2学习笔记 表单过滤、表单验证

    ZF2有非常多内建的Filter和Validator组件,能够方便地对表单数据进行处理. Filter的作用是过滤表单数据.比如,去除一些空格,替换一些敏感词等. Validator的作用是检验表单数 ...

  3. 使用golang来设计我们的Ubuntu Scope

    我们知道golang越来越被非常多的开发人员来开发应用.go语言也能够用于开发Ubuntu Scope. 在今天的教程中.我们将具体介绍怎样使用go语言来开发我们的Scope.这对于非常多的不太熟悉C ...

  4. 卸载完百度影音以后天气助手还在,而且总是自己主动打开ie浏览器,解决方式

    今天暴风影音不好用了.我就安装了百度影音,还有意外发现.相同的视频,用百度影音看不清楚,然后我就直接卸载了.结果卸掉以天气小助手还是在,而且总弹白色小框框,各种广告.最忍不了的是还自己主动打开ie浏览 ...

  5. cocos2d-x开发的《派对小游戏》-github源代码分享

    这是博主非常久曾经写的一个cocos2d-x跨平台小游戏,我称它为<派对小游戏>,如今分享给大家.希望对大家有所帮助的话. 项目源代码地址:https://github.com/xieba ...

  6. How to build CppCMS 1.x.x

    How to build CppCMS 1.x.x Requirements Mandatory Requirements Recommended Dependencies Suggested Dep ...

  7. selenium3 + python - css定位

    一.css:属性定位 1.css可以通过元素的id.class.标签这三个常规属性直接定位到 2.如下是百度输入框的的html代码: <input id="kw" class ...

  8. [BZOJ2017][Usaco2009 Nov]硬币游戏(要复习系列)

    又是DP? 好吧,或者说是博弈论,但是我不会啊. 先搞个O(n^3)的记忆化搜索,然后瞎搞好像发现两个状态几乎一样? 竟然过了样例,然后竟然A了... #include<iostream> ...

  9. IP地址库

    吐槽 前两天一个线上的IP地址库除了点幺蛾子,一查代码,发现用的库早就不更新了,遂决定换库,有几个方案: 纯真数据库 IPIP数据库 GeoIP 纯真数据库是大码农的福音,免费,但是精度一般:IPIP ...

  10. 3.sql基础

    sql语句是和dbms交谈专用的语句,不同dbms都认sql语法 sql语句中字符串用单引号 sql语句是大小写不敏感的,不敏感指的是sql关键字,字符串值还是大小写敏感的 创建表.删除表不仅可以手工 ...