Servlet使用总结专题

1:Servlet简介

Servlet是一种运行于服务器端的java应用程序。通过创建一个java类,然后实现servlet接口就可以生成一个servlet。
ServletAPI包括:

  • javax.servlet.* 主要包括所有servle实现的基本接口以及继承的基本类。
  • java.servlet.http.*包含了编写基于HTTP协议的servlet所需基类。

Servlet生命周期:

  • 初始阶段
    当客服端第一次发送某个servlet请求的时候,会调用这个servlet的init()方法进行初始化,这个servlet未被卸载之前只能初始化一次。

  • 服务阶段
    客服端每次发送servlet请求的时候,会调用service()方法给予响应,在service()方法中处理对应的业务逻辑。

  • 卸载阶段
    当servlet容器确认某个servlet不再提供服务的时候,会卸载这个servlet程序,释放对应的servlet资源,同时这个servlet的生命周期也随之结束。

2:Servlet运行过程

  1. 客服端发送一个servlet请求服务端,服务端会检查当前servlet是否已经装载并创建对象。

  2. 如果当前servlet对象已经存在,直接执行步骤4,否则执行步骤2, 当前Servlet实例化并生成一个对象

  3. 调用当前Servlet对象的init()方法

  4. 创建一个用于封装HTTP请求的对象HttpServletResquest与响应对象HttpServletResponse。并把这个两个对象传入service方法中。

  5. Servlet引擎卸载Servlet,在卸载之前调用destory()方法进行销毁。

3:Servlet线程安全问题

当多个客服端去访问服务端的Servlet的时候,服务端会为每个客服端都创建一个线程,这些线程都会去调用service方法,在这个service方法中可能会去访问同一个资源,因此就会发生线程安全问题。

public class ServletThreadDemo extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private int global_x=0; //定义一个全局变量


    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        int local_x = 0; //定义一个局部变量

        try {
            global_x++;
            local_x++;
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        /**
         * 通过在两个不同的浏览器分别访问这个Servlet,最终在控制台的输出为:
         * global_x:2  local_x:1
         * global_x:2  local_x:1
         * 通过控制台的输出可以得出:全局变量为一个共享的变量,局部变量为每个线程私有的变量。当多个线程同时访问同一个servlet的时候,全局变量会发生线程安全问题,局部变量不会发生线程安全问题
         * 当客户端请求servlet时,会去判断servlet容器中是否有当前servlet实例,如果没有就会根据web.xml的配置去实例化当前的servlet,否则就直接用servlet容器中存在的实例。
         * 因此该servlet为单例模式。每个线程都拥有自己的栈区,栈区是线程私有的,局部变量存放在栈区中,全局变量存放在方法区中,是所有线程共享的。
         * 
         */
        System.out.println("global_x:"+global_x+"  local_x:"+local_x);
    }

4:ServletConfig讲解

4.1:配置Servlet初始化参数

 <servlet>
    <servlet-name>ServletConfigDemo01</servlet-name>
    <servlet-class>com.lx.study.servlet.ServletConfigDemo01</servlet-class>
    <!-- 通过<init-param>标签为ServletConfigDemo01配置初始化参数 -->
    <init-param>
      <param-name>name</param-name>
      <param-value>liaoxue</param-value>
    </init-param>
    <init-param>
      <param-name>password</param-name>
      <param-value>123456</param-value>
    </init-param>
    <init-param>
      <param-name>charset</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </servlet>

4.2:通过ServletConfig获取配置的初始化参数

public class ServletConfigDemo01 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    //定义ServletConfig来接收当前Servlet配置的初始化参数
    private ServletConfig config;

    @Override
    public void init(ServletConfig config) throws ServletException{
        this.config=config;
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     * 当Servlet被实例化的时候,会通过init(ServletConfig config)方法把初始化参数封装到ServletConfig对象中
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        String paramVal=config.getInitParameter("name");
        response.getWriter().println(paramVal);

        Enumeration<String> params = config.getInitParameterNames();
       while(params.hasMoreElements()){
            String name=params.nextElement();
            String value=config.getInitParameter(name);
            response.getWriter().println("name="+name+" value="+value);
        }
    }

页面输出:

这里写图片描述

5:ServletContext对象讲解

Web容器在启动的时候,他会为每个web应用程序去创建一个ServletContext对象。在程序代码中可以通过ServletConfig对象获取ServletContext。ServletContext是当前web中所有servlet共享的一个对象,所以可以通过ServletContext对象实现不同servlet间的通信传递。

5.1: 多个Servlet通过ServletContext对象实现数据共享

存放共享数据:

public class ServletConfigDemo01 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * 通过ServletContext对象中存放当前web应用共享的数据
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        ServletContext sc =this.getServletConfig().getServletContext();

        String data="aaa";

        sc.setAttribute("data", data);
    }

在另外一个servlet中取出共享数据:

@WebServlet("/ServletConfigDemo02")
public class ServletConfigDemo02 extends HttpServlet {
    private static final long serialVersionUID = 1L;


    /**
     * 获取ServletContext对象中存放当前web应用共享的数据
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        ServletContext servletContext = this.getServletContext();
        String data=(String) servletContext.getAttribute("data");
        response.getWriter().write(data);
    }

先运行ServletConfigDemo01保存共享数据,后运行ServletConfigDemo02 取出共享数据,运行ServletConfigDemo02 后浏览器显示内容:
这里写图片描述
5.2:获取web应用的初始化参数
在web.xml文件中使用 标签配置web应用的初始化参数

 <context-param>
    <param-name>url</param-name>
    <param-value>jdbc://mysql://localhost:3306/test</param-value>
  </context-param>

在代码中获取web的初始化参数

/**
     * 获取web标签的初始化参数
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        ServletContext servletContext = this.getServletContext();
        //获取整个web站点的初始化参数
        String url=servletContext.getInitParameter("url");
        response.getWriter().print(url);

    }

效果展示:
这里写图片描述
5.2:通过ServletContext实现请求转发
ServletConfigDemo04:

/**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String data="<h1><font color='red'>abcdefg</font></h1>";
        response.getOutputStream().write(data.getBytes());
        ServletContext servletContext = this.getServletContext(); //获取ServletContext对象
        RequestDispatcher rd = servletContext.getRequestDispatcher("/ServletConfigDemo05"); //获取请求转发对象
        rd.forward(request, response); //请求转发

    }

ServletConfigDemo05:

/**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getOutputStream().write("servletDemo05".getBytes());
    }

运行ServletConfigDemo04后浏览器效果如下:
这里写图片描述
5.3:通过ServletContext读取资源文件
这里写图片描述
代码展示:


/**
 * Servlet implementation class ServletConfigDemo06
 */
@WebServlet("/ServletConfigDemo06")
public class ServletConfigDemo06 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private void readWebContentDirPropFIile(HttpServletResponse response) throws IOException {
        // TODO Auto-generated method stub
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); //db.properties的部署路径
        Properties pro=new Properties();
        pro.load(is);
        String driver=pro.getProperty("driver"); 
        String url=pro.getProperty("url");
        String username=pro.getProperty("username");
        String psw=pro.getProperty("password");
        response.getWriter().write(MessageFormat.format("driver={0},url={1},username={2},psw={3}",driver,url,username,psw));

    }


    /**
     * 使用ServletContext读取资源文件
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        response.setHeader("context-type", "text/html;charset=UTF-8"); //设置浏览器的编码格式
        readWebContentDirPropFIile(response); //读取maven目录结构中src/main/resources中db.properties文件资源
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

使用类装载器读取文件:

ClassLoader loader=XXX.class.getClassLoader(); (XXX表示工程中的某个类)
 InputStream in = loader.getResourceAsStream("资源部署相对路径");

对于大文件不能采用类装载器读取文件,否则会导致jvm内存溢出。大文件只能用ServletContext去读取。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值