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.
- The servlet is constructed, then initialized with the
initmethod. - Any calls from clients to the
servicemethod are handled. - The servlet is taken out of service, then destroyed with the
destroymethod, then garbage collected and finalized.
手动实现Servlet
1.编写一个类实现Servlet接口
2.将编写好的Servlet放置在WebServer中运行。
原因在哪?
涉及到类加载。当执行编译指令时,会将相关联的class文件加载到内存中,那么去那个目录下寻找对应的文件呢?
涉及到类加载的机制。
类加载器其实就是负责将相关的类加载到内存中的。
一共有三类
1.BootStrap类加载器:jre目录下面的class
2.Extension类加载器:jre/ext目录下面的class
3.System类加载器:主要加载通过 -classpath指令的类加载到内存中
javax.servlet相关的jar包以及class不在JDK中。

如何运行?

A servlet is a small Java program that runs within a Web server
如何把一个class文件部署在服务器中呢?
需要记住一个知识点(很重要),JavaWeb项目标准目录结构

接下来,如何让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
package com.cskaoyan.servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class ThirdServlet extends HttpServlet {/*** 如果你发送的时HTTP Get请求,那么会进入到doGet方法中* 如果发送的时HTTP Post请求,会进入到doPost方法中* @param req* @param resp* @throws ServletException* @throws IOException*/@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//super.doGet(req, resp);System.out.println("doGet");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPost");}}
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>second</servlet-name><servlet-class>com.cskaoyan.servlet.SecondServlet</servlet-class></servlet><servlet-mapping><servlet-name>second</servlet-name><url-pattern>/second</url-pattern></servlet-mapping><servlet><servlet-name>third</servlet-name><servlet-class>com.cskaoyan.servlet.ThirdServlet</servlet-class></servlet><servlet-mapping><servlet-name>third</servlet-name><url-pattern>/third</url-pattern></servlet-mapping></web-app>
实现方式三
针对声明Servlet,不仅可以通过web.xml方式,还可以通过注解的方式
package com.cskaoyan.servlet;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;//@WebServlet(name = "fourth",value = "/fourth")//如果你的WebServlet注解里面只有一个值,那么表示的就是value或者urlPattern值//@WebServlet(value = "/fourth")@WebServlet("/fourth")public class FourthServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doget");}/*** 如何发送请求到doPost方法中* http://localhost/app2/fourth 要以post方式来访问* @param req* @param resp* @throws ServletException* @throws IOException*/@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dopost");}}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="http://localhost/app2/fourth" method="post"><input type="text" name="username"><br><input type="submit"></form></body></html>
推荐:
推荐使用继承HttpServlet,并且使用注解的方式。
继承HttpServlet的好处?
可以根据请求方法的不同,做不同的分发。比如
查询 get
提交 post
为什么继承HttpServlet没有service方法?doGet和doPost又是经过怎么样的执行流程过来的?


因为HttpServlet已经实现了service方法
程序执行入口
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {HttpServletRequest request;HttpServletResponse response;try {request = (HttpServletRequest)req;response = (HttpServletResponse)res;} catch (ClassCastException var6) {throw new ServletException("non-HTTP request or response");}this.service(request, response);}
执行自身的service方法,根据请求方法的不同,分发到不同的方法中
GET请求方法——doGet方法中
POST请求方法—doPost方法中
IDEA和Tomcat的关联方式
CATALINA_BASE: 】【
;·1 9.3\system\tomcat\Tomcat_8_5_37_servlet
IDEA会复制tomcat的配置文件,到这个地方新开启一个新的tomcat,利用这个tomcat来部署我们的应用
<Context path="/app2" docBase="D:\ideaProjects\servlet\out\artifacts\servlet_war_exploded" />


可以发现,开发目录和最终部署目录不是同一个目录,但是却不是没有关系。
开发目录里面的文件会按照某种规则复制到部署目录里面去。

结论:
开发目录和部署目录不是一个目录,存在着复制规则,会将开发目录里面的文件复制到部署目录里面去
facet artifacts
如果在开发目录里面web目录里面新建了一个静态资源文件,但是访问却显示404,这个时候一定要记得去到部署目录里面看看是否存在,部署目录不存在,那么404时正常的
开发目录里面有,但是部署目录里面没有,怎么办呢?
1.重新Redeploy,重新部署一下试试,
2.如果不行,那么接下来,

先rebuild project,再次重新部署,执行步骤1
如果还是不行,那么可以把部署目录里面的文件全部删除,然后执行2,再执行1
Servlet生命周期
package com.cskaoyan.servlet.life;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/*** 当你访问servlet相关联的url-pattern时,那么就会访问当前servlet* 只要你访问当前servlet,那么就一定会执行该servlet的service方法* init方法默认情况下再第一次访问当前servlet的时候会执行到,利用该方法将servlet对象进行初始化,* 后续再次访问不会执行*/@WebServlet("/life")public class LifeCycleServlet extends HttpServlet {/*** init表示的时servlet被创建的时候会调用该方法来初始化一些参数* 执行时机:第一次访问当前servlet的时候,会先创建一个servlet对象,然后调用init方法* 后面再次访问不会调用init方法* 结论:再tomcat中默认每一个servlet类只有一个servlet对象----单例* @throws ServletException*/@Overridepublic void init() throws ServletException {//super.init();System.out.println("life init");}/*** 当应用被卸载、tomcat服务器关闭*/@Overridepublic void destroy() {System.out.println("life destroy");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("dopost");}/*** service方法,每一次访问当前servlet,都会执行service方法* 再HttpServlet中,doGet和doPost就是service方法* @param request* @param response* @throws ServletException* @throws IOException*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("doget");}}
补充:
其中对于servlet的init方法,默认情况下是再第一次访问当前servlet的时候会执行调用,但是可以通过设置一个参数,让init方法随着应用的启动而执行,
load-on-startup=1 非负数
@WebServlet(value = "/life",loadOnStartup = 1)
或者通过web.xml方式
<servlet><servlet-name>life</servlet-name><servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>life</servlet-name><url-pattern>/life</url-pattern></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里面的数据生成响应报文,发送出去


url-pattern的细节
1.一个servlet可以设置多个url-pattern吗?可以
servlet><servlet-name>life</servlet-name><servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>life</servlet-name><url-pattern>/life1</url-pattern><url-pattern>/life2</url-pattern></servlet-mapping>
@WebServlet(value = {"life1","/life2"},loadOnStartup = 1)
2.多个servlet可以映射到同一个url-pattern吗?不可以
@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文件,里面的配置信息对所有的应用全部有效。
<servlet><servlet-name>jsp</servlet-name><servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class><init-param><param-name>fork</param-name><param-value>false</param-value></init-param><init-param><param-name>xpoweredBy</param-name><param-value>false</param-value></init-param><load-on-startup>3</load-on-startup></servlet><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>*.jsp</url-pattern><url-pattern>*.jspx</url-pattern></servlet-mapping>
当我们再访问index.jsp时,实际访问的是谁?实际访问的是这个JspServlet
为什么我们设置了/ 之后,显示的就是/ 而不再是原先的jsp了呢?
原先是因为 / 的优先级高于 * .jsp,始终无法访问到jspServlet
/ /同时存在,无论访问jsp还是访问html均无法正常访问,显示的均是 /
/ *注释之后,jsp可以正常访问到,但是html仍然无法正常访问到,显示的是 /
/其实是一个缺省servlet,当一个请求到达应用,如果没有任何的servlet的url-pattern可以i处理该请求,那么就会调用缺省servlet来处理。
结论:访问静态资源时,有没有servlet参与进来?有servlet参与进来,那就是缺省servlet。
<servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- The default servlet for all web applications, that serves static --><!-- resources. It processes all requests that are not mapped to other --><!-- servlets with servlet mappings (defined either here or in your own --><!-- web.xml file).
ServletConfig
利用该对象可以获取某个servlet的一些初始化参数。

接下来只需要利用ServletConfig.getInitParameter(name),
本API再实际使用中使用的场景不是特别的多,但是需要大家知道这个是用来干什么的,如果看到别人的代码里面有这个,那么你需要清楚时再干什么。
package com.cskaoyan.servlet.config;import javax.servlet.*;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class ConfigServlet extends GenericServlet {@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//这个方法哪来的?继承自GenericServlet而来的//tomcat再启动的过程中,会将某个servlet下面的init-param自动封装到servletConfig对象中ServletConfig servletConfig = getServletConfig();String name = servletConfig.getInitParameter("name");System.out.println(name);}}
ServletContext对象
再每一个应用中,有且只有一个servletContext对象,当前应用下的任何的servlet都可以拿到该context对象的引用。
获取全局性初始化参数
package com.cskaoyan.servlet.context;import javax.servlet.*;import java.io.IOException;public class ContextServlet1 extends GenericServlet {@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {ServletContext servletContext = getServletContext();String name = servletContext.getInitParameter("name");System.out.println(name);}}
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>second</servlet-name><servlet-class>com.cskaoyan.servlet.SecondServlet</servlet-class></servlet><servlet-mapping><servlet-name>second</servlet-name><url-pattern>/second</url-pattern></servlet-mapping><servlet><servlet-name>third</servlet-name><servlet-class>com.cskaoyan.servlet.ThirdServlet</servlet-class></servlet><servlet-mapping><servlet-name>third</servlet-name><url-pattern>/third</url-pattern></servlet-mapping><!--<servlet><servlet-name>life</servlet-name><servlet-class>com.cskaoyan.servlet.life.LifeCycleServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>life</servlet-name><url-pattern>/life1</url-pattern><url-pattern>/life2</url-pattern></servlet-mapping>--><!--<servlet><servlet-name>servlet1</servlet-name><servlet-class>com.cskaoyan.servlet.priority.Servlet1</servlet-class></servlet><servlet><servlet-name>servlet2</servlet-name><servlet-class>com.cskaoyan.servlet.priority.Servlet2</servlet-class></servlet><servlet><servlet-name>servlet3</servlet-name><servlet-class>com.cskaoyan.servlet.priority.Servlet3</servlet-class></servlet><servlet><servlet-name>servlet4</servlet-name><servlet-class>com.cskaoyan.servlet.priority.Servlet4</servlet-class></servlet><servlet-mapping><servlet-name>servlet1</servlet-name><url-pattern>/abc/*</url-pattern></servlet-mapping><servlet-mapping><servlet-name>servlet2</servlet-name><url-pattern>/*</url-pattern></servlet-mapping><servlet-mapping><servlet-name>servlet3</servlet-name><url-pattern>/abc</url-pattern></servlet-mapping><servlet-mapping><servlet-name>servlet4</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>--><servlet><servlet-name>config</servlet-name><servlet-class>com.cskaoyan.servlet.config.ConfigServlet</servlet-class><init-param><param-name>name</param-name><param-value>ligenli</param-value></init-param></servlet><servlet-mapping><servlet-name>config</servlet-name><url-pattern>/config</url-pattern></servlet-mapping><servlet><servlet-name>context1</servlet-name><servlet-class>com.cskaoyan.servlet.context.ContextServlet1</servlet-class></servlet><servlet-mapping><servlet-name>context1</servlet-name><url-pattern>/context1</url-pattern></servlet-mapping><!--并不从属于任何servelt节点下,所以时全局性的--><context-param><param-name>name</param-name><param-value>shuaige</param-value></context-param></web-app>
Context域
一块内存空间,可以再这快内存空间里面进行数据的共享。比如局域网 27th 26th
package com.cskaoyan.servlet.context;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/domain1")public class DomainServlet1 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();servletContext.setAttribute("key", "ligenli");}}
package com.cskaoyan.servlet.context;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/domain2")public class DomainServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//只要再一个应用中,不管任何servlet,拿到的全部都是同一个servletContext对象的引用ServletContext servletContext = getServletContext();String key = (String) servletContext.getAttribute("key");System.out.println(key);}}

package com.cskaoyan.servlet.context;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet(value = "/domain1",loadOnStartup = 1)public class DomainServlet1 extends HttpServlet {@Overridepublic void init() throws ServletException {//初始化工作,拿到结果集,放入context域中ServletContext servletContext = getServletContext();servletContext.setAttribute("key", "ligenli");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();String key = (String) servletContext.getAttribute("key");System.out.println(key);}}
package com.cskaoyan.servlet.context;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/domain2")public class DomainServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//只要再一个应用中,不管任何servlet,拿到的全部都是同一个servletContext对象的引用ServletContext servletContext = getServletContext();String key = (String) servletContext.getAttribute("key");System.out.println(key);}}
获取EE项目文件的绝对路径
servletContext.getRealPath(path)
利用这个API可以获取EE项目部署根目录下某个资源文件的绝对路径
如果里面输入的是空字符串,那么得到的是部署根目录的绝对路径;
如果希望获取部署根目录下面的某个文件的绝对路径,只需要指明它和部署根目录之间的相对路径关系即可。
比如再部署根目录中有一个1.html,
如果是WEB-INF/1.html,能不能获取到?
package com.cskaoyan.servlet.path;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;@WebServlet("/path")public class PathServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//想获取1.html文件流信息-----file信息//D:\apache-tomcat-8.5.37\bin\1.html// File file = new File("1.html");// file.createNewFile();// String path = file.getAbsolutePath();// System.out.println(path);// 问题1:为什么创建一个文件,会创建到tomcat的bin目录下//相对路径:JDK中关于相对路径的描述其实是相对的jvm的调用目录//ee项目本质上来说,就是我们写了很多的代码片段,来供服务器tomcat来调用//服务器会再bin目录下调用jvm,所以项目中相对路径相对的全部都是tomcat的bin目录//问题2:我们希望获取部署根目录下面的某个资源文件的流信息 file信息//servletContext可以给我们提供一个API,利用这个API可以获取到EE项目文件的绝对路径ServletContext servletContext = getServletContext();//如果里面什么参数都不输入,这个时候可以定位到应用部署根目录//如果你希望获取部署根目录下的任何一个文件的路径信息,只需要指明它和部署根目录之间的相对路径关系即可String realPath = servletContext.getRealPath("");System.out.println(realPath);}}
package com.cskaoyan.servlet.path;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;@WebServlet("/path")public class PathServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//想获取1.html文件流信息-----file信息//D:\apache-tomcat-8.5.37\bin\1.html// File file = new File("1.html");// file.createNewFile();// String path = file.getAbsolutePath();// System.out.println(path);// 问题1:为什么创建一个文件,会创建到tomcat的bin目录下//相对路径:JDK中关于相对路径的描述其实是相对的jvm的调用目录//ee项目本质上来说,就是我们写了很多的代码片段,来供服务器tomcat来调用//服务器会再bin目录下调用jvm,所以项目中相对路径相对的全部都是tomcat的bin目录//问题2:我们希望获取部署根目录下面的某个资源文件的流信息 file信息//servletContext可以给我们提供一个API,利用这个API可以获取到EE项目文件的绝对路径ServletContext servletContext = getServletContext();//如果里面什么参数都不输入,这个时候可以定位到应用部署根目录//如果你希望获取部署根目录下的任何一个文件的路径信息,只需要指明它和部署根目录之间的相对路径关系即可String realPath = servletContext.getRealPath("");System.out.println(realPath);String realPath1 = servletContext.getRealPath("1.html");boolean exists = new File(realPath1).exists();System.out.println(exists);//如果希望访问WEB-INF目录下的文件,可以访问到吗 可以获取到//注意WEB-INF屏蔽的是浏览器的直接访问,不是服务器;对于服务器来说,任何目录都是非常普通的目录String realPath2 = servletContext.getRealPath("WEB-INF/1.txt");boolean exists1 = new File(realPath2).exists();System.out.println(exists1);}}
