Servlet

合成词。Servlet = Server + applet。服务器上面的一个小程序。

开发动态web资源的。每刷新一次浏览器,显示最新的时间。

how?

官方开发手册。技术文档。API文档。Servlet再JDK中吗?不能。Servlet属于EE的范畴

http://tomcat.apache.org/tomcat-8.5-doc/servletapi/

A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.

  1. The servlet is constructed, then initialized with the init method.
  2. Any calls from clients to the service method are handled.
  3. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.

手动实现Servlet

1.编写一个类实现Servlet接口

2.将编写好的Servlet放置在WebServer中运行。
image.png

原因在哪?

涉及到类加载。当执行编译指令时,会将相关联的class文件加载到内存中,那么去那个目录下寻找对应的文件呢?

涉及到类加载的机制。

类加载器其实就是负责将相关的类加载到内存中的。

一共有三类

1.BootStrap类加载器:jre目录下面的class

2.Extension类加载器:jre/ext目录下面的class

3.System类加载器:主要加载通过 -classpath指令的类加载到内存中

javax.servlet相关的jar包以及class不在JDK中。

image.png

如何运行?

image.png

A servlet is a small Java program that runs within a Web server

如何把一个class文件部署在服务器中呢?

需要记住一个知识点(很重要),JavaWeb项目标准目录结构

image.png

接下来,如何让Servlet真正的被执行到呢?

服务器给提供了一个机制,做了一个映射,当你访问某个对应的url时,相当于告诉服务器我需要执行当前对应的servlet。

/first———-FirstServlet

/second ——SecondServlet

访问的时候,首先要加上应用名,接下来才是url-pattern映射

行政区域。

总结一下Servlet的执行流程

当我们访问http://localhost/app/first时,经历了哪些事情呢?

1.请求到达服务器tomcat之后,被监听80端口的Connector接收到,将其解析成为Request对象,同时还生成一个Response对象

2.将这两个对象传给Engine,Engine挑选一个Host进行后续逻辑处理

3.Host来挑选一个合适的Context来处理,将这两个对象交给app Context来处理

4.web.xml中配置了一个映射关系,tomcat在启动的时候,Context可以拿到对应的映射关系。

/first FirstServlet

根据有效请求/first去寻找有没有对应的class,找到FirstServlet.class

利用反射实例化该对象 Class.forName.newInstance

执行该对象的service方法。——-因为它时Servlet,实现了Servlet接口,肯定有service方法

5.Context处理完毕之后,依次返回两个对象给Host、Engine、Connector,Connector读取Response里面的数据生成响应报文,发送出去

使用IDEA来编写Servlet

继承HttpServlet

  1. package com.cskaoyan.servlet;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.http.HttpServlet;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. public class ThirdServlet extends HttpServlet {
  8. /**
  9. * 如果你发送的时HTTP Get请求,那么会进入到doGet方法中
  10. * 如果发送的时HTTP Post请求,会进入到doPost方法中
  11. * @param req
  12. * @param resp
  13. * @throws ServletException
  14. * @throws IOException
  15. */
  16. @Override
  17. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  18. //super.doGet(req, resp);
  19. System.out.println("doGet");
  20. }
  21. @Override
  22. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  23. System.out.println("doPost");
  24. }
  25. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <servlet>
  7. <servlet-name>second</servlet-name>
  8. <servlet-class>com.cskaoyan.servlet.SecondServlet</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>second</servlet-name>
  12. <url-pattern>/second</url-pattern>
  13. </servlet-mapping>
  14. <servlet>
  15. <servlet-name>third</servlet-name>
  16. <servlet-class>com.cskaoyan.servlet.ThirdServlet</servlet-class>
  17. </servlet>
  18. <servlet-mapping>
  19. <servlet-name>third</servlet-name>
  20. <url-pattern>/third</url-pattern>
  21. </servlet-mapping>
  22. </web-app>

实现方式三

针对声明Servlet,不仅可以通过web.xml方式,还可以通过注解的方式

  1. package com.cskaoyan.servlet;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. //@WebServlet(name = "fourth",value = "/fourth")
  9. //如果你的WebServlet注解里面只有一个值,那么表示的就是value或者urlPattern值
  10. //@WebServlet(value = "/fourth")
  11. @WebServlet("/fourth")
  12. public class FourthServlet extends HttpServlet {
  13. @Override
  14. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  15. System.out.println("doget");
  16. }
  17. /**
  18. * 如何发送请求到doPost方法中
  19. * http://localhost/app2/fourth 要以post方式来访问
  20. * @param req
  21. * @param resp
  22. * @throws ServletException
  23. * @throws IOException
  24. */
  25. @Override
  26. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  27. System.out.println("dopost");
  28. }
  29. }
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <form action="http://localhost/app2/fourth" method="post">
  9. <input type="text" name="username"><br>
  10. <input type="submit">
  11. </form>
  12. </body>
  13. </html>

推荐:

推荐使用继承HttpServlet,并且使用注解的方式。

继承HttpServlet的好处?

可以根据请求方法的不同,做不同的分发。比如

查询 get

提交 post

为什么继承HttpServlet没有service方法?doGet和doPost又是经过怎么样的执行流程过来的?

Servlet - 图5

Servlet - 图6

因为HttpServlet已经实现了service方法

程序执行入口

  1. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  2. HttpServletRequest request;
  3. HttpServletResponse response;
  4. try {
  5. request = (HttpServletRequest)req;
  6. response = (HttpServletResponse)res;
  7. } catch (ClassCastException var6) {
  8. throw new ServletException("non-HTTP request or response");
  9. }
  10. this.service(request, response);
  11. }

执行自身的service方法,根据请求方法的不同,分发到不同的方法中

GET请求方法——doGet方法中

POST请求方法—doPost方法中

IDEA和Tomcat的关联方式

CATALINA_BASE: 】【

;·1 9.3\system\tomcat\Tomcat_8_5_37_servlet

IDEA会复制tomcat的配置文件,到这个地方新开启一个新的tomcat,利用这个tomcat来部署我们的应用

  1. <Context path="/app2" docBase="D:\ideaProjects\servlet\out\artifacts\servlet_war_exploded" />

Servlet - 图7

Servlet - 图8

可以发现,开发目录和最终部署目录不是同一个目录,但是却不是没有关系。

开发目录里面的文件会按照某种规则复制到部署目录里面去。

Servlet - 图9

结论:

开发目录和部署目录不是一个目录,存在着复制规则,会将开发目录里面的文件复制到部署目录里面去

facet artifacts

如果在开发目录里面web目录里面新建了一个静态资源文件,但是访问却显示404,这个时候一定要记得去到部署目录里面看看是否存在,部署目录不存在,那么404时正常的

开发目录里面有,但是部署目录里面没有,怎么办呢?

1.重新Redeploy,重新部署一下试试,

2.如果不行,那么接下来,

Servlet - 图10

先rebuild project,再次重新部署,执行步骤1

如果还是不行,那么可以把部署目录里面的文件全部删除,然后执行2,再执行1

Servlet生命周期

  1. package com.cskaoyan.servlet.life;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. /**
  9. * 当你访问servlet相关联的url-pattern时,那么就会访问当前servlet
  10. * 只要你访问当前servlet,那么就一定会执行该servlet的service方法
  11. * init方法默认情况下再第一次访问当前servlet的时候会执行到,利用该方法将servlet对象进行初始化,
  12. * 后续再次访问不会执行
  13. */
  14. @WebServlet("/life")
  15. public class LifeCycleServlet extends HttpServlet {
  16. /**
  17. * init表示的时servlet被创建的时候会调用该方法来初始化一些参数
  18. * 执行时机:第一次访问当前servlet的时候,会先创建一个servlet对象,然后调用init方法
  19. * 后面再次访问不会调用init方法
  20. * 结论:再tomcat中默认每一个servlet类只有一个servlet对象----单例
  21. * @throws ServletException
  22. */
  23. @Override
  24. public void init() throws ServletException {
  25. //super.init();
  26. System.out.println("life init");
  27. }
  28. /**
  29. * 当应用被卸载、tomcat服务器关闭
  30. */
  31. @Override
  32. public void destroy() {
  33. System.out.println("life destroy");
  34. }
  35. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  36. System.out.println("dopost");
  37. }
  38. /**
  39. * service方法,每一次访问当前servlet,都会执行service方法
  40. * 再HttpServlet中,doGet和doPost就是service方法
  41. * @param request
  42. * @param response
  43. * @throws ServletException
  44. * @throws IOException
  45. */
  46. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  47. System.out.println("doget");
  48. }
  49. }

补充:

其中对于servlet的init方法,默认情况下是再第一次访问当前servlet的时候会执行调用,但是可以通过设置一个参数,让init方法随着应用的启动而执行,

load-on-startup=1 非负数

  1. @WebServlet(value = "/life",loadOnStartup = 1)

或者通过web.xml方式

  1. <servlet>
  2. <servlet-name>life</servlet-name>
  3. <servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class>
  4. <load-on-startup>1</load-on-startup>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>life</servlet-name>
  8. <url-pattern>/life</url-pattern>
  9. </servlet-mapping>

这个有什么意义呢?

可以做一些预处理操作。算法、查询数据库。

比如可以再某个servlet的init方法中进行一些运算,或者查询数据库等,得到一个结果集,这个结果有可能再不同的servlet中都有可能用到,放入context域中。

执行流程补充

当我们访问http://localhost/app/first时,经历了哪些事情呢?

1.请求到达服务器tomcat之后,被监听80端口的Connector接收到,将其解析成为Request对象,同时还生成一个Response对象

2.将这两个对象传给Engine,Engine挑选一个Host进行后续逻辑处理

3.Host来挑选一个合适的Context来处理,将这两个对象交给app Context来处理

4.web.xml中配置了一个映射关系,tomcat在启动的时候,Context可以拿到对应的映射关系。

/first FirstServlet

根据有效请求/first去寻找有没有对应的class,找到FirstServlet.class

如果是第一次访问当前servlet,那么会利用反射实例化该对象 Class.forName.newInstance,如果不是第一次访问,那么直接

执行该对象的service方法。——-因为它时Servlet,实现了Servlet接口,肯定有service方法

5.Context处理完毕之后,依次返回两个对象给Host、Engine、Connector,Connector读取Response里面的数据生成响应报文,发送出去

Servlet - 图11

Servlet - 图12

url-pattern的细节

1.一个servlet可以设置多个url-pattern吗?可以

  1. servlet>
  2. <servlet-name>life</servlet-name>
  3. <servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class>
  4. <load-on-startup>1</load-on-startup>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>life</servlet-name>
  8. <url-pattern>/life1</url-pattern>
  9. <url-pattern>/life2</url-pattern>
  10. </servlet-mapping>
  1. @WebServlet(value = {"
  2. life1","/life2"},loadOnStartup = 1)

2.多个servlet可以映射到同一个url-pattern吗?不可以

  1. @WebServlet(value = {"/life2"},loadOnStartup = 1)

Caused by: java.lang.IllegalArgumentException: The servlets named [com.cskaoyan.servlet.life.LifeCycleServlet] and [com.cskaoyan.servlet.life.LifeCycleServlet2] are both mapped to the url-pattern [/life2] which is not permitted

主动去复现这个bug,然后找出来

3.url-pattern的写法有哪些呢?可以随意写吗? /xxx *.xxx

Caused by: java.lang.IllegalArgumentException: Invalid [life1] in servlet mapping

url-pattern优先级

1、 /xxx开头的优先级高于.xxx,如果有/xxx存在,那么始终无法执行到 .xxx

2、都是/开头的url-pattern,匹配程度越高,优先级越高

缺省Servlet(非常重要)

保留/ *,接下来访问静态资源。

conf/web.xml文件中有如下配置,tomcat的web.xml你可以认为是我们所有应用的一个父配置i文件,里面的配置信息对所有的应用全部有效。

  1. <servlet>
  2. <servlet-name>jsp</servlet-name>
  3. <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
  4. <init-param>
  5. <param-name>fork</param-name>
  6. <param-value>false</param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name>xpoweredBy</param-name>
  10. <param-value>false</param-value>
  11. </init-param>
  12. <load-on-startup>3</load-on-startup>
  13. </servlet>
  14. <servlet-mapping>
  15. <servlet-name>jsp</servlet-name>
  16. <url-pattern>*.jsp</url-pattern>
  17. <url-pattern>*.jspx</url-pattern>
  18. </servlet-mapping>

当我们再访问index.jsp时,实际访问的是谁?实际访问的是这个JspServlet

为什么我们设置了/ 之后,显示的就是/ 而不再是原先的jsp了呢?

原先是因为 / 的优先级高于 * .jsp,始终无法访问到jspServlet

/ /同时存在,无论访问jsp还是访问html均无法正常访问,显示的均是 /

/ *注释之后,jsp可以正常访问到,但是html仍然无法正常访问到,显示的是 /

/其实是一个缺省servlet,当一个请求到达应用,如果没有任何的servlet的url-pattern可以i处理该请求,那么就会调用缺省servlet来处理。

结论:访问静态资源时,有没有servlet参与进来?有servlet参与进来,那就是缺省servlet。

  1. <servlet>
  2. <servlet-name>default</servlet-name>
  3. <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
  4. <init-param>
  5. <param-name>debug</param-name>
  6. <param-value>0</param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name>listings</param-name>
  10. <param-value>false</param-value>
  11. </init-param>
  12. <load-on-startup>1</load-on-startup>
  13. </servlet>
  14. <servlet-mapping>
  15. <servlet-name>default</servlet-name>
  16. <url-pattern>/</url-pattern>
  17. </servlet-mapping>
  18. <!-- The default servlet for all web applications, that serves static -->
  19. <!-- resources. It processes all requests that are not mapped to other -->
  20. <!-- servlets with servlet mappings (defined either here or in your own -->
  21. <!-- web.xml file).

ServletConfig

利用该对象可以获取某个servlet的一些初始化参数。

Servlet - 图13

接下来只需要利用ServletConfig.getInitParameter(name),

本API再实际使用中使用的场景不是特别的多,但是需要大家知道这个是用来干什么的,如果看到别人的代码里面有这个,那么你需要清楚时再干什么。

  1. package com.cskaoyan.servlet.config;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. public class ConfigServlet extends GenericServlet {
  9. @Override
  10. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  11. //这个方法哪来的?继承自GenericServlet而来的
  12. //tomcat再启动的过程中,会将某个servlet下面的init-param自动封装到servletConfig对象中
  13. ServletConfig servletConfig = getServletConfig();
  14. String name = servletConfig.getInitParameter("name");
  15. System.out.println(name);
  16. }
  17. }

ServletContext对象

再每一个应用中,有且只有一个servletContext对象,当前应用下的任何的servlet都可以拿到该context对象的引用。

获取全局性初始化参数

  1. package com.cskaoyan.servlet.context;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class ContextServlet1 extends GenericServlet {
  5. @Override
  6. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  7. ServletContext servletContext = getServletContext();
  8. String name = servletContext.getInitParameter("name");
  9. System.out.println(name);
  10. }
  11. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <servlet>
  7. <servlet-name>second</servlet-name>
  8. <servlet-class>com.cskaoyan.servlet.SecondServlet</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>second</servlet-name>
  12. <url-pattern>/second</url-pattern>
  13. </servlet-mapping>
  14. <servlet>
  15. <servlet-name>third</servlet-name>
  16. <servlet-class>com.cskaoyan.servlet.ThirdServlet</servlet-class>
  17. </servlet>
  18. <servlet-mapping>
  19. <servlet-name>third</servlet-name>
  20. <url-pattern>/third</url-pattern>
  21. </servlet-mapping>
  22. <!--<servlet>
  23. <servlet-name>life</servlet-name>
  24. <servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class>
  25. <load-on-startup>1</load-on-startup>
  26. </servlet>
  27. <servlet-mapping>
  28. <servlet-name>life</servlet-name>
  29. <url-pattern>/life1</url-pattern>
  30. <url-pattern>/life2</url-pattern>
  31. </servlet-mapping>-->
  32. <!--<servlet>
  33. <servlet-name>servlet1</servlet-name>
  34. <servlet-class>com.cskaoyan.servlet.priority.Servlet1</servlet-class>
  35. </servlet>
  36. <servlet>
  37. <servlet-name>servlet2</servlet-name>
  38. <servlet-class>com.cskaoyan.servlet.priority.Servlet2</servlet-class>
  39. </servlet>
  40. <servlet>
  41. <servlet-name>servlet3</servlet-name>
  42. <servlet-class>com.cskaoyan.servlet.priority.Servlet3</servlet-class>
  43. </servlet>
  44. <servlet>
  45. <servlet-name>servlet4</servlet-name>
  46. <servlet-class>com.cskaoyan.servlet.priority.Servlet4</servlet-class>
  47. </servlet>
  48. <servlet-mapping>
  49. <servlet-name>servlet1</servlet-name>
  50. <url-pattern>/abc/*</url-pattern>
  51. </servlet-mapping>
  52. <servlet-mapping>
  53. <servlet-name>servlet2</servlet-name>
  54. <url-pattern>/*</url-pattern>
  55. </servlet-mapping>
  56. <servlet-mapping>
  57. <servlet-name>servlet3</servlet-name>
  58. <url-pattern>/abc</url-pattern>
  59. </servlet-mapping>
  60. <servlet-mapping>
  61. <servlet-name>servlet4</servlet-name>
  62. <url-pattern>*.do</url-pattern>
  63. </servlet-mapping>-->
  64. <servlet>
  65. <servlet-name>config</servlet-name>
  66. <servlet-class>com.cskaoyan.servlet.config.ConfigServlet</servlet-class>
  67. <init-param>
  68. <param-name>name</param-name>
  69. <param-value>ligenli</param-value>
  70. </init-param>
  71. </servlet>
  72. <servlet-mapping>
  73. <servlet-name>config</servlet-name>
  74. <url-pattern>/config</url-pattern>
  75. </servlet-mapping>
  76. <servlet>
  77. <servlet-name>context1</servlet-name>
  78. <servlet-class>com.cskaoyan.servlet.context.ContextServlet1</servlet-class>
  79. </servlet>
  80. <servlet-mapping>
  81. <servlet-name>context1</servlet-name>
  82. <url-pattern>/context1</url-pattern>
  83. </servlet-mapping>
  84. <!--并不从属于任何servelt节点下,所以时全局性的-->
  85. <context-param>
  86. <param-name>name</param-name>
  87. <param-value>shuaige</param-value>
  88. </context-param>
  89. </web-app>

Context域

一块内存空间,可以再这快内存空间里面进行数据的共享。比如局域网 27th 26th

  1. package com.cskaoyan.servlet.context;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. @WebServlet("/domain1")
  10. public class DomainServlet1 extends HttpServlet {
  11. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. }
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. ServletContext servletContext = getServletContext();
  15. servletContext.setAttribute("key", "ligenli");
  16. }
  17. }
  1. package com.cskaoyan.servlet.context;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. @WebServlet("/domain2")
  10. public class DomainServlet2 extends HttpServlet {
  11. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. }
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. //只要再一个应用中,不管任何servlet,拿到的全部都是同一个servletContext对象的引用
  15. ServletContext servletContext = getServletContext();
  16. String key = (String) servletContext.getAttribute("key");
  17. System.out.println(key);
  18. }
  19. }

Servlet - 图14

  1. package com.cskaoyan.servlet.context;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. @WebServlet(value = "/domain1",loadOnStartup = 1)
  10. public class DomainServlet1 extends HttpServlet {
  11. @Override
  12. public void init() throws ServletException {
  13. //初始化工作,拿到结果集,放入context域中
  14. ServletContext servletContext = getServletContext();
  15. servletContext.setAttribute("key", "ligenli");
  16. }
  17. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. }
  19. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  20. ServletContext servletContext = getServletContext();
  21. String key = (String) servletContext.getAttribute("key");
  22. System.out.println(key);
  23. }
  24. }
  1. package com.cskaoyan.servlet.context;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. @WebServlet("/domain2")
  10. public class DomainServlet2 extends HttpServlet {
  11. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. }
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. //只要再一个应用中,不管任何servlet,拿到的全部都是同一个servletContext对象的引用
  15. ServletContext servletContext = getServletContext();
  16. String key = (String) servletContext.getAttribute("key");
  17. System.out.println(key);
  18. }
  19. }

获取EE项目文件的绝对路径

servletContext.getRealPath(path)

利用这个API可以获取EE项目部署根目录下某个资源文件的绝对路径

如果里面输入的是空字符串,那么得到的是部署根目录的绝对路径;

如果希望获取部署根目录下面的某个文件的绝对路径,只需要指明它和部署根目录之间的相对路径关系即可。

比如再部署根目录中有一个1.html,

如果是WEB-INF/1.html,能不能获取到?

  1. package com.cskaoyan.servlet.path;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.File;
  9. import java.io.IOException;
  10. @WebServlet("/path")
  11. public class PathServlet extends HttpServlet {
  12. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. }
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //想获取1.html文件流信息-----file信息
  16. //D:\apache-tomcat-8.5.37\bin\1.html
  17. // File file = new File("1.html");
  18. // file.createNewFile();
  19. // String path = file.getAbsolutePath();
  20. // System.out.println(path);
  21. // 问题1:为什么创建一个文件,会创建到tomcat的bin目录下
  22. //相对路径:JDK中关于相对路径的描述其实是相对的jvm的调用目录
  23. //ee项目本质上来说,就是我们写了很多的代码片段,来供服务器tomcat来调用
  24. //服务器会再bin目录下调用jvm,所以项目中相对路径相对的全部都是tomcat的bin目录
  25. //问题2:我们希望获取部署根目录下面的某个资源文件的流信息 file信息
  26. //servletContext可以给我们提供一个API,利用这个API可以获取到EE项目文件的绝对路径
  27. ServletContext servletContext = getServletContext();
  28. //如果里面什么参数都不输入,这个时候可以定位到应用部署根目录
  29. //如果你希望获取部署根目录下的任何一个文件的路径信息,只需要指明它和部署根目录之间的相对路径关系即可
  30. String realPath = servletContext.getRealPath("");
  31. System.out.println(realPath);
  32. }
  33. }
  1. package com.cskaoyan.servlet.path;
  2. import javax.servlet.ServletContext;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.File;
  9. import java.io.IOException;
  10. @WebServlet("/path")
  11. public class PathServlet extends HttpServlet {
  12. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. }
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //想获取1.html文件流信息-----file信息
  16. //D:\apache-tomcat-8.5.37\bin\1.html
  17. // File file = new File("1.html");
  18. // file.createNewFile();
  19. // String path = file.getAbsolutePath();
  20. // System.out.println(path);
  21. // 问题1:为什么创建一个文件,会创建到tomcat的bin目录下
  22. //相对路径:JDK中关于相对路径的描述其实是相对的jvm的调用目录
  23. //ee项目本质上来说,就是我们写了很多的代码片段,来供服务器tomcat来调用
  24. //服务器会再bin目录下调用jvm,所以项目中相对路径相对的全部都是tomcat的bin目录
  25. //问题2:我们希望获取部署根目录下面的某个资源文件的流信息 file信息
  26. //servletContext可以给我们提供一个API,利用这个API可以获取到EE项目文件的绝对路径
  27. ServletContext servletContext = getServletContext();
  28. //如果里面什么参数都不输入,这个时候可以定位到应用部署根目录
  29. //如果你希望获取部署根目录下的任何一个文件的路径信息,只需要指明它和部署根目录之间的相对路径关系即可
  30. String realPath = servletContext.getRealPath("");
  31. System.out.println(realPath);
  32. String realPath1 = servletContext.getRealPath("1.html");
  33. boolean exists = new File(realPath1).exists();
  34. System.out.println(exists);
  35. //如果希望访问WEB-INF目录下的文件,可以访问到吗 可以获取到
  36. //注意WEB-INF屏蔽的是浏览器的直接访问,不是服务器;对于服务器来说,任何目录都是非常普通的目录
  37. String realPath2 = servletContext.getRealPath("WEB-INF/1.txt");
  38. boolean exists1 = new File(realPath2).exists();
  39. System.out.println(exists1);
  40. }
  41. }