文档章节

(JavaEE-04)Servlet

_-Leon-_
 _-Leon-_
发布于 2014/06/15 11:53
字数 3486
阅读 404
收藏 12
点赞 0
评论 0

#Servlet

  • Servlet是sun公司提供的一套专门用于开发动态web资源的技术
  • sun公司在ServletAPI中提供了一个servlet接口,如果需我们需要开发一个动态web资源,需要两步:
  • 编写一个Java类,实现servlet接口
  • 把开发好的Java类部署到web服务器中

###demo:使用servlet给浏览器输出“Hello World!~”

  • 首先查看ServletAPI,Servlet开发属于JavaEE技术,在JavaSEAPI中是没有的,需要查看JavaEEAPI,但是JavaEEAPI太过繁多,建议直接查看ServletAPI
  • 根据API可以得知Servlet具体释义以及相关接口和类(GenericServlet, HttpServlet)
  • 在webapps下新建一个web应用,搭建必要的目录结构与文件(WEB-INF、classes、lib、web.xml)
  • 在classes文件夹下新建一个Java源文件(也可以不在这里),文件名叫HelloServlet.java(可以不是这个名字)
  • 继承GenericServlet接口,重写service方法,在service方法中使用response对象编写给客户端发送数据的程序(获取输出流)
  • 添加import和package语句
  • 对该文件进行编译,由于有package,要使用 -d 来进行编译,而且需要使用JavaEE的类,所以需要JavaEE的Jar文件
  • 使用set classpath来设置类文件路径(set classpath=%classpath%;serlvet-api.jar文件的目录)
  • javac -d . HelloServlet.java(进行编译)
  • 将这个Servlet配置到web容器中(配置web.xml,添加servlet元素与servlet-mapping元素)
  • 启动服务器,访问Servlet

使用UML描述Servlet的调用过程

###Servlet的生命周期 Servlet会在第一次被访问的时候创建出相应的Servlet对象,为了方便后续请求的访问,Web容器创建一个Servlet对象后,会一直将其保存在容器中,以后关于该Servlet的请求,都使用该对象处理,一直不会被销毁,直到web容器关闭。也就是说,在一个Servlet运行的过程中,web容器中有且只有一个该Servlet对象存在,多个请求使用多线程来分别处理,一个请求对应一个线程,多个请求多个线程(Tomcat会给每个线程创建对应的request对象和response对象,一起交给Servlet对象),这些线程共享Servlet对象!可以得出一个结论:Servlet是非线程安全的,但是request对象和response对象是线程安全的

Servlet的生命周期演示(init方法与destroy方法)

###使用Eclipse开发Servlet

  • 怎样创建一个web项目
  • 给Eclipse配置Tomcat服务器(Tomcat使用的虚拟机与web应用编译器的版本问题)
  • 导入web开发的相关jar文件
  • Eclipse帮助我们都干了哪些事情

###HttpServlet HttpServlet指得是能够处理HTTP请求的serlvet,它在原有的Servlet接口上添加了一些HTTP协议处理的方法,它更加强大,在开发中通常继承这个类。 HttpServlet在实现Servlet接口时,重写了service方法,该方法内部会自动判断用户的请求方式,比如是get请求,则会调用HttpServlet的doGet方法,post请求,调用doPost方法。 在开发中,直接覆盖doGet和doPost方法,不用覆盖service方法。

阅读HttpServlet文档,查看HttpServlet源码(ctrl+shift+T) 使用Eclipse创建一个新的Servlet,继承HttpServlet,直接创建Servlet,自动生成配置(一个Servlet可以配置多个映射)

#Servlet细节总结

  1. **Servlet如果想要外部访问,必须把Servlet程序映射到一个URL地址上,在web.xml中使用`<servlet>`元素和`<servlet-mapping>`元素完成**
     >`<servlet>`元素用于注册Servlet,它包含两个子元素:`<servlet-name>`和`<servlet-class>`,分别用于注册Servlet的注册名称和Servlet的完整类名
     >`<servlet-mapping>`元素用于映射一个已经注册的Servet对外访问路径,它包含两个子元素:`<servlet-name>`和`<url-pattern>`,分别用于指定注册名和对外访问路径
    
  2. 用一个Servlet可以被映射到多个URL上

    在Servlet映射到的URL,可以使用通配符来配置,但是只能有两种固定的格式: > * “ * . 扩展名”,如: *.do,*.html(伪静态) > * "/* ",如:/action/*

  3. 使用了通配符后,就会产生一些新的问题,如下:

    • Servlet1 映射到 /abc/*
    • Servlet2 映射到 /*
    • Servlet3 映射到 /abc
    • Servlet4 映射到 *.do
那么当这样通配后,对于相似的URL请求会怎么去处理呢?举例来说明:

* `/abc/a.html,/abc/* 和 /* 都匹配,Servlet引擎将会调用Servlet1`
* `/abc,/abc/* 和 /abc 都匹配,Servlet引擎将会调用Servlet3`
* `/abc/a.do,/abc/* 和 *.do 都匹配,Serlvet引擎将会调用Servlet1`
* `/a.do,/* 和 *.do 都匹配,Servlet引擎将会调用Servlet2`
* `/xxx/yyy/a.do,/* 和 *.do 都匹配,Servlet引擎将会调用Servlet2`

\*号开头的优先级最低!不以\*开头的话,哪个最像选择哪个
  1. Servlet是不能独立运行的,它的运行完全是由Servlet引擎来控制和调度的。一个Servlet如果被访问,不管访问多少次,Web容器中之后一个Servlet对象,被多个请求(线程)共享,但是每次执行service方法,都是根据这次请求重新创建的请求对象和响应对象。当本次请求完成,请求对象和响应对象都会被销毁(响应对象的销毁在创建了标准的Http响应之后)。

  2. <serlvet>元素可以配置随着web容器的启动而创建该Servlet对象。使用<load-on-startup>元素来完成,在创建过程中,就会调用Servlet的init方法。如果有一些操作需要在服务 器启动的时候就完成,就可以使用这种方式来完成(初始化数据库连接池等)。

  3. 如果某个Servlet的映射路径为 "/",那么这个Servlet就是当前web应用的默认Servlet。凡是在web.xml中找不到映射的URL,它们的访问请求都将交给这个默认的Servlet处理,也就是说,默认的Servlet用于处理所有其它Servlet都不处理的请求。

    其实对于Tomcat来说,我们所有的请求都不能直接到达web资源,都会经过一个Servlet。如:http://localhost:8080/testweb/1.html ,如果项目根目录有一个 1.html 文件 是可以请求的到的,但其实,并不是直接访问了该资源,Tomcat有一个默认的Servlet,由这个默认的Servlet读取了这个资源,然后返回给客户端。如果没有,就是404 如果你自定义了默认的Servlet,将会覆盖掉系统的默认Servlet,所以不建议这么做。(查看Tomcat的web.xml,其实所有的静态资源,都由该Servlet处理)

  4. 线程安全

    Servlet存在线程安全问题,在实际开发中,要根据具体情况来编写解决同步的代码 在Servlet中编写程序时,要注意对象的静态属性的处理,不然会引发内容溢出的问题(对象的静态集合属性处理) 标准解决方案:同步代码块。非标准解决方案:SingleThreadModel(已经被废弃) 对于Servlet的线程安全问题,的确是一个比较灵活的问题,那么有以下几条开发建议,可以避免Servlet的线程安全问题:

  5. 尽量避免使用成员变量,如果万不得已使用了,就需要同步,但是注意同步可用性最小的代码路径

  6. 要清楚request是线程安全的,HttpSession,ServletContext都不会线程安全的

  7. 使用同步的集合类

  8. 不要在Servlet中创建自己的线程来完成某个功能(增加了复杂度)

  9. 在多个servlet中对外部对象(比如文件)进行修改操作时,一定要加锁,做到互斥的访问效果

#ServletConfig对象

  • 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数
  • 当配置了初始化参数后,在web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递 servlet。进而,在程序中通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
  • ServletConfig一般应用于帮助Servlet存储一些固定信息,如:字符编码、数据库连接、获取配置文件等
  • 如果使用的Servlet继承了HttpServlet,由于在GenericServlet中实现了对于Config对象的处理,所以在自己的Servlet中,直接使用getConfig对象就可以了。

#ServletContext对象(重点)

  • Web容器在启动时,它会为每个Web应用都创建一个对应的ServletContext对象,它代表当前web应用。
  • 通过ServletConfig对象是可以获取ServletContext对象的(如果继承了HttpServlet,可以直接使用getServletContext()来获取ServletContext对象)
  • 一个Web应用只有一个ServletContext,所以这个对象将会被所有的Servlet所共享,通过这个特性,我们可以利用ServletContext让多个Servlet进行数据传递
  • 要明白Servlet对象是由web服务器来掌管生死,千万不要自己创建Servlet对象来进行传值
  • ServletContext对象通常被称之为Context域对象
  • 查看ServletContext API文档
  • ServletContext初始化参数
  • 获取Servlet规范的版本号,获取文件的MIME类型表示
  • ServletContext可以做请求转发,将一个Servlet的请求转发给另一个,一般用于(MVC设计模式)

###MVC简单介绍 到目前为止,对于客户端的请求,我们都是使用对应的Servlet来做简单处理,但是问题是,一般的,不可能就简单在返回一个字符串或者在控制台打印一个语句,应该给客户返回一个html页面,那么这个html页面哪里来?如果这个html是个静态资源,那么很简单,但是我们开发的是动态web资源,该怎么办呢?其实很简单,使用Servlet的response对象发送html的字符流给客户端。这种方法表面上看起来是没有什么问题,但是实际操作你就会发现,这个做法相当麻烦,而且开发效率很低,应该专门有一种特殊能力的Servlet来处理html的绘制,这种具有特殊能力的Servlet就是JSP。

MVC简单介绍

JSP其实就是一个特殊的Servlet,它能很好的处理html的问题,使得页面的渲染与程序逻辑的处理可以得以分离。(demo,在Servlet中传值并转发给一个JSP)

#在Servlet中获取各种资源文件(重点)

在实际开发中,很多时候需要获取服务器上的一些别的资源来帮助开发,这些资源的获取方式都不太一样。

从web目录中读取资源文件

如果在开发中,需要的文件存储在WebContent(项目目录)中,那就使用ServletContext来读取,相关的方法有:

  • getRealPath(String path),返回一个虚拟路径对应资源的真实路径
  • getResource(String path),返回一个虚拟路径对应资源的URL对象
  • getRescourceAsStream(String path),返回一个虚拟路径对应资源的输入流
  • getResoucePaths(String path),返回一个虚拟路径下的所有对应资源的集合

这些方法中的参数都不应该是资源的绝对路径或相对路径,应该是一个针对当前应用的虚拟路径,应该以 “/” 开头,这个 "/" 就表示web应用所在目录,也成为项目根目录,然后按照资源在应用的目录结构来指定资源的虚拟路径。

从源代码src(类路径)文件夹中读取资源文件

在很多时候,我们的资源文件并不在Web资源目录中,而是在类目录中,这个时候怎么读取呢?

  • 使用类加载器来获取类路径中的资源:getSystemResource(String path),getResource(String path)
  • 使用类本身来获取类路径中的资源:getResource(String path)
  • 使用ServletContext获取项目根目录,然后按照项目层级去读取文件(WEB-INF/classes/a.txt)
  • 根据类加载器来获取资源时,不要添加 "/",类加载器会从该加载器的类路径根目录来查找 path 指定的资源,加了 "/",反而找不到。
  • 使用类本身来获取资源时,加 "/" ,意味着从类路径的根目录来查找,不加 "/",意味着,从当前类所在的文件夹来查找资源
  • web应用和本地方法运行的效果是不一样的,有关于System的资源获取,在web应用中是不起作用的
  • 还有 getResourceAsStream(String path)系列的方法,跟上述的 getResource(String path)方法特点是一致的,只不过一个是返回URL对象,一个是返回流对象
  • 使用类加载器的 getResourceAsStream(String path) 方法来获取资源的输入流时,不能实现动态读取文件变更,应该用类加载器来获取路径,然后用传统的读取文件的方式再次读取文件,这样就能实现实时更新数据了
  • 如果资源文件过大,不要使用类加载器的方式来直接获取,因为这种方式会直接把资源全部加载进内存,容易内存溢出,使用类加载器获取地址,用传统方式的流然后缓冲读取
  • 关于System与no-System的方法有什么区别,我已经总结好了,如果需要进一步了解,参看官方关于Resources的解释

#在客户端缓存Servlet的输出 对于不经常变化的数据,在Servlet中可以为其设置合理的缓存时间值,以避免浏览器频繁得向服务器发送请求,提升服务器的性能。

String data = "aaaaaaaaaaaaaaaaaaaaaa";
long time = System.currentTimeMillis() + 1 * 24 * 60 * 60 * 1000;
System.out.println("hehe");
response.setDateHeader("expires", time);
response.getWriter().write(data);

© 著作权归作者所有

共有 人打赏支持
_-Leon-_
粉丝 10
博文 17
码字总数 34045
作品 0
朝阳
部门经理
servlet xml 配置详解

2013-11-08 09:04 161人阅读 评论(0) 收藏 举报 web.xmlmyeclipse 首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关。即不会因为 filter 写在 listener 的前面而会先加载 ...

yiguangtia
2014/03/30
0
0
JavaEE细节问题04——Servlet细节问题

1.<url-patten>的优先级问题 大家都知道,在web.xml中可以通过配置<servlet>和<servlet-mapping>来让一个servlet真正跑起来,而让服务器通过URL定位到 具体serlvet的标签就是通过<url-patten......

Lunqi
2015/08/17
0
0
JSP 学习总结---学习笔记

什么是JSP 1)为什么说,Servlet是一个动态Web开发技术呢? Servlet是基于服务端的一种动态交互技术, HttpServletRequest表示客户端到服务端的对象 HttpServletResponse表示服务端到客户端的...

知止内明
04/18
0
0
Servlet的一些细节--学习笔记

Servlet细节 1)浏览器访问的url-pattern只是一个符合格式的任意字符串,以/开头 2)一个Servlet的url-pattern可以是1个或多个,有二种形式; a).xx b)/xx/ 注意:/不能一起直接使用 3)/和....

知止内明
04/17
0
0
Servlet生命周期与工作原理

Servlet生命周期分为三个阶段:   1,初始化阶段 调用init()方法   2,响应客户请求阶段  调用service()方法   3,终止阶段  调用destroy()方法 Servlet初始化阶段:   在下列时...

罗荣熙
2012/12/01
0
2
Tomcat如何与Servlet对象进行交互

Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上...

KeepMoving
2015/03/09
0
0
spring mvc 中如何访问到静态的文件,如jpg js css

如何你的DispatcherServlet拦截".do"这样的有后缀的URL,就不存在访问不到静态资源的问题。 如果你的DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对.js,.jpg等静...

随智阔
2014/03/11
0
0
访问WEB-INF目录中的JSP文件

方法1: 本来WEB-INF中的jsp就是无法通过地址栏访问的.所以安全.如果说你要访问这个文件夹中的jsp文件需要在项目的web.xml文件中去配置servlet格式差不多的配置就ok了。如下: [html] view p...

moz1q1
2015/03/31
0
0
JAVA编程导入Word文件到数据区域,实现多个word文件合并

在开发项目时,如何通过后台编程把多个Word文档合并到一起呢,这就需要借助PageOffice开发平台中的数据区域了。 具体实现步骤如下: 第一步:拷贝文件到WEB项目的“WEB-INF/lib”目录下。拷贝...

yert
2013/04/24
0
0
和的区别

<%@include%>和jsp:include的区别,发现了一些东西的。 <%@include%>:页面请求之前预编译,所有代码包含进来之后,一起进行处理,把所有代码合在一起,编译成一个servlet jsp:include:所有...

Alex_曰生
2015/04/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

实现异步有哪些方法

有哪些方法可以实现异步呢? 方式一:java 线程池 示例: @Test public final void test_ThreadPool() throws InterruptedException { ScheduledThreadPoolExecutor scheduledThre......

黄威
今天
0
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

六库科技
今天
0
0
牛客网刷题

1. 二维数组中的查找(难度:易) 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入...

大不了敲一辈子代码
今天
0
0
linux系统的任务计划、服务管理

linux任务计划cron 在linux下,有时候要在我们不在的时候执行一项命令,或启动一个脚本,可以使用任务计划cron功能。 任务计划要用crontab命令完成 选项: -u 指定某个用户,不加-u表示当前用...

黄昏残影
昨天
0
0
设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
昨天
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
昨天
1
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
昨天
1
0
Confluence 6 安装补丁类文件

Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中。这些问题将会使用 Class 类文件同时在官方 Jira bug...

honeymose
昨天
0
0
非常实用的IDEA插件之总结

1、Alibaba Java Coding Guidelines 经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的《阿里巴巴Java开发规约》扫描插件!该插件由阿里巴巴P3C项目组研发。P3C...

Gibbons
昨天
1
0
Tomcat介绍,安装jdk,安装tomcat,配置Tomcat监听80端口

Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 java程序写的网站用tomcat+jdk来运行...

TaoXu
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部