servlet 基础原理 (映射方式、运行初始化参数)

简介

servlet 本身是一个 JAVA 程序(或者其他环境的程序),  通过 web.xml 文件把 请求资源页 反射成 JAVA对象到内存, 反射的对象需要实现 javax.servlet 里的 HttpServlet 接口


映射方式

web.xml 是关键
一个 <servlet> 对应一个 <servlet-mapping>, 关联唯一键值 <servlet-name>,  从而把 实现了 SERVLET接口的 JAVA类 映射到 URL的资源
这种映射在 JEE 5.0之后的版本变成默认的了, 不用配置, 可以没有这个文件
  <servlet>
	  <servlet-name>Hello</servlet-name>
	  <servlet-class>cn.it.HelloServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  		<servlet-name>Hello</servlet-name>
  		<url-pattern>/hello/1234</url-pattern>
  </servlet-mapping>

访问主机名/hello/1234 就能映射到 cn.it.HelloServlet,  前提该类要实现好 implements Servlet 接口

Servlet 接口

servlet 是一个通用的接口, 只是看起来象或者就是为 HTTP专门设计的, 带http打头的类 一般 继承至 GenericServlet, 并且用对应的 http参数类继承或者实现 servlet参数或者实现
比如  HttpServletRequest(tomcat中为RequestFacade实现) Ex ==> ServletRequest 这类形式
也就是 servlet 提供了一个应用层协议的交互方式的统一接口, 把一些 参数配置, 加载方式, 请求应答 等统一了;

public void init(ServletConfig config) throws ServletException

config 里面读好了 web.xml 里面的 init param
XML
  <servlet>
	  <servlet-name>Hello</servlet-name>
	  <servlet-class>cn.it.HelloServlet</servlet-class>
	  
	  <init-param>
	  	<param-name>WEB_NAME</param-name>
	  	<param-value>HELLO IT</param-value>	
	  </init-param>
	  
	  <init-param>
	  	<param-name>WEB_NAME2</param-name>
	  	<param-value>HELLO IT2</param-value>	
	  </init-param> 
	  
	  <init-param>
	  	<param-name>WEB_NAME3</param-name>
	  	<param-value>HELLO IT3</param-value>	
	  </init-param> 
  </servlet>
	public void init(ServletConfig config) throws ServletException {
		System.out.println("Init");
		
		System.out.println(config.getInitParameter("WEB_NAME")); // 输出: HELLO IT

		Enumeration<String> names = config.getInitParameterNames();
		
		while( names.hasMoreElements() )
		{
			String name = names.nextElement();
			System.out.println(name + ":" + config.getInitParameter(name)); // 遍历输出
																			// init
																			// PARAM
		}
首次使用某个 servlet 时, 可能init中出现较长时间的初始化动作, 用户体验不好, 通过添加配置 <servlet > 中的 <load-on-startup>节点, 让服务器开启时即完成 类的init操作, 改元素的值越小, 加载的顺序越靠前


public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

标准请求应答方式类型的协议通讯方式封装
具体实现为 org.apache.catalina.connector.RequestFacade ==> HttpServletRequest ==> ServletRequest


servlet 层次范围



转载下别人的笔记

喜羊羊同学 : http://blog.csdn.net/wandan_/article/details/17401883

一、Servlet生命周期

       servlet的生命周期:init(ServletConfig)、service(ServletRequest,ServletResponse)、destroy()

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class HelloWorldInit implements Servlet {  
  2.     public HelloWorldInit(){  
  3.         System.out.println("hello 默认构造");  
  4.     }  
  5.     public void init(ServletConfig config) throws ServletException {  
  6.         System.out.println("init");  
  7.     }  
  8.     public void service(ServletRequest request, ServletResponse response)  
  9.             throws ServletException, IOException {  
  10.         System.out.println("service");  
  11.     }  
  12.     public void destroy() {  
  13.         System.out.println("destroy");  
  14.     }  
  15.     public ServletConfig getServletConfig() {  
  16.         return null;  
  17.     }  
  18.     public String getServletInfo() {  
  19.         return null;  
  20.     }  
  21. }  

输出结果:

            

为什么会创建构造方法?

Tomcat服务器加载web.xml中的<servlet-class>com.test.HelloWorldInit</servlet>时,会根据这个类路径通过反射创建该类的实例。在服务器中操作大概过程如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Class clazz = Class.forName("com.test.HelloWorldInit");  
  2. Object obj = clazz.newInstance();//调用了构造方法  

然后通过反射获取该对象里的init和service方法并调用,调用时会传入相应的实参(ServletConfig、ServletRequest和ServletResponse)

二、init(ServletConfig config)和service(ServletRequest request, ServletResponse response)俩方法的参数解析 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void init(ServletConfig config) throws ServletException {  
  2.     System.out.println("config:"+config);  
  3. }  
  4. public void service(ServletRequest request, ServletResponse response)  
  5.         throws ServletException, IOException {  
  6.     System.out.println("request:"+request+"\n"+"response:"+response);  
  7. }  

输入结果:

           

上图输出的结果分别是ServletConfig、ServletRequest、ServletResponse的实现类,下图为源码中的实现

         

  (1)javax.servlet.ServletConfig(接口),该接口下有四个抽象方法

         

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void init(ServletConfig config) throws ServletException {  
  2.         //1、<servlet-name>返回这个里面的名称</servlet-name>  
  3.         System.out.println(config.getServletName());  
  4.         //2、返回指定初始化参数名称的值,如果参数不存在就返回Null(在web.xml中要配置初始化参数)  
  5.         System.out.println(config.getInitParameter("gf"));  
  6.           
  7.         //3、返回当前servlet的所有的初始化参数的名称,返回的是一个Enumeration(枚举)  
  8.         Enumeration<String> names = config.getInitParameterNames();  
  9.         while(names.hasMoreElements()){  
  10.             String name = names.nextElement();  
  11.             System.out.println(name + ":" + config.getInitParameter(name));  
  12.         }  
  13.         //4、ServletConfig保存了当前web项目的 ServletContext的引用  
  14.         ServletContext sc = config.getServletContext();  
  15.         System.out.println(sc);  
  16.         //实现类:org.apache.catalina.core.ApplicationContextFacade  
  17.     }  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <servlet>  
  2.     <servlet-name>helloWorldInit</servlet-name>  
  3.     <servlet-class>cn.test.HelloWorldInit</servlet-class>  
  4.     <!-- 配置初始化参数列表 -->  
  5.     <init-param>  
  6.         <!-- 初始化参数的名称 -->  
  7.         <param-name>gf</param-name>  
  8.         <!-- 初始化参数的值 -->  
  9.         <param-value>规范</param-value>  
  10.     </init-param>  
  11. </servlet>  

(2)javax.servlet.ServletRequest和javax.servlet.ServletResponse(service方法的两个参数)]

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.             /**第一个参数*/  
  2. //接口:javax.servlet.ServletRequest  
  3. //实现类:org.apache.catalina.connector.RequestFacade  
  4. /*  
  5.  * 关系:  
  6.  *   * public class RequestFacade implements HttpServletRequest {  
  7.  *   * public interface HttpServletRequest extends ServletRequest {  
  8.  *   
  9.  *   总结: RequestFacade --> HttpServletRequest  --> ServletRequest  
  10.  *   ************  
  11.  *   ServletRequest req = new RequestFacade();  
  12.  *   HttpServletRequest http = new RequestFacade();  
  13.  *   HttpServletRequest http2 = (HttpServletRequest)req;  
  14.  */  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**第二个参数*/  
  2.         //接口:javax.servlet.ServletResponse  
  3.         //实现类:org.apache.catalina.connector.ResponseFacade  
  4.           
  5.         /* 关系:  
  6.          *   * public class ResponseFacade implements HttpServletResponse {  
  7.          *   * public interface HttpServletResponse extends ServletResponse {  
  8.          *     
  9.          *   * 总结:ResponseFacade  --> HttpServletResponse  --> ServletResponse  
  10.          */  
  11.         HttpServletResponse response = (HttpServletResponse)resp;  

三、Servlet实现初始化工作

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class FirstServlet extends HttpServlet {  
  2.     //进行初始化,直接覆盖GenericServlet的init()方法  
  3.     @Override  
  4.     public void init() throws ServletException {  
  5.         //初始化工作  
  6.     }  
  7.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  8.             throws ServletException, IOException {  
  9.         this.doPost(request, response);  
  10.     }  
  11.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  12.             throws ServletException, IOException {  
  13.     }  
  14. }  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.  <servlet>  
  2.     <servlet-name>FirstServletxx</servlet-name>  
  3.     <servlet-class>cn.itcast.servlet.FirstServlet</servlet-class>  
  4.     <!-- 配置当前servlet在服务器启动时加载顺序  
  5.         取值:0-6 ,值越小,优先加载  
  6.      -->  
  7.     <load-on-startup>2</load-on-startup>  
  8. </servlet>  
  9. <servlet-mapping>  
  10.     <servlet-name>FirstServletxx</servlet-name>  
  11.     <url-pattern>/firstServlet</url-pattern>  
  12. </servlet-mapping>  

四、servlet的虚拟路径
      1) 只能使用 / 或 * 开头
      2) / 和 *. 不能同时存在
      3) / 或 /* 表示任意
      4) 只有*.才表示通配符

五、项目路径

     (1)getAbsolutePath( )  

              案例1:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     File file = new File("");  
  3.     System.out.println(file.getAbsolutePath());//absolute绝对的意思  
  4. }  

       输出结果:
                     

       用命令窗口执行:

                    JAVA项目的class文件是存放在项目根目录的bin目录下

                    

       案例2:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     File file = new File("/") ; //   '/'是相对路径,相对于当前盘符 可以获得当前盘符  
  3.     System.out.println(file.getAbsolutePath());  
  4. }  

        输出结果都为:F:\(命令运行和eclipse运行)
        总结:getAbsolutePath()使用java命令时输出的路径是当前Java命令停留的目录,使用eclipse运行时输出的路径是当前项目根目录的绝对路径

       注意:生成jar包后里面的没有src和bin目录的,生成jar包的过成是把bin目录下的文件全都拷贝过来,所以将配置文件放在src下其实就是在根目录下

    

     (2)类加载器获取路径

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     //类加载器  
  3.     //通过类 -> 获得字节码 -> 获得类加载器 -> 获得资源路径  
  4.     //路径指向class文件存放的目录  
  5.     URL url = Hello.class.getClassLoader().getResource("");  
  6. /       InputStream is = Hello.class.getClassLoader().getResourceAsStream(""); //跟getResource一样  
  7.     System.out.println(url);  
  8. }  

输出结果:file:/F:/myeclipse/Workspaces/TestProject/WebRoot/WEB-INF/classes/
注意:类加载器不能使用"/"

    (3)ServletContext获取路径

              ServletContext是对当前项目上下文的描述(对当前web项目所有内容的描述),tomcat为每一个web项目单独创建一个区域,用来管理整个项目。此区域称为ServletContext。

              context root是指当前项目的根目录:

                    * tomcat --> webapps/webName

                    * myeclipse --> webName/WebRoot 指向的是WebRoot目录

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void doGet(HttpServletRequest req, HttpServletResponse resp)  
  2.             throws ServletException, IOException {  
  3.         ServletContext sc2 = this.getServletConfig().getServletContext();  
  4.         ServletContext sc = this.getServletContext();  
  5.         //1 、  
  6.         String path = sc.getRealPath("/1.html");//获得实际路径,要求/开头  
  7.         System.out.println(path);//     F:\apache-tomcat-7.0.29\webapps\day06\1.html  
  8.         //2、获得资源文件  
  9.         URL url = sc.getResource("/1.html");   
  10.         System.out.println(url.getPath());//   /localhost/day06/1.html  
  11.         //3、  
  12.         InputStream is = sc.getResourceAsStream("/1.html");  
  13.         System.out.println(is);       
  14.     }  

输出结果:F:\apache-tomcat-7.0.29\webapps\day06\1.html

要求必须以'/'开头
(4)web的相对路径

    1、abc:与当前页面同级的目录或servlet的名称
     * <a href="c/c.html">c.html</a><br>
    2、/abc:相对于web站点,%tomcat%/webapps/
     * <a href="/day06_web/b/c/c.html">c.html</a><br>
    3、./abc:当前目录,与第一种情况相同
     * <a href="./c/c.html">c.html</a><br>
    4、../abc:上一次目录
     * <a href="../b/c/c.html">c.html</a><br>

 六、Servlet过滤器Filter

        所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:

            init( FilterConfig config);//Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml件中Servlet过滤器的初始化参数

           doFilter( ServletRequest req, ServletResponse resp ,FilterChain chain);//FilterChain参数用于访问后续过滤器

           destroy( );

         在web.xml中必须先配置过滤器再配置Servlet

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.io.IOException;  
  2. import java.io.PrintWriter;  
  3.   
  4. import javax.servlet.Filter;  
  5. import javax.servlet.FilterChain;  
  6. import javax.servlet.FilterConfig;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.ServletRequest;  
  9. import javax.servlet.ServletResponse;  
  10. import javax.servlet.http.HttpServletRequest;  
  11.   
  12. public class MyFilter implements Filter {  
  13.     private FilterConfig config = null;  
  14.   
  15.     private String blackList = null;  
  16.   
  17.     public void init(FilterConfig config) throws ServletException {  
  18.         this.config = config;  
  19.         blackList = config.getInitParameter("blacklist");  
  20.     }  
  21.   
  22.     public void destroy() {  
  23.         config = null;  
  24.     }  
  25.   
  26.     public void doFilter(ServletRequest request, ServletResponse response,  
  27.             FilterChain chain) throws IOException, ServletException {  
  28.   
  29.         String username = ((HttpServletRequest) request)  
  30.                 .getParameter("username");  
  31.         if (username != null)  
  32.             username = new String(username.getBytes("ISO-8859-1"), "GB2312");  
  33.         if (username != null && username.indexOf(blackList) != -1) {  
  34.             response.setContentType("text/html;charset=GB2312");  
  35.             PrintWriter out = response.getWriter();  
  36.             out.println("<html><head></head><body>");  
  37.             out.println("<h1>对不起," + username + ",你没有权限留言 </h1>");  
  38.             out.println("</body></html>");  
  39.             out.flush();  
  40.             return;  
  41.         }  
  42.   
  43.         long before = System.currentTimeMillis();  
  44.         config.getServletContext().log(  
  45.                 "NoteFilter:before call chain.doFilter()");  
  46.   
  47.         chain.doFilter(request, response);  
  48.   
  49.         config.getServletContext()  
  50.                 .log("NoteFilter:after call chain.doFilter()");  
  51.         long after = System.currentTimeMillis();  
  52.         String name = "";  
  53.         if (request instanceof HttpServletRequest) {  
  54.             name = ((HttpServletRequest) request).getRequestURI();  
  55.         }  
  56.         config.getServletContext().log(  
  57.                 "NoteFilter:" + name + ": " + (after - before) + "ms");  
  58.     }  
  59. }   
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <filter>  
  2.     <filter-name>myFilter</filter-name>  
  3.     <filter-class>com.test.filter.MyFilter</filter-class>  
  4.     <init-param>  
  5.         <param-name>blacklist</param-name>  
  6.         <param-value>hello</param-value>  
  7.     </init-param>  
  8. </filter>  
  9.   
  10. <filter-mapping>  
  11.     <filter-name>myFilter</filter-name>  
  12.     <url-pattern>/NoteServlet</url-pattern>  
  13. </filter-mapping>  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值