1. 首页
  2. JavaWeb学习总结

javaweb学习总结(六)——Servlet开发(二)

一、ServletConfig讲解

1.1、配置Servlet初始化参数

  在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。

例如:

   1 <servlet>
     2     <servlet-name>ServletConfigDemo1</servlet-name>
     3     <servlet-class>gacl.servlet.study.ServletConfigDemo1</servlet-class>
     4     <!--配置ServletConfigDemo1的初始化参数 -->
     5     <init-param>
     6         <param-name>name</param-name>
     7         <param-value>gacl</param-value>
     8     </init-param>
     9      <init-param>
    10         <param-name>password</param-name>
    11         <param-value>123</param-value>
    12     </init-param>
    13     <init-param>
    14         <param-name>charset</param-name>
    15         <param-value>UTF-8</param-value>
    16     </init-param>
    17 </servlet>

1.2、通过ServletConfig获取Servlet的初始化参数

  当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

例如:

   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import java.util.Enumeration;
     5 import javax.servlet.ServletConfig;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 public class ServletConfigDemo1 extends HttpServlet {
    12 
    13     /**
    14      * 定义ServletConfig对象来接收配置的初始化参数
    15      */
    16     private ServletConfig config;
    17     
    18     /**
    19      * 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,
    20      * 会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,
    21      * 将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以
    22      * 得到当前servlet的初始化参数信息。
    23      */
    24     @Override
    25     public void init(ServletConfig config) throws ServletException {
    26         this.config = config;
    27     }
    28 
    29     public void doGet(HttpServletRequest request, HttpServletResponse response)
    30             throws ServletException, IOException {
    31         //获取在web.xml中配置的初始化参数
    32         String paramVal = this.config.getInitParameter("name");//获取指定的初始化参数
    33         response.getWriter().print(paramVal);
    34         
    35         response.getWriter().print("<hr/>");
    36         //获取所有的初始化参数
    37         Enumeration<String> e = config.getInitParameterNames();
    38         while(e.hasMoreElements()){
    39             String name = e.nextElement();
    40             String value = config.getInitParameter(name);
    41             response.getWriter().print(name + "=" + value + "<br/>");
    42         }
    43     }
    44 
    45     public void doPost(HttpServletRequest request, HttpServletResponse response)
    46             throws ServletException, IOException {
    47         this.doGet(request, response);
    48     }
    49 
    50 }

运行结果如下:

  izongjieliuservletkaifaer_1.png

二、ServletContext对象

  WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
  ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
  由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

三、ServletContext的应用

  3.1、多个Servlet通过ServletContext对象实现数据共享

  范例:ServletContextDemo1和ServletContextDemo2通过ServletContext对象实现数据共享

   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletContext;
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 public class ServletContextDemo1 extends HttpServlet {
    11 
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14         String data = "xdp_gacl";
    15         /**
    16          * ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,
    17          * 可以通过ServletConfig.getServletContext方法获得ServletContext对象。
    18          */
    19         ServletContext context = this.getServletConfig().getServletContext();//获得ServletContext对象
    20         context.setAttribute("data", data);  //将data存储到ServletContext对象中
    21     }
    22 
    23     public void doPost(HttpServletRequest request, HttpServletResponse response)
    24             throws ServletException, IOException {
    25         doGet(request, response);
    26     }
    27 }
   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletContext;
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 public class ServletContextDemo2 extends HttpServlet {
    11 
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14         ServletContext context = this.getServletContext();
    15         String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据
    16         response.getWriter().print("data="+data);
    17     }
    18 
    19     public void doPost(HttpServletRequest request, HttpServletResponse response)
    20             throws ServletException, IOException {
    21         doGet(request, response);
    22     }
    23 }

  先运行ServletContextDemo1,将数据data存储到ServletContext对象中,然后运行ServletContextDemo2就可以从ServletContext对象中取出数据了,这样就实现了数据共享,如下图所示:

  izongjieliuservletkaifaer_2.png

  3.2、获取WEB应用的初始化参数

  在web.xml文件中使用<context-param>标签配置WEB应用的初始化参数,如下所示:

   1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     3     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
     4     <display-name></display-name>
     5     <!-- 配置WEB应用的初始化参数 -->
     6     <context-param>
     7         <param-name>url</param-name>
     8         <param-value>jdbc:mysql://localhost:3306/test</param-value>
     9     </context-param>
    10 
    11     <welcome-file-list>
    12         <welcome-file>index.jsp</welcome-file>
    13     </welcome-file-list>
    14 </web-app>

  获取Web应用的初始化参数,代码如下:

   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletContext;
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 
    11 public class ServletContextDemo3 extends HttpServlet {
    12 
    13     public void doGet(HttpServletRequest request, HttpServletResponse response)
    14             throws ServletException, IOException {
    15 
    16         ServletContext context = this.getServletContext();
    17         //获取整个web站点的初始化参数
    18         String contextInitParam = context.getInitParameter("url");
    19         response.getWriter().print(contextInitParam);
    20     }
    21 
    22     public void doPost(HttpServletRequest request, HttpServletResponse response)
    23             throws ServletException, IOException {
    24         doGet(request, response);
    25     }
    26 
    27 }

运行结果:

  izongjieliuservletkaifaer_3.png

  3.3、用servletContext实现请求转发

  ServletContextDemo4
   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     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 ServletContextDemo4 extends HttpServlet {
    13 
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         String data = "<h1><font color='red'>abcdefghjkl</font></h1>";
    17         response.getOutputStream().write(data.getBytes());
    18         ServletContext context = this.getServletContext();//获取ServletContext对象
    19         RequestDispatcher rd = context.getRequestDispatcher("/servlet/ServletContextDemo5");//获取请求转发对象(RequestDispatcher)
    20         rd.forward(request, response);//调用forward方法实现请求转发
    21     }
    22 
    23     public void doPost(HttpServletRequest request, HttpServletResponse response)
    24             throws ServletException, IOException {
    25     }
    26 }
  ServletContextDemo5

   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class ServletContextDemo5 extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12             throws ServletException, IOException {
    13         response.getOutputStream().write("servletDemo5".getBytes());
    14     }
    15 
    16     public void doPost(HttpServletRequest request, HttpServletResponse response)
    17             throws ServletException, IOException {
    18         this.doGet(request, response);
    19     }
    20 
    21 }

  运行结果:

  izongjieliuservletkaifaer_4.png

  访问的是ServletContextDemo4,浏览器显示的却是ServletContextDemo5的内容,这就是使用ServletContext实现了请求转发

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

  项目目录结构如下:

  izongjieliuservletkaifaer_5.png

代码范例:使用servletContext读取资源文件

    1 package gacl.servlet.study;
      2 
      3 import java.io.FileInputStream;
      4 import java.io.FileNotFoundException;
      5 import java.io.IOException;
      6 import java.io.InputStream;
      7 import java.text.MessageFormat;
      8 import java.util.Properties;
      9 import javax.servlet.ServletException;
     10 import javax.servlet.http.HttpServlet;
     11 import javax.servlet.http.HttpServletRequest;
     12 import javax.servlet.http.HttpServletResponse;
     13 
     14 /**
     15  * 使用servletContext读取资源文件
     16  * 
     17  * @author gacl
     18  * 
     19  */
     20 public class ServletContextDemo6 extends HttpServlet {
     21 
     22     public void doGet(HttpServletRequest request, HttpServletResponse response)
     23             throws ServletException, IOException { 
     24         /**
     25          * response.setContentType("text/html;charset=UTF-8");目的是控制浏览器用UTF-8进行解码;
     26          * 这样就不会出现中文乱码了
     27          */
     28         response.setHeader("content-type","text/html;charset=UTF-8");
     29         readSrcDirPropCfgFile(response);//读取src目录下的properties配置文件
     30         response.getWriter().println("<hr/>");
     31         readWebRootDirPropCfgFile(response);//读取WebRoot目录下的properties配置文件
     32         response.getWriter().println("<hr/>");
     33         readPropCfgFile(response);//读取src目录下的db.config包中的db3.properties配置文件
     34         response.getWriter().println("<hr/>");
     35         readPropCfgFile2(response);//读取src目录下的gacl.servlet.study包中的db4.properties配置文件
     36         
     37     }
     38 
     39     /**
     40      * 读取src目录下的gacl.servlet.study包中的db4.properties配置文件
     41      * @param response
     42      * @throws IOException
     43      */
     44     private void readPropCfgFile2(HttpServletResponse response)
     45             throws IOException {
     46         InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/gacl/servlet/study/db4.properties");
     47         Properties prop = new Properties();
     48         prop.load(in);
     49         String driver = prop.getProperty("driver");
     50         String url = prop.getProperty("url");
     51         String username = prop.getProperty("username");
     52         String password = prop.getProperty("password");
     53         response.getWriter().println("读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
     54         response.getWriter().println(
     55                 MessageFormat.format(
     56                         "driver={0},url={1},username={2},password={3}", 
     57                         driver,url, username, password));
     58     }
     59 
     60     /**
     61      * 读取src目录下的db.config包中的db3.properties配置文件
     62      * @param response
     63      * @throws FileNotFoundException
     64      * @throws IOException
     65      */
     66     private void readPropCfgFile(HttpServletResponse response)
     67             throws FileNotFoundException, IOException {
     68         //通过ServletContext获取web资源的绝对路径
     69         String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");
     70         InputStream in = new FileInputStream(path);
     71         Properties prop = new Properties();
     72         prop.load(in);
     73         String driver = prop.getProperty("driver");
     74         String url = prop.getProperty("url");
     75         String username = prop.getProperty("username");
     76         String password = prop.getProperty("password");
     77         response.getWriter().println("读取src目录下的db.config包中的db3.properties配置文件:");
     78         response.getWriter().println(
     79                 MessageFormat.format(
     80                         "driver={0},url={1},username={2},password={3}", 
     81                         driver,url, username, password));
     82     }
     83 
     84     /**
     85      * 通过ServletContext对象读取WebRoot目录下的properties配置文件
     86      * @param response
     87      * @throws IOException
     88      */
     89     private void readWebRootDirPropCfgFile(HttpServletResponse response)
     90             throws IOException {
     91         /**
     92          * 通过ServletContext对象读取WebRoot目录下的properties配置文件
     93          * “/”代表的是项目根目录
     94          */
     95         InputStream in = this.getServletContext().getResourceAsStream("/db2.properties");
     96         Properties prop = new Properties();
     97         prop.load(in);
     98         String driver = prop.getProperty("driver");
     99         String url = prop.getProperty("url");
    100         String username = prop.getProperty("username");
    101         String password = prop.getProperty("password");
    102         response.getWriter().println("读取WebRoot目录下的db2.properties配置文件:");
    103         response.getWriter().print(
    104                 MessageFormat.format(
    105                         "driver={0},url={1},username={2},password={3}", 
    106                         driver,url, username, password));
    107     }
    108 
    109     /**
    110      * 通过ServletContext对象读取src目录下的properties配置文件
    111      * @param response
    112      * @throws IOException
    113      */
    114     private void readSrcDirPropCfgFile(HttpServletResponse response) throws IOException {
    115         /**
    116          * 通过ServletContext对象读取src目录下的db1.properties配置文件
    117          */
    118         InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");
    119         Properties prop = new Properties();
    120         prop.load(in);
    121         String driver = prop.getProperty("driver");
    122         String url = prop.getProperty("url");
    123         String username = prop.getProperty("username");
    124         String password = prop.getProperty("password");
    125         response.getWriter().println("读取src目录下的db1.properties配置文件:");
    126         response.getWriter().println(
    127                 MessageFormat.format(
    128                         "driver={0},url={1},username={2},password={3}", 
    129                         driver,url, username, password));
    130     }
    131 
    132     public void doPost(HttpServletRequest request, HttpServletResponse response)
    133             throws ServletException, IOException {
    134         this.doGet(request, response);
    135     }
    136 
    137 }

运行结果如下:

  izongjieliuservletkaifaer_6.png

代码范例:使用类装载器读取资源文件

    1 package gacl.servlet.study;
      2 
      3 import java.io.FileOutputStream;
      4 import java.io.IOException;
      5 import java.io.InputStream;
      6 import java.io.OutputStream;
      7 import java.text.MessageFormat;
      8 import java.util.Properties;
      9 
     10 import javax.servlet.ServletException;
     11 import javax.servlet.http.HttpServlet;
     12 import javax.servlet.http.HttpServletRequest;
     13 import javax.servlet.http.HttpServletResponse;
     14 
     15 /**
     16  * 用类装载器读取资源文件
     17  * 通过类装载器读取资源文件的注意事项:不适合装载大文件,否则会导致jvm内存溢出
     18  * @author gacl
     19  *
     20  */
     21 public class ServletContextDemo7 extends HttpServlet {
     22 
     23     public void doGet(HttpServletRequest request, HttpServletResponse response)
     24             throws ServletException, IOException {
     25         /**
     26          * response.setContentType("text/html;charset=UTF-8");目的是控制浏览器用UTF-8进行解码;
     27          * 这样就不会出现中文乱码了
     28          */
     29         response.setHeader("content-type","text/html;charset=UTF-8");
     30         test1(response);
     31         response.getWriter().println("<hr/>");
     32         test2(response);
     33         response.getWriter().println("<hr/>");
     34         //test3();
     35         test4();
     36         
     37     }
     38     
     39     /**
     40      * 读取类路径下的资源文件
     41      * @param response
     42      * @throws IOException
     43      */
     44     private void test1(HttpServletResponse response) throws IOException {
     45         //获取到装载当前类的类装载器
     46         ClassLoader loader = ServletContextDemo7.class.getClassLoader();
     47         //用类装载器读取src目录下的db1.properties配置文件
     48         InputStream in = loader.getResourceAsStream("db1.properties");
     49         Properties prop = new Properties();
     50         prop.load(in);
     51         String driver = prop.getProperty("driver");
     52         String url = prop.getProperty("url");
     53         String username = prop.getProperty("username");
     54         String password = prop.getProperty("password");
     55         response.getWriter().println("用类装载器读取src目录下的db1.properties配置文件:");
     56         response.getWriter().println(
     57                 MessageFormat.format(
     58                         "driver={0},url={1},username={2},password={3}", 
     59                         driver,url, username, password));
     60     }
     61 
     62     /**
     63      * 读取类路径下面、包下面的资源文件
     64      * @param response
     65      * @throws IOException
     66      */
     67     private void test2(HttpServletResponse response) throws IOException {
     68         //获取到装载当前类的类装载器
     69         ClassLoader loader = ServletContextDemo7.class.getClassLoader();
     70         //用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件
     71         InputStream in = loader.getResourceAsStream("gacl/servlet/study/db4.properties");
     72         Properties prop = new Properties();
     73         prop.load(in);
     74         String driver = prop.getProperty("driver");
     75         String url = prop.getProperty("url");
     76         String username = prop.getProperty("username");
     77         String password = prop.getProperty("password");
     78         response.getWriter().println("用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
     79         response.getWriter().println(
     80                 MessageFormat.format(
     81                         "driver={0},url={1},username={2},password={3}", 
     82                         driver,url, username, password));
     83     }
     84     
     85     /**
     86      * 通过类装载器读取资源文件的注意事项:不适合装载大文件,否则会导致jvm内存溢出
     87      */
     88     public void test3() {
     89         /**
     90          * 01.avi是一个150多M的文件,使用类加载器去读取这个大文件时会导致内存溢出:
     91          * java.lang.OutOfMemoryError: Java heap space
     92          */
     93         InputStream in = ServletContextDemo7.class.getClassLoader().getResourceAsStream("01.avi");
     94         System.out.println(in);
     95     }
     96     
     97     /**
     98      * 读取01.avi,并拷贝到e:\根目录下
     99      * 01.avi文件太大,只能用servletContext去读取
    100      * @throws IOException
    101      */
    102     public void test4() throws IOException {
    103         // path=G:\Java学习视频\JavaWeb学习视频\JavaWeb\day05视频\01.avi
    104         // path=01.avi
    105         String path = this.getServletContext().getRealPath("/WEB-INF/classes/01.avi");
    106         /**
    107          * path.lastIndexOf("\\") + 1是一个非常绝妙的写法
    108          */
    109         String filename = path.substring(path.lastIndexOf("\\") + 1);//获取文件名
    110         InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/01.avi");
    111         byte buffer[] = new byte[1024];
    112         int len = 0;
    113         OutputStream out = new FileOutputStream("e:\\" + filename);
    114         while ((len = in.read(buffer)) > 0) {
    115             out.write(buffer, 0, len);
    116         }
    117         out.close();
    118         in.close();
    119     }
    120 
    121     public void doPost(HttpServletRequest request, HttpServletResponse response)
    122             throws ServletException, IOException {
    123 
    124         this.doGet(request, response);
    125     }
    126 
    127 }

  运行结果如下:

  izongjieliuservletkaifaer_7.png

四、在客户端缓存Servlet的输出

  对于不经常变化的数据,在servlet中可以为其设置合理的缓存时间值,以避免浏览器频繁向服务器发送请求,提升服务器的性能。例如:

   1 package gacl.servlet.study;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 public class ServletDemo5 extends HttpServlet {
    11 
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14         String data = "abcddfwerwesfasfsadf";
    15         /**
    16          * 设置数据合理的缓存时间值,以避免浏览器频繁向服务器发送请求,提升服务器的性能
    17          * 这里是将数据的缓存时间设置为1天
    18          */
    19         response.setDateHeader("expires",System.currentTimeMillis() + 24 * 3600 * 1000);
    20         response.getOutputStream().write(data.getBytes());
    21     }
    22 
    23     public void doPost(HttpServletRequest request, HttpServletResponse response)
    24             throws ServletException, IOException {
    25 
    26         this.doGet(request, response);
    27     }
    28 
    29 }

izongjieliuservletkaifaer_8.png

作者:孤傲苍狼

来源:https://www.cnblogs.com/xdp-gacl/p/3763559.html


看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「方志朋」,公众号后台回复「666」 免费领取我精心整理的进阶资源教程
  4. JS中文网,Javascriptc中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,是给开发者用的 Hacker News,技术文章由为你筛选出最优质的干货,其中包括:Android、iOS、前端、后端等方面的内容。目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。

    本文著作权归作者所有,如若转载,请注明出处

    转载请注明:文章转载自「 Java极客技术学习 」https://www.javajike.com

    标题:javaweb学习总结(六)——Servlet开发(二)

    链接:https://www.javajike.com/article/1129.html

« javaweb学习总结(四十二)——Filter(过滤器)学习
javaweb学习总结(二十八)——JSTL标签库之核心标签»

相关推荐

QR code