Java Web学习总结(六)——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. }

运行结果如下:

  

二、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对象中取出数据了,这样就实现了数据共享,如下图所示:

  

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

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

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <web-app version="3.0"

  3. xmlns="http://java.sun.com/xml/ns/javaee"

  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  5. http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  6. <display-name></display-name>

  7. <!-- 配置WEB应用的初始化参数 -->

  8. <context-param>

  9. <param-name>url</param-name>

  10. <param-value>jdbc:mysql://localhost:3306/test</param-value>

  11. </context-param>

  12. <welcome-file-list>

  13. <welcome-file>index.jsp</welcome-file>

  14. </welcome-file-list>

  15. </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. }

运行结果:

  

  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. }

  运行结果:

  

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

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

  项目目录结构如下:

   

代码范例:使用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. }

运行结果如下:

  

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

 
  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. }

运行结果如下:

  

四、在客户端缓存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. }

猜你喜欢

转载自blog.csdn.net/qq_40285302/article/details/82797535
今日推荐