zoukankan      html  css  js  c++  java
  • 深入理解Servlet原理

    Servlet介绍:

    1. 如何返回一个网页:

     a. 静态网页

        >新闻页、百度百科

        >服务器保存一份HTML,直接返回给浏览器即可

     b. 动态网页

        >淘宝、QQ空间、微博

        >服务器保存一个组件,通过它动态拼一个HTML

        >在Java中这个组件就是Servlet

    2. Servlet特征:

      a. Servlet是服务器端组件,必须保存在服务器上。

      b. Servlet可以动态拼资源(HTML/IMG等),即处理HTTP协议。

      c. Servlet必须满足Sun的规范。

      d. Servlet是什么:Servlet是Sun推出的,用来在服务器端处理HTTP协议的组件。

    服务器:

    1. 名称:Java 服务器、Java Web 服务器、Servlet 容器;

    2. 本质:是一个软件,需要安装在硬件上才能用和浏览器是平级的关系;

    3. 举例:Tomcat(Apache)、JBOSS、WebLogic、WebSphere。

    Tomcat使用:

    1. 启动Tomcat:

       -Linux:打开/tomcat/bin,终端输入命令./startup.sh

       -Windows:打开/tomcat/bin,双击startup.bat

    2. 关闭Tomcat:

       -Linux:打开/tomcat/bin,终端输入命名./shutdown.sh

       -Windows:打开/tomcat/bin,双击shutdown.bat

    Servlet开发步骤:

    1.创建WEB项目

      >目录:webapp/WEB-INF/web.xml

    2.导入jar包

      >通过maven导入jar包,搜javaee

      >使用服务器自带的jar包,右键项目->target runtime->勾选tomcat

    3.创建Servlet

      >实现Servlet接口

      >也可以继承HttpSevlet,此类已实现了Servlet接口

      >实现/重写service(),在此方法内动态拼HTML

    4.注册Servlet

      >注册Servlet,并声明别名

      >通过别名,给此Servlet注册网名(以/开头)

    5.部署项目

      >在Servers下选择Tomcat,右键Add and Remove

      >在弹出框内左侧选中项目,双击移动到右侧

      >部署:就是拷贝

    6.访问Servlet

      >启动Tomcat

      >浏览器输入地址 http://ip:port/项目名/Servlet网名

    7.重新部署

      >修改代码后,需要重新部署并重启Tomcat才有效

      >点击Servers下面的Tomcat7,右键publish

      >可以手动关闭Tomcat,再启动它

      >也可以等待Eclipse自动重启Tomcat(Reloading...)

    Servlet执行原理:

    HTTP协议:

    1. 什么是HTTP协议:它规定了浏览器和服务器如何通信,以及通信时的数据格式。

    2. 如何通信:

      >建立连接

      >发送请求

      >接收响应

      >关闭连接

    3. 数据格式:

     a. 请求数据包

       >请求行:请求方式、Servlet网名、协议类型

       >消息头:数据的描述信息

       >实体内容:浏览器发送给服务器的数据

     b. 响应数据包

       >状态行:协议类型、状态码、状态

       >消息头:数据的描述信息

       >实体内容:服务器给浏览器发送的数据

    4. 对开发的要求

      -通信的方式已经由浏览器和服务器完成;

      -请求数据的打包由浏览器实现;

      -响应数据的打包由服务器实现;

      -开发需要提供浏览器发送给服务器的数据,以及服务器返回的数据;

      -服务器通过request对象接收请求数据;

      -服务器通过response对象向浏览器发送数据;

    注册案例:

    1. form的action属性要写上Servlet的访问路径(网名);

    2. 在表单空间上,使用name属性给该控件的数据命名,可以调用request的getParameter("name的指")来获取值;

    3. radio和checkbox需要设置value属性的值,就是要传递给服务器的具体的值;

    Servlet原理图:

    请求方式:

    1. 介绍:浏览器向服务器发送数据的方式;

    2. GET:

      >默认情况下所有的请求都是GET请求

      >采用路径传参,即通过路径携带参数

      >传参过程中参数可见,隐私性差

      >因为路径大小有限制,所以能够传递的参数很小

    3. POST:

      >method="post"

      >采用实体内容传参

      >在传参的过程中,路径上看不到参数,隐私性好

      >实体内容专门用于传递数据,因此大小不受限制

    4. 使用场景:

      >浏览器向服务器索取(查询)数据用GET请求

      >浏览器向服务器提交(保存)数据用POST请求

    解决乱码问题:

    重定向:

     1. 格式:res.sendRedirect("findEmp");//findEmp是网名

     2. 原理图如下:

    项目路径:

    URI和URL:

    1. 狭义(Java):

       - URI:绝对路径;

       - URL:完整路径;

       - URL包含了URI;

    2. 广义(Java/.net/php):

       - URI:资源的名称;

       - URL:资源的真名;

       - URI包含了URL;  

    Servlet路径的配置方式及用途:

    1. 精确匹配(/test):

        - 只有这唯一的路径可以可以访问此Servlet

        - 该Servlet只能处理一个请求 

    2. 通配符(/*):

        - 所有的路径都是可以访问此Servlet

        - 该Servlet可以处理所有请求

    3. 后缀匹配(*.test):

        - 所有以.test为后缀的路径都可以访问此Servlet

        - 该Servlet可以处理很多请求

    注:

      a. 必须先通过规范约定正确的路径;

      b. 按照规范判断路径,处理请求。对于不满足规范的路径,认为是用户输入的错误路径,统一报错;

    Servlet生命周期:

    1. 第1、2、4步只能执行一次,第3步可以执行多次;

    2. 因为Servlet被Tomcat自动创建一次,因此它在Tomcat内是单例的(只有1个实例),即Servlet满足单例模式;

    3. 默认情况下,首次访问Servlet时,Tomcat会创建它,也可以修改配置文件web.xml,使得Tomcat启动时就直接创建Servlet;

    4. 启动时创建Servlet,数字1代表创建的次序:<load-on-startup>1</load-on-startup>;

    ServletConfig和ServletContext:

    1. Context:上下文,理解为环境。环境可以给其内部的个体提供资源。从编程的角度来说可以给内部的对象提供数据;
    2. ServletConfig:它是Servlet的私有环境,可以为某一个Servlet提供数据;
    3. ServletContext:它是Servlet的公有环境,可以为所有Servlet提供数据;
    4. 使用ServletConfig和ServletContext给Servlet预置数据,不用写单独的配置文件,直接使用web.xml即可;另外这两个对象可以在初始化Servlet之前自动读取web.xml中的预置数据;
    5. Servlet特殊用法:
        - 可以使用此对象存取一些变量;
        - 即在程序运行阶段随时向此对象存取数据;
        - 获取对象:ServletContext ctx = getServletContext();
        - 取:ctx.getAttribute("user");
        - 存:ctx.setAttribute("user","admin");
     6. 通常在Tomcat启动时,都要调用某Servlet重写init(ServletConfig config)方法,专门用来在此阶段初始化项目所需要的一些变量。

    使用案例:

    1. ServletConfig案例:
      a. 配置文件web.xml 

    <servlet>

    <servlet-name>login</servlet-name>
    <servlet-class>web.LoginServlet</servlet-class>

    <!-- 给当前Servlet预置一个数据 -->

    <init-param>

    <param-name>maxOnline</param-name>

    <param-value>2000</param-value>

    </init-param>

    </servlet>

    <servlet-mapping>

    <servlet-name>login</servlet-name>

    <url-pattern>/login</url-pattern>

    </servlet-mapping>

      b. 在Servlet类中读取参数
     

    /**

    * 1.Tomcat在创建此Servlet后,会自动创建ServletConfig对象。

    * 2.Tomcat会调用此对象,读取web.xml中给当前Servlet所配置的参数。

    * 3.Tomcat会自动调用init方法,并传入已创建好的ServletConfig对象。

    * 归纳:调用init方法前,创建config并读取数据。在init及其后面的方法内可以使用config。

    */

    @Override

    public void init(ServletConfig config) throws ServletException {

    super.init(config);

    String mo = config.getInitParameter("maxOnline");

    System.out.println(mo);

    }

    @Override

    protected void service(

    HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    //从web.xml中读取参数

    ServletConfig cfg = getServletConfig();

    String mo = cfg.getInitParameter("maxOnline");

    System.out.println(mo);

    }

    2. ServletContext案例:

      a. 配置文件web.xml

     

    <!--

    给所有的Servlet预置一个数据。
    1.Tomcat启动时会自动创建ServletContext对象。

    2.Tomcat调用context读取此参数。

    由于这件事是在调用Servlet之前完成的,所以在service()中可以通过context读取参数。

    -->

    <context-param>

    <param-name>size</param-name>

    <param-value>10</param-value>

    </context-param>

    <servlet>

    <servlet-name>findDept</servlet-name>

    <servlet-class>web.FindDeptServlet</servlet-class>

    </servlet>

    <servlet-mapping>

    <servlet-name>findDept</servlet-name>

    <url-pattern>/findDept</url-pattern>

    </servlet-mapping>

      b. 在Servlet类中读取参数

     

    @Override

    protected void service(
    HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    //从web.xml中读取分页条件

    ServletContext ctx = getServletContext();

    String size = ctx.getInitParameter("size");

    //分页查询

    System.out.println(size);

    }

    线程安全:

    1. 成员变量:

        - 成员变量存于堆内;

        - 堆内数据只有一份;

        - 多线程共用一份数据;

        - 存在并发问题;

    2. 局部变量:

        - 成员变量存于栈内;

        - 栈内数据是多份;

        - 每个线程都有一份自己的数据;

        - 没有并发问题;

    3. 解决方案:

       - 不用成员;

       - 枷锁synchronized (this) {//TODO};

    HttpServlet:

    1. 自定义的类继承HttpServlet类,重写service方法,Tomcat将HttpServletRequest,HttpServletResponse传入此方法:

    public class TestServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    super.service(req, res);

    }

    //...

    }

    2. 调用父类,并将HttpServletRequest、HttpServletResponse两个参数传入:

    public class HttpServlet {

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res= (HttpServletResponse) response;
    this.service(req, res);
    }
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    String m = req.getMethod();
    if(m.equals("GET")) {
    doGet(req, res);
    }else if(m.equals("POST")) {
    doPost(req, res);
    }
    }
    private void doPost(HttpServletRequest req, HttpServletResponse res) {
    // TODO
    }
    private void doGet(HttpServletRequest req, HttpServletResponse res) {
    // TODO
    }
    //...
    }
    3. doGet()和doPost()默认的代码直接抛出了异常,为了强制开发者去重写他们。若要调用它们,就必须重写;

    4. service()内去掉super.service()的目的就是不掉用它们,从而避免异常;

  • 相关阅读:
    Elasticsearch5.3 学习(一):安装、Yii2.0 下载es扩展
    lnmp 环境require(): open_basedir restriction in effect 错误
    Ueditor编辑器图片上传到万象优图
    Linux curl 模拟form表单提交信息和文件
    CP936 转换成 UTF-8
    wamp 两个不同的php.ini
    PHP浮点数运算精度造成的,订单金额支付经常少1分的问题
    进制相关:存储与转换
    Python的数据类型
    pycharm+PyQt5 开发配置
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/10583886.html
Copyright © 2011-2022 走看看