7.JavaEE开发入门(2) (我的JavaEE笔记)

六、在MyEclipse中建立servlet服务

我们可以直接建立servlet服务,首先新建一个web工程,然后在src中新建Servlet,然后选择覆写的方法,一般只需要选第一个和doGet、doPost方法。
ServletDemo3.java

package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class Servlet Demo3 extends HttpServlet {
         public void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                   response.getOutputStream().write("Hello Servlet!!!".getBytes());
         }
         public void doPost(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                   doGet(request, response);
         }
}

web.xml文件会自动生成



 
  
    ServletDemo3
    cn.itcast.servlet.ServletDemo3
  
 
  
    ServletDemo3
    /servlet/ServletDemo3
  
 
  day05
  
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  

这里需要注意几个使用MyEclipse的几个小细节:
当我们建立一个servlet类之后,会覆写一些方法,而如果发现自动生成的方法中的参数不是我们想要的,比如arg0、arg1之类的,这是我们需要导入源码。可以直接按住ctrl键然后将鼠标置于类上(如HttpServlet)左键,然后点击attach source,然后选择External Folder,选择源码路径:E:\apache\apache-tomcat-8.0.26-src,点击ok,如果还是不出现源码则重启MyEclipse。

*** 注意***:一定要注意web.xml中类名的写法:cn.itcast.servlet.ServletDemo1,同时GenericServlet是普通的servlet实现,我们一般使用HttpServlet这个父类。

注意:当我们改动web.xml(web应用程序的配置文件)后,服务器会自动重启,但是当我们改动java类之后需要手动重新部署发布。同时我们在MyEclipse中的一个web应用程序中要写一个静态页面(1.html)时,需要将这个文件放在WebRoot目录下。

七、Servlet的一些细节

细节一##

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

元素用于注册Servlet,它包含两个主要的子元素,,分别用于设置servlet的注册名称和servlet的完整名称。

一个元素用于映射一个已注册的servlet的一个对外访问路径,它包含两个子元素:,分别用于指定servlet的注册名称和servlet的对外访问路径。

细节二

同一个servlet可以被映射到多个url上,即多个元素的子元素的设置值可以是同一个servlet的注册名。

在servlet映射到url中也可以使用通配符,但是只能有两种固定的格式:一种格式是****.do,另一种是/****结尾。第一种情况是必须以.do 结尾,第二种情况若是/****则可以匹配任意地址字符串,若是/abc/****则必须以/abc/开头的任意字符串地址。

细节三

对于如下的一些映射关系:
Servlet1映射到/abc/****, Servlet2映射到/****,Servlet3映射到/abc,Servlet4映射到****.do问题:*
(1)当请求url为/abc/a.html/abc/****和/****都匹配,哪个servlet响应?
调用servlet1,这里是根据相似度来选择的。

(2)当请求url为/abc/abc/**** 和/abc*** 都匹配,哪个servlet响应?
调用servlet3,这里也是根据相似度来选择的。

(3)当请求url为/abc/a.do/abc/****和****.do都匹配,哪个servlet响应?
这里调用servlet1,这里是“/”的优先级比”.”要高。

(4)当请求url为/a.do/**** 和****.do都匹配,哪个servlet响应?
调用servlet2,这里是“/”的优先级比”.”要高。

(5)当请求url为/xxx/vvv/a.do/**** 和****.do 都匹配,哪个servlet响应?
调用servlet2,这里是“/”的优先级比”.”要高。

细节四

servlet是一个供其他java程序调用的java类,它不能独立运行,它的运行完全由servlet引擎来控制和调度。

针对客户端的多次servlet请求,通常情况下,服务器只会创建一个servlet实例对象,也就是说servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。

在servlet的整个声明周期,servlet的init方法只被调用一次。而对一个servlet的每次访问请求都导致servlet引擎被调用一次servlet的service方法。对于每次访问请求,service引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的servlet的service方法,service方法再根据请求方式分别调用doXXX方法。

细节五

如果在元素中配置了一个元素,那么web应用程序在启动时,就会装载并创建servlet的实例对象、以及调用servlet实例对象的init方法。如:


    ServletDemo3
    cn.itcast.servlet.ServletDemo3
    2
 

用途是为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。这在后面的框架中会用到。最好配置

详解元素:

1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

2)它的值必须是一个整数,表示servlet应该被载入的顺序

3)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

4)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

5)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

6)当值相同时,容器就会自己选择顺序来加载。

所以,x,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。

细节六

如果某个servlet的映射路径仅仅为一个正斜杠(/),那么这个servlet就称为当前web应用程序的缺省servlet。

凡是在web.xml文件中找不到匹配的元素的url,它们的访问请求都将交给缺省的servlet处理,也就是说,缺省servlet用于处理所有其他servlet都不处理的访问请求。

在tomcat的配置文件web.xml中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的servlet,并将这个servlet设置为缺省servlet。

当访问tomcat服务器中的某个静态html文件和图片时,实际上是在访问这个缺省的servlet。

细节七

当多个客户端并发访问同一个servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

如果某个servlet实现了SingleThreadModel接口,那么servlet引擎将以单线程模式来调用其service方法。其实这和我们使用同步(synchronized)的方式是一样的原理,但是这里注意: 子类不能抛出比父类更多的异常

SingleThreadModel接口中没有定义任何方法,只要在servlet类的定义中增加实现SingleThreadModel接口的声明即可。

对于实现了SingleThreadModel接口的servlet,servlet引擎仍然支持对该servlet的多线程并发访问,其采用的方式是产生多个servlet实例对象,并发的每个线程分别调用一个独立的servlet实例对象。

实现SingleThreadModel接口并不能真正解决servlet的线程安全问题,因为servlet引擎会创建多个servlet实例对象,而真正意义上解决多线程安全问题是指一个servlet实例对象被多个线程同时调用的问题。事实上,在ServletAPI2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。

你可能感兴趣的:(7.JavaEE开发入门(2) (我的JavaEE笔记))