zoukankan      html  css  js  c++  java
  • 【Web入门系列】初探Servlet

    1、Servlet开发过程及执行过程

    2、Servlet路径映射

    3、缺省Servlet 

    4、Servlet生命周期

    5、Servlet自动加载 

    6、Servlet线程安全 


    Servlet开发过程及执行过程

    1、编写java类,继承HttpServlet 2、重写doGetdoPost方法 3、Servlet程序交给tomcat服务器运行 4、web.xml文件中进行配置

    <!-- 配置一个servlet -->
    <!-- servlet的配置 -->
    <servlet>
        <!-- servlet的内部名称,自定义,尽量有意义 -->
        <servlet-name>FirstServlet</servlet-name>
        <!-- servlet的类全名: 包名 + 简单类名 -->
        <servlet-class>ysdrzp.servlet.FirstServlet</servlet-class>
    </servlet>
    
    <!-- servlet的映射配置 -->
    <servlet-mapping>
        <!-- servlet的内部名称,一定要和上面的内部名称保持一致 -->
        <servlet-name>FirstServlet</servlet-name>
        <!-- servlet的映射路径(访问servlet的名称) -->
        <url-pattern>/first</url-pattern>
    </servlet-mapping>
    public class FirstServlet extends HttpServlet {
    
        /**
         *
         * @param request
         * @param response
         * @throws ServletException
         * @throws IOException
         */
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().write("this is first servlet");
        }
    
        /**
         *
         * @param request
         * @param response
         * @throws ServletException
         * @throws IOException
         */
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            doGet(request,response);
        }
        
    }

    访问http://localhost:8080/myweb/first是如何找到FirstServlet的?

    首先tomcat服务器启动时会加载webapps中的每个web应用的web.xml配置文件。

    http://指定http协议,localhost会到本地的hosts文件中查找是否存在该域名对应的IP地址127.0.0.1,根据8080端口找到tomcat服务器,

    /myweb会在tomcat的webapps目录下找myweb的目录,/first 匹配资源名称。

    1)在myweb的web.xml中查找是否有匹配的url-pattern的内容(/first)

    2)如果找到匹配的url-pattern,则使用当前servlet-name的名称到web.xml文件中查询是否相同名称的servlet配置

    3)如果找到,则取出对应的servlet配置信息中的servlet-class内容:ysdrzp.servlet.FirstServlet

    4)通过反射:构造FirstServlet的对象,然后调用FirstServlet里面的方法

    Servlet路径映射

    精确映射

    /first                  http://localhost:8080/myweb/first

    /xxx/firstServlet        http://localhost:8080/myweb/xxx/firstServlet

    模糊匹配

    /*                       http://localhost:8080/myweb/任意路径

    /test/*                  http://localhost:8080/myweb/test/任意路径

    *.后缀名                 http://localhost:8080/myweb/任意路径.do   如:*.do      *.action        *.html(伪静态)

    假如将上面的配置文件,映射信息调整一下由<url-pattern>/first</url-pattern>改为<url-pattern>/*</url-pattern>

    在浏览器地址栏中输入http://localhost:8080/myweb/xxxx(任意的请求映射路径/xxxx)一样可以请求到FirstServlet。

    注意:

    1)url-pattern(请求servlet的映射路径)要么以 / 开头,要么以*开头

    2)不能同时使用两种模糊匹配,例如 /test/*.do是非法路径

    3)当有输入的URL有多个servlet同时被匹配的情况下:3.1 精确匹配优优先,长的最像优先被匹配 3.2 以后缀名结尾的模糊url-pattern优先级最低

    缺省Servlet路径

    Servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。

    URL输入http://localhost:8080/myweb/index.html 是如何读取文件?

    1)到当前myweb应用下的web.xml文件查找是否有匹配的url-pattern。

    2)如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理

    3)DefaultServlet程序到myweb应用的根目录下查找是存在一个名称为index.html的静态文件。

    4)如果找到该文件,则读取该文件内容,返回给浏览器。

    5)如果找不到该文件,则返回404错误页面。

    结论: 先找动态资源,再找静态资源。

    Servlet生命周期

    Servlet的生命周期是由tomcat服务器控制的。

    构造方法:创建servlet对象的时候调用。默认情况下,第一次访问Servlet的时候创建Servlet对象只调用1次,这也可以说明Servlet对象在tomcat是单实例的。

    init方法:创建完servlet对象的时候调用,只调用1次。

    service方法:每次发出请求时调用,会被调用n次。

    destroy方法:销毁Servlet对象的时候调用,停止服务器或者重新部署web应用时销毁servlet对象,只调用1次。

    public class FirstServlet extends HttpServlet {

    public FirstServlet(){
    System.out.println("FirstServlet对象构造完成");
    }

    @Override
    public void init(ServletConfig servletConfig){
    System.out.println("init()方法被调用");
    }


    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("service()方法被调用");
    doGet(request,response);
    }

    @Override
    public void destroy(){
    System.out.println("destroy()方法被调用");
    }

    /**
    *
    * @param request
    * @param response
    * @throws ServletException
    * @throws IOException
    */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.getWriter().write("this is first servlet");
    }

    /**
    *
    * @param request
    * @param response
    * @throws ServletException
    * @throws IOException
    */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    doGet(request,response);
    }


    Servlet自动加载

    默认情况下,第一次访问Servlet的时候创建Servlet对象。如果Servlet的构造方法或init方法中执行了比较多的逻辑代码,这样会导致用户第一次访问sevrlet的时候比较慢。

    在Servlet的配置信息中,加上一个<load-on-startup>配置信息,这样就可改变servlet创建对象的时机,提前到加载web应用的时候。

    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>ysdrzp.servlet.FirstServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
        <url-pattern>/first</url-pattern>
    </servlet-mapping>

    有参init方法和无参init方法

    /**
     *  有参数的init和无参的init方法
     */
    public class InitServlet extends HttpServlet {
    
        /**
         * 有参数的init方法
         * 该方法是Servlet的生命周期方法,一定会被tomcat服务器调用
         * 注意:如果要编写初始代码,不需要覆盖有参数的init方法
         */
        /*@Override
        public void init(ServletConfig config) throws ServletException {
            System.out.println("有参数的init方法被调用");
        }*/
    
        /**
         * 无参数的init方法
         * 该方法是Servlet的编写初始化代码的方法,是设计出来专门给开发者进行覆盖,然后在里面编写Servlet的初始逻辑代码的方法。
         */
        @Override
        public void init() throws ServletException {
            System.out.println("无参数的init方法被调用");
        }
    
    }

    Servlet线程安全

    Servlet对象在tomcat服务器是单实例多线程的。正因为Servlet是多线程的,所以当多个Servlet的线程同时访问了Servlet的共享数据,如成员变量,可能会引发线程安全问题。

    解决办法:

    1)把使用到共享数据的代码块进行同步(使用synchronized关键字)

    2)建议在Servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步,而且尽量缩小同步代码块的范围,避免因为同步而导致并发效率降低。

    public class ThreadServlet extends HttpServlet {
    
        int count = 1;
    
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            synchronized (ThreadServlet.class) {
                response.getWriter().write("你是第"+count+"位仿客。");
                /*try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                count++;
            }
        }
    }
  • 相关阅读:
    JAVA线程池管理及分布式HADOOP调度框架搭建
    技术人员如何创业《二》 合伙人的模式
    JavaScript中的运动数学函数(持续更新)
    JavaScript中的加号
    JavaScript 函数绑定 Function.prototype.bind
    基于C#的波形显示控件的实现[附完整源码下载]
    JavaScript中的声明提升
    JavaScript & HTML5 Canvas 概览 更新时间201404111805
    《编写高质量代码——Web前端开发修炼之道》读后随笔
    B树/B+树/二叉搜索树/AVL树/红黑树
  • 原文地址:https://www.cnblogs.com/ysdrzp/p/9864554.html
Copyright © 2011-2022 走看看