zoukankan      html  css  js  c++  java
  • java攻城师之路--复习java web之servlet

    需要掌握的知识点:
    1、Servlet程序编写 ----- 生命周期
    2、ServletAPI Request Response
    3、Cookie 和 Session

    Servlet 用来 动态web资源 开发
    静态web资源 : 固定数据文件
    动态web资源 : 通过程序动态生成数据文件

    Servlet技术基于Request-Response编程模型 ---- HTTP协议也是基于请求响应 模型
    * Servlet技术 用来 开发基于HTTP web 应用程序

    接触 JavaEE API ------ 程序 接口 和 已经实现接口 类的 使用
    JavaEE ---- Java Platform, Enterprise Edition 缩写

    Servlet快速入门
    1、创建web project
    2、编写 class 继承 HttpServlet
    3、在web.xml 配置 Servlet程序 虚拟访问路径
    * 用户在浏览器上通过这个路径 访问编写Servlet程序
    4、覆盖doGet或者doPost方法 进行输出

    * Servlet 动态生成 网页文件

    执行过程
    1、用户在客户端发起url请求 : http://localhost/day05/hello ----- web.xml /hello 映射 HelloServlet程序
    2、用户提交请求时,get方式提交 执行 HelloServlet的 doGet方法 post方式提交 执行 HelloServlet的doPost 方法

    Servlet程序在编写和运行时,需要javaee 类库 (API支持)
    * 在学习javase List 需要 import java.util.List 需要 jre/lib/rt.jar
    * MyEclipse 自动导入 javaee5 liberary 存在 javaee.jar 提供 Servlet 需要类 API支持 (开发环境使Servlet程序正常编译)
    * Serlvet程序运行tomcat环境中 没有javaee.jar , 在 tomcat/lib/servlet-api.jar 提供Servlet程序运行需要 类API 支持 (运行环境需要的)

    手动编写Servlet运行
    1、在webapps 新建 day05test目录 --- 虚拟应用
    2、在day05test 新建 WEB-INF/classes
    3、将编写Servlet的java源码文件 放入 classes ,在 WEB-INF 配置web.xml
    4、编译Servlet的 java程序
    javac -classpath E:apache-tomcat-6.0.14libservlet-api.jar HelloServlet.java // 通过 -classpath 指定 Servlet需要jar 包
    生成Servlet package结构
    javac -d . -classpath E:apache-tomcat-6.0.14libservlet-api.jar HelloServlet.java

    Servlet运行原理分析
    编写Servlet程序没有 main函数 ---- tomcat调用Servlet程序执行

    通过myeclipse向导 创建Servlet ---- 创建Servlet程序,生成web.xml 配置
    * 生成Servlet信息非常复杂,想生成Servlet 内容整洁一些,精简一些 ------ 修改Servlet模板
    1、myeclipse工具 ---- 安装目录 common / plugins
    com.genuitec.eclipse.wizards_8.5.0.me201003052220.jar

    2、解压缩 templates/Servlet.java --- 这个就是Servlet模板

    通过API Servlet继承关系
    Servlet接口 ---- 实现类 : GenericServlet ------ 子类 HttpServlet ------ 编写Servlet 继承HttpServlet
    * 编写Servlet 间接 实现 Servlet 接口 (简化开发)
    Servlet接口 提出,为了解决基于请求-响应模型数据处理 (并没有涉及与HTTP协议相关 API)
    GenericServlet 实现接口 通用Servlet 也没有提供与 HTTP协议相关 API
    HttpServlet 引入与 协议相关 API

    Servlet生命周期
    init(ServletConfig config) 初始化
    service(ServletRequest req, ServletResponse res) 提供服务方法
    destroy() 销毁

    1、tomcat服务器启动时,没有创建Servlet对象
    2、第一次访问时,tomcat构造Servlet对象,调用 init,执行service
    3、从第二次以后访问 tomcat 不会从新创建Servlet对象,也不会调用init ---- 每一次访问都会调用service
    4、当服务器重启或正常关闭时 调用destroy (正常关闭 shutdown.bat)

    Servlet对象是tomcat创建的,每次请求调用Servlet中service方法,tomcat服务器会在每次调用Servlet的service方法时,为该方法创建Request对象和Response对象
    * 在 JavaEE API 中没有Request和Response实现类 ----- 实现类由Servlet服务器提供的,tomcat提供实现类 weblogic 提供实现类

    service方法 和 HttpServlet doGet/doPost 关系区别? ----- 必须阅读HttpServlet源代码
    在HttpServlet代码实现中,根据请求方式不同 调用相应doXXX方法 get方式请求 --- doGet post方式 --- doPost

    配置Servlet随tomcat服务器启动时 进行初始化 --- <load-on-startup >
    *<load-on-startup > 参数可以是一个数字 0-9 代表服务器加载优先级 0 最高
    例如:在tomcat启动时,想通过Servlet加载一些框架配置文件 配置随服务器启动 (struts1 )

    结论:
    1、编写Servlet 继承HttpServlet
    2、编写Servlet 不需要覆盖service方法,只需要覆盖doGet和doPost 方法

    Servlet初始化时覆盖init() ,无需覆盖init(config) ??
    * init(Config) 调用 init()

    当doGet和doPost代码逻辑相同时,可以相互调用,简化编程

    一个Servlet可以配置多个url-pattern
    URL 配置格式 三种:
    1、完全路径匹配 (以/开始 ) 例如:/hello /init
    * 当前工程没有被正确发布,访问该工程所有静态资源、动态资源 发生404 ----- 工程启动时出错了
    * 查看错误时 分析错误
    1) 单一错误 : 从上到下 查看第一行你自己写代码 (有的错误与代码无关,查看错误信息)
    2)复合错误 Caused by ---- 查看最后一个Caused by
    * Invalid <url-pattern> init2 in servlet mapping

    2、目录匹配 (以/开始) 例如:/* /abc/*
    / 代表网站根目录

    3、扩展名 (不能以/开始) 例如:*.do *.action
    典型错误 /*.do

    优先级:完全匹配>目录匹配 > 扩展名匹配

    路径问题:编写九九乘法表
    1、需要用户在客户端输入一个数字
    2、Servlet接收客户输入数字 打印对应乘法表

    在chengfabiao.html 通过 action 访问 ChengfabiaoServlet 路径可以用绝对路径和相对路径

    相对路径:相对当前网页地址 路径 例如 chengfabiao ./chengfabiao ../chengfabiao
    例如: http://localhost/day05/chengfabiao.html 提交 action="chengfabiao"
    * 将url最后地址换成相对路径
    结果: http://localhost/day05/chengfabiao ----- 服务器端 /chengfabiao

    例如: http://localhost/day05/aaa/chengfabiao.html 提交 action="chengfabiao"
    结果: http://localhost/day05/aaa/chengfabiao ----- 服务器 /chengfabiao
    * /aaa/chengfabiao 与服务器 /chengfabiao 不匹配 出现404

    http://localhost/day05/aaa/chengfabiao.html 提供 action="../chengfabiao"
    结果:http://localhost/day05/aaa/../chengfabiao ---- > ..和/aaa抵消 http://localhost/day05/chengfabiao 可以匹配服务器 /chengfabiao

    结论:如果用相对路径提交请求,考虑当前路径, 当前访问服务器资源路径不同 ---- 相对路径写法不同

    绝对路径 解决相对路径,会根据当前地址改变问题。 例如: /day05/chengfabiao 、http://localhost/day05/chengfabiao
    绝对路径 以/开始 /访问服务器根目录
    例如: 客户端访问服务器,不管当前路径是什么 --- / 服务器根目录 http://localhost
    /day05 --- 找到虚拟目录day05工程 /day05/chengfabiao --- 找到 day05工程下配置 虚拟路径/chengfabiao

    结论: 客户端路径 /工程虚拟目录/servlet虚拟路径 例如:/day05/chengfabiao
    服务器端 配置web.xml 不需要写工程虚拟目录 只要直接写/servlet虚拟路径 例如:/chengfabiao

    ----------------------------------------------------------------------------
    掌握Servlet程序编写
    通过路径 访问Servlet 程序
    * Servlet 生命周期

    init
    service
    destroy

    学习init方法 ---- init(ServletConfig) ---- 通过ServletConfig 获得Servlet初始化参数
    1、创建一个Servlet
    2、在web.xml 中 <servlet> 标签内 通过 <init-param> 标签 为Servlet配置初始化参数
    <init-param>
    <param-name>itcast</param-name>
    <param-value>传智播客</param-value>
    </init-param>

    3、在Servlet程序中通过ServletConfig对象 获得itcast对应数据
    getInitParameter ------ 通过name获得value
    getInitParameterNames ----- 获得所有name

    * 思考 :如何在doGet 或 doPost 方法中 获得 Servlet初始化参数
    将ServletConfig对象保存实例成员变量
    GenericServlet 已经将ServletConfig 保存成员变量 ----- 在子类中通过 getServletConfig方法 获得 初始化参数

    结论:子类Servlet不需要覆盖 init(ServletConfig) , 只需要通过GenericServlet中 getServletConfig() 获得ServletConfig对象

    应用:在init-param 指定配置文件位置和名称,配置Servlet随服务器启动创建 load-on-startup

    * ServletConfig 配置初始化数据,只能在配置Servlet获得,其它Servlet无法获得 ----- 每个Servlet程序都对应一个ServletConfig对象

    ServletContext 是Servlet上下文对象
    每一个工程 对会创建 单独ServletContext对象,这个对象代表当前web工程
    操作ServletContext 必须通过ServletConfig 获得对象

    应用:
    1、 获得整个web应用初始化参数
    2、 实现全局数据共享
    3、 实现服务器端转发功能
    4、 读取web工程资源文件

    1、获取WEB应用的初始化参数 和 ServletConfig 对象不同
    * ServletConfig对象配置参数,只对配置Servlet有效,如果配置参数,所有Servlet都可以访问 通过ServletContext
    <context-param>

     1     @Override
     2     public void init(ServletConfig config) throws ServletException {
     3         String name = config.getInitParameter("shellway");
     4         System.out.println(name);
     5         //Enumeration相当于Iterator 它是Iterator的前身
     6          Enumeration<String> names = config.getInitParameterNames();
     7          while (names.hasMoreElements()) {
     8             String name2 = (String) names.nextElement();
     9             System.out.println(name2+":"+config.getInitParameter(name2));
    10         }
    11     }
    ServletConfig对象配置参数的获取
    1     public void doGet(HttpServletRequest request, HttpServletResponse response)
    2             throws ServletException, IOException {
    3         System.out.println(getServletConfig().getInitParameter("shellway"));
    4         ServletContext sc = getServletContext();
    5         System.out.println(sc.getInitParameter("XXX"));
    6     }
    全局的配置参数,所有Servlet都可以访问,通过ServletContext获取

    2、通过ServletContext 在多个Servlet间 共享数据
    在ServletContext中 保存站点访问次数 ,每当一个用户访问站点,将访问次数+1
    在CountServlet 初始化过程中,向ServletContext 保存访问次数 ---- 0 --------------> ServletContext setAttribute

    每次访问次数 +1 --- 数据存放ServletContext中 ---- 所有Servlet都可以获得该数据

    * 在ServletContext中保存数据,所有Servlet都可以访问

     1 package com.shellway.servlet;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.ServletConfig;
     6 import javax.servlet.ServletContext;
     7 import javax.servlet.ServletException;
     8 import javax.servlet.http.HttpServlet;
     9 import javax.servlet.http.HttpServletRequest;
    10 import javax.servlet.http.HttpServletResponse;
    11 
    12 public class HelloServlet2 extends HttpServlet {
    13     @Override
    14     public void init() throws ServletException {
    15         ServletContext  sc = getServletContext();
    16         sc.setAttribute("times", 0);
    17         System.out.println("已经初始化。。。");
    18     }
    19 
    20     public void doGet(HttpServletRequest request, HttpServletResponse response)
    21             throws ServletException, IOException {
    22         ServletContext  sc = getServletContext();
    23         int time=(Integer)sc.getAttribute("times");
    24          time++;
    25          sc.setAttribute("times", time);
    26          System.out.println("被访问第:"+time+"次");
    27     }
    28 
    29     public void doPost(HttpServletRequest request, HttpServletResponse response)
    30             throws ServletException, IOException {
    31 
    32         doGet(request, response);
    33 
    34     }
    35 }
    统计网页访问次数:HelloServlet2
     1 package com.shellway.servlet;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 
     6 import javax.servlet.ServletContext;
     7 import javax.servlet.ServletException;
     8 import javax.servlet.http.HttpServlet;
     9 import javax.servlet.http.HttpServletRequest;
    10 import javax.servlet.http.HttpServletResponse;
    11 
    12 public class CountServlet extends HttpServlet {
    13 
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         ServletContext sc = getServletContext();
    17         int time=(Integer)sc.getAttribute("times");
    18          PrintWriter pw = response.getWriter();
    19          pw.write("this site has been visit "+time+" times");
    20 
    21     }
    22 
    23     public void doPost(HttpServletRequest request, HttpServletResponse response)
    24             throws ServletException, IOException {
    25 
    26         doGet(request, response);
    27 
    28     }
    29 }
    统计网页访问次数:CountServlet

    3、通过ServletContext 完成服务器程序转发
    什么是转发? 转发和重定向区别 ?
    getRequestDispatcher(java.lang.String path) ---- 完成转发

    使用转发还是重定向? ---- 转发性能好于重定向,请求次数好

    统计字母次数
    request.getParameter("content") 获得form 提交内容 content 就是 textarea name属性

     1 package com.shellway.servletcontext;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.RequestDispatcher;
     6 import javax.servlet.ServletContext;
     7 import javax.servlet.ServletException;
     8 import javax.servlet.http.HttpServlet;
     9 import javax.servlet.http.HttpServletRequest;
    10 import javax.servlet.http.HttpServletResponse;
    11 
    12 public class CountForA_Z extends HttpServlet {
    13 
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         //拿到请求数据
    17         String content = request.getParameter("content");
    18         //减少工作量,把内容都转为大写
    19         String upcontent = content.toUpperCase();
    20         //为26个字母创建数组,每个字母对应一个数组位置,每个数组位置存放统计该字母的数量
    21         int[] arr = new int[26];
    22         for (int i = 0; i < upcontent.length(); i++) {
    23             //charAt(int index)返回指定索引处的 char 值。索引范围为从 0 到 length()-1
    24             char c = upcontent.charAt(i);
    25             //isLetter()确定指定字符是否为字母。
    26             if (Character.isLetter(c)) {  //等价于c>='A'&&c<='Z'
    27                 arr[c-'A']++;
    28             }
    29         }
    30          ServletContext context = getServletContext();
    31          context.setAttribute("arr", arr);
    32          RequestDispatcher rd =context.getRequestDispatcher("/servlet/result");
    33          rd.forward(request, response);
    34     }
    35 
    36     public void doPost(HttpServletRequest request, HttpServletResponse response)
    37             throws ServletException, IOException {
    38 
    39         doGet(request, response);
    40 
    41     }
    42 }
    统计字母次数:CountForA_Z
     1 package com.shellway.servletcontext;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 
     6 import javax.servlet.ServletContext;
     7 import javax.servlet.ServletException;
     8 import javax.servlet.http.HttpServlet;
     9 import javax.servlet.http.HttpServletRequest;
    10 import javax.servlet.http.HttpServletResponse;
    11 
    12 public class CountForResult extends HttpServlet {
    13 
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         ServletContext sc = getServletContext();
    17         int []arr1 = (int[])sc.getAttribute("arr");
    18         char c = 0 ;
    19         response.setContentType("text/html;charset=utf-8");
    20         PrintWriter pw =response.getWriter();
    21         for (int i = 0; i < arr1.length; i++) {
    22             c = (char) (i+'A');
    23             pw.write(c+"出现的次数为: "+arr1[i]+" 次"+"<br/>");
    24         }
    25     }
    26 
    27     public void doPost(HttpServletRequest request, HttpServletResponse response)
    28             throws ServletException, IOException {
    29 
    30         doGet(request, response);
    31 
    32     }
    33 }
    统计字母次数:CountForResult

    4、利用ServletContext对象读取资源文件

    使用java application 读取文件,读取当前工程下所有文件 ----- 使用相对路径读取文件
    使用Servlet读取文件 只能读取WebRoot下所有文件 ---- 必须使用绝对磁盘路径读取文件

    通过站点根目录绝对路径 获得磁盘绝对路径 ------ getServletContext().getRealPath(“/WEB-INF/info.txt”)

    * 因为 WEB-INF/classes 非常特殊 (存放.class文件目录),被类加载器加载,通过Class类对象读取 该目录下文件
    String filename3 = c.getResource("/a1.txt").getFile(); ----- / 代表 /WEB-INF/classes

    结论:在web工程中,必须将 文件路径转换绝对磁盘路径 c:xxx e:xxxxxx ----- getServletContext().getRealPath("/xxx"); /代表WebRoot
    如果读取文件 恰好位于 WEB-INF/classes ----- 通过 类名.class.getResource("/文件名").getFile(); 获得绝对磁盘路径 / 代表 /WEB-INF/classes

     1 package com.shellway.io;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.FileNotFoundException;
     5 import java.io.FileReader;
     6 import java.io.IOException;
     7 
     8 public class ReadFile {
     9     public static void main(String[] args) throws Exception {
    10         String fileName = "src/a1.txt";
    11         readfile(fileName);
    12         
    13         String fileName2 = "WebRoot/a2.txt";
    14         readfile(fileName2);
    15         
    16         String fileName3 = "a3.txt";
    17         readfile(fileName3);
    18     }
    19 
    20     private static void readfile(String fileName) throws FileNotFoundException,
    21             IOException {
    22         BufferedReader in = new BufferedReader(new FileReader(fileName));
    23         String len;
    24         while ((len = in.readLine())!=null) {
    25             System.out.println(len);
    26         }
    27     }
    28 }
    使用java application 读取上图中文件a1,a2,a3
     1 package com.shellway.io;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.FileNotFoundException;
     5 import java.io.FileReader;
     6 import java.io.IOException;
     7 
     8 import javax.servlet.ServletException;
     9 import javax.servlet.http.HttpServlet;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletResponse;
    12 
    13 public class ReadFileServlet extends HttpServlet {
    14 
    15     public void doGet(HttpServletRequest request, HttpServletResponse response)
    16             throws ServletException, IOException {
    17         String fileName = "/a2.txt";//这里的/代表网站的根目录
    18         String s = getServletContext().getRealPath(fileName);
    19         //返回: D:apache-tomcat-6.0.14webappsday03a2.txt
    20         System.out.println(s);
    21         readfile(s);
    22 
    23         String fileName2 = "/a1.txt";//这里的/代表classpath根路径,即: /WEB-INF/classes
    24         String s2 = ReadFileServlet.class.getResource(fileName2).getFile();
    25         //返回: /D:/apache-tomcat-6.0.14/webapps/day03/WEB-INF/classes/a1.txt
    26         System.out.println(s2);//
    27         readfile(s2);
    28     }
    29 
    30     private static void readfile(String fileName) throws FileNotFoundException,
    31             IOException {
    32         BufferedReader in = new BufferedReader(new FileReader(fileName));
    33         String len;
    34         while ((len = in.readLine()) != null) {
    35             System.out.println(len);
    36         }
    37     }
    38 
    39     public void doPost(HttpServletRequest request, HttpServletResponse response)
    40             throws ServletException, IOException {
    41 
    42         doGet(request, response);
    43 
    44     }
    45 }
    使用Servlet读取文件 只能读取WebRoot下所有文件。只能读取/WEB-INF下的a2和类路径下的a1,而a3读取不了


    缺省Servlet 功能:处理其他Servlet都不处理请求
    tomcat/conf/web.xml org.apache.catalina.servlets.DefaultServlet 作为缺省Servlet

    总结:
    1、编写Servlet HelloServlet
    2、修改Servlet模板
    3、Servlet生命周期 理论重点掌握
    4、Servlet url三种写法 完全、目录、扩展名
    5、路径问题:绝对路径 ----- 案例 九九乘法表
    将web.xml 配置路径复制到网页 在路径前 /工程名
    6、ServletConfig 和ServletContext 读取初始化参数区别 ?
    7、ServletContext数据共享案例 ----- 统计访问次数
    8、ServletContext转发案例 --- 统计字母出现次数
    9、读取web工程中资源文件 ---- 绝对路径
    在web工程中,必须将 文件路径转换绝对磁盘路径 c:xxx e:xxxxxx ----- getServletContext().getRealPath("/xxx"); /代表WebRoot
    如果读取文件 恰好位于 WEB-INF/classes ----- 通过 类名.class.getResource("/文件名").getFile(); 获得绝对磁盘路径 / 代表 /WEB-INF/classes
    10、缺省Servlet 了解功能将静态资源数据内容读取写给客户端

     

  • 相关阅读:
    面试题3(百思教育面试软件开发岗位笔试题)
    python开发工具安装
    涉及 委托事件 程序运行越来越慢
    整理收藏
    数据库作业创建
    剑指offer-面试题37:序列化二叉树及二叉树的基本操作和测试
    剑指offer-面试题41:数据流中的中位数
    快速排序及其优化
    冒泡排序算法及相应的优化
    leetcode问题:缺失数字
  • 原文地址:https://www.cnblogs.com/shellway/p/3992680.html
Copyright © 2011-2022 走看看