zoukankan      html  css  js  c++  java
  • Servlet学习

    编写Servlet应该注意的一些细节:

    1: 

    由于客户端是通过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的对外访问路径。例如:
    <web-app>
    	<servlet>
    		<servlet-name>AnyName</servlet-name>
    		<servlet-class>HelloServlet</servlet-class>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>AnyName</servlet-name>
    		<url-pattern>/demo/hello.html</url-pattern>
    	</servlet-mapping>
    </web-app>
    

      

    如果我们使用MyEclipse开发的话,当我们创建完Servlet之后,它会自动帮我们在web.xml中添加好配置。 注意: 如果我们修改了Servlet的名字的话,MyEclipse是不会自动帮我们修改web.xml中的配置的,所以我们必须自己修改web.xml中的配置。

    2:

    一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。
    在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
    <servlet-mapping>                              
    	<servlet-name>
    		AnyName
    	</servlet-name>
    	<url-pattern>
    		*.do
    	</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    	<servlet-name>
    		AnyName
    	</servlet-name>
    	<url-pattern>
    		/action/*
    	</url-pattern>
    </servlet-mapping>
    

    3:

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

    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

    谁最像匹配谁,*.do的优先率最低

    4:

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

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

    Servlet的整个生命周期内,Servletinit方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servletservice方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servletservice()方法,service方法再根据请求方式分别调用doXXX方法
     
    5:
    如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。

      举例:

      <servlet>

      <servlet-name>invoker</servlet-name>

      <servlet-class>

      org.apache.catalina.servlets.InvokerServlet

      </servlet-class>

      <load-on-startup>2</load-on-startup>

      </servlet>

    用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据
     
    6:
    如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
    凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
    在<tomcat的安装目录>confweb.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。
    当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。
    如果我们自己定义缺省的servlet的话,会覆盖该servlet所以最好不要自己定义缺省的servlet
     
    7:
    当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servletservice方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
    如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。
    SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。 
    对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。
    实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。  
     
    ServletConfig对象 :
    Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
    servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servletinit方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
     
    ServletContext对象:
    WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
    ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
    由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域象。
     
     
    读取每个Servlet共享的资源配置的时候,我们可以通过ServletContext 获得
    二对于普通的Java的程序读取资源的话,我们可以通过以下两种方式:
    1:
    //上面代码类装载器只装载一次, 读取不到文件的更新
    InputStream in=UserDao.class.getClassLoader().getResourceAsStream("db.properties");
    dbconfig.load(in);
    2:
    //用类装载方式得到文件位置, 可以读到文件的更新

    URL url=UserDao.class.getClassLoader().getResource("db.properties");
    String str=url.getPath();

    InputStream in2=new FileInputStream(str);

    dbconfig.load(in2);

     
     
  • 相关阅读:
    Ubuntu 14.04 卸载通过源码安装的库
    Ubuntu 14.04 indigo 相关依赖
    Ubuntu 14.04 indigo 安装 cartographer 1.0.0
    Ubuntu 14.04 改变文件或者文件夹的拥有者
    安装cartographer遇到Unrecognized syntax identifier "proto3". This parser only recognizes "proto2"问题
    Unrecognized syntax identifier "proto3". This parser only recognizes "proto2". ”问题解决方法
    查看所有用户组,用户名
    1卸载ROS
    Ubuntu14.04 软件安装卸载
    Ubuntu14.04系统显示器不自动休眠修改
  • 原文地址:https://www.cnblogs.com/E-star/p/3500451.html
Copyright © 2011-2022 走看看