JavaWeb学习之Servlet(三)----Servlet的映射匹配问题、线程安全问题

一、Servlet映射匹配问题:

在第一篇文章中的第四段(MyEclipse及Tomcat的配置)已经讲到这个知识,现在再细化一下:

由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

<servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。例如:

    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.vae.servlet.MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/servlet/MyServlet</url-pattern>
    </servlet-mapping>

需要注意的是:

1、一个<servlet>可以对应多个<serlvet-mapping>,从而一个Servlet可以有多个路径来访问

2、url-partten中的路径也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

由于*的引入,有可能一个路径被多个urlpartten匹配,这是优先级判断条件如下:

  • 哪个越精确找哪个
  • *.后缀的格式永远匹配级最低

【举例】

对于如下的一些映射关系:

  • Servlet1 映射到 /abc/*
  • Servlet2 映射到 /*    (表示任何路径都能匹配)
  • Servlet3 映射到 /abc
  • Servlet4 映射到 *.do

问题:

  • 当请求URL为“/abc/a.html”时,“/abc/*”和“/*”都匹配,哪个servlet响应?Servlet引擎将调用Servlet1。
  • 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应?Servlet引擎将调用Servlet3。
  • 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet1。
  • 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet2。
  • 当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet2。

 

3、可以在<serlvet>标签里配置<load-on-startup>可以用来指定启动顺序。Servlet默认是在第一次被访问的时候创建,如果配置了这个标签,就会随着Web应用的启动而创建。举例:

    <servlet>
        <servlet-name>Servlet2</servlet-name>
        <servlet-class>Servlet2</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

第4行的int值表示多个serlvet的启动顺序。 

 

4、缺省Servlet:

如果有一个Servlet的url-partten被配置为了一根正斜杠"/",这个Servlet就变成了缺省Serlvet.其他Servlet都不处理的请求,由缺省Servlet来处理.

其实对于静态资源的访问就是由缺省Servlet来执;设置404页面、500页面等提示页面也是由缺省Servlet来执行。通常我们不会自己去配置缺省Servlet

 

二、线程安全问题

Servlet引擎采用多线程模式运行,它为并发的每个访问请求都使用一个独立的线程来进行响应。

由于默认情况下Servlet在内存中只有一个对象,当多个浏览器并发访问Servlet时就有可能产生线程安全问题。

面试题目注意:Servlet线程不安全,自始至终只维护一个实例。

注:线程安全本质即:同一个资源被多个线程同时操作,可能会互相干扰。  

解决方案:

1、SingleThreadModel接口(标记接口,单线程模型接口):不能真的防止线程安全问题(已过时)

Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用Servlet的service方法。对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用独立的一个Servlet实例对象

注:此接口在API 2.4中就已经过时,虽然解决了线程安全问题,但是消耗了大量性能(不同的客户端同时访问会创建不同的Servlet实例),所以此方法建议不用,实际开发中也不用。

2、使用同步代码块:效率降低

下列需要考虑线程安全问题:(多个线程同时访问数据时)

  • 访问成员变量时(所以,在Servlet中定义成员变量时,需要考虑线程安全问题) 
  • 访问共享资源时

注:Servlet中尽量不要使用成员变量。

代码举例:访问成员变量时,要考虑线程安全问题

 1 public class MyServlet1 extends HttpServlet {
 2     private static final long serialVersionUID = 1L;
 3
 4     public int count = 10;// 在Servlet中定义成员变量,需要考虑线程安全问题
 5
 6     public MyServlet1() {
 7         super();
 8     }
 9
10     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
11         doPost(request, response);
12     }
13
14     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
15
16         synchronized (this) {
17             count ++;
18         }
19     }
20
21 }

 

最终解决方案:在Servlet中尽量少用类变量(成员变量),如果一定要用类变量则用锁来防止线程安全问题,但是要注意锁住内容应该是造成线程安全问题的核心代码,尽量的少锁主内容,减少等待时间提高servlet的响应速度。

 

时间: 2025-01-21 05:06:59

JavaWeb学习之Servlet(三)----Servlet的映射匹配问题、线程安全问题的相关文章

JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板

一.http协议回顾: 在上一篇文章中:JavaWeb学习之Servlet(一)----MyEclipse及Tomcat的配置,我们通过在浏览器输入url,就能看到在MyEclipse中编写的Servlet资源,效果如下: 上图中,整个过程是这样的:浏览器中输入url后,会通过hosts文件/dns服务器解析为IP地址,进而找到对应ip地址的服务器. 在这期间,浏览器会通过http协议发出请求.服务器端收到请求后,做了下面这些事: (1)分析出当前请求的是哪台虚拟主机: 查看Host请求头分析出

JavaWeb学习之Servlet(一)----MyEclipse及Tomcat的配置

[开发环境] 物理机版本:Win 7旗舰版(64位) jdk版本:jdk1.8.0_20 MyEclipse版本:10.7.1 Tomcat版本:apache-tomcat-7.0.57 一.Servlet的基本概念: Servlet是sun提供的一种动态web资源开发技术.本质上就是一段java小程序.可以将Servlet加入到Servlet容器中运行. Servlet容器:能够运行Servlet的环境就叫做Servlet容器. --- tomcat web容器:能够运行web应用的环境就叫做

Servlet和Filter的url匹配url-pattern

Servlet和filter是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜. 估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,servlet和filter中的url-pattern还是有一些文章在里面的,总结了一些东西,放出来供大家参考,以免遇到问题又要浪费时间. 一.servlet容器对url的匹配过程: 当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,

java web-求大神指教关于JavaWeb学习的相关盲区?

问题描述 求大神指教关于JavaWeb学习的相关盲区? 1.javaWeb主要学的是哪几方面的知识点,这个与web前端开发有多大关系? 2.web里在做界面设计的时候,用网页设计里的标签重复写jsp文件可以实现网页打印列表,有没有别的方法可以避免重复写标签,实现相同的效果? 3.在做注册登陆案例时,jsp文档里实现列表框界面,因为Servlet里的doget( )方法传递数据有大小限制,所以调用servlet里的dopost( ),调用后在web上成功运行后,想知道超链接后出现的界面内容的源代码

Linux命名空间学习教程(三) PID

本文讲的是Linux命名空间学习教程(三) PID,[编者的话]Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源.而 LXC所实现的隔离性主要是来自内核的命名空间, 其中pid.net.ipc.mnt.uts 等命名空间将容器的进程.网络.消息.文件系统和hostname 隔离开.本文是Linux命名空间系列教程的第三篇,重点介绍PID命名空间.DockerOne在撸代码的基础上进行了校对和整理. 继上一篇关于IPC namespac

Servlet和JSP的线程安全问题

js|servlet|安全|问题 编写Servlet和JSP的时候,线程安全问题很容易被忽略,如果忽视了这个问题,你的程序就存在潜在的隐患. 1.Servlet的生命周期 Servlet的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet类.以后这个实例就负责客户端的请求,一般不会再实例化其他Servlet类,也就是有多个线程在使用这个实例.Servlet之所以比CGI效率高就是因为Servlet是多线程的.如果该Ser

Servlet开发入门(3) Servlet与表单|路径匹配详解

Servlet开发得需要JSP等技术的辅助,我们先来看一下Servlet与表单的应用. Servlet程序开发---一个实例 由于Servlet本身也存在着HttpServletRequest 和HttpServletResponse对象的声明,所以既可以使用Servlet接受用户所提交的内容 我们来以一个实例说明一下: 项目如下: 先做一个表单的页面 input.html <html> <head> <title>WEB开发</title> </he

拒绝从入门到放弃_《鸟哥的 Linux 私房菜 — 基础学习篇(第三版)》必读目录

目录 目录 前言 关于这本书 必看知识点 最后 前言 相信部分刚进入这个行业的新同学会对一个问题感到疑惑,为什么从培训学校出来的学员不被欢迎? 这里记录下一些我个人的看法(博主也曾有面试新员工的经历):说到底还是一个学习能力的问题.就这一点,从我的经历看来(曾到多家企业培训新人),培训出身的技术人员大体而言确实没有科班出身的学得更快准狠一些.学习能力这个东西其实比较虚,它并没有一个直观的考量方式,所以企业一般都会简单粗暴的使用学历.专业.项目经验来衡量.这之间反映了你的计算机知识框架是否完善.基

Jquery 学习笔记(三)240多个jQuery插件

Jquery 学习笔记(三) -240多个jQuery插件 2009年11月30日二 作者:   邦畿千里   概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是-写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不及的,它兼容 CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+). jQuery 是一个快速的,简洁的 javaScript