笔记
java Servlet是运行在web服务器或者应用服务器上的程序,
War文件 一个war文件包含一个web项目的文件,他可能有
Servlet、xml、jsp、image、html、js、css、json、properties等文件
什么是war文件 web存档(war)文件包含web应用程序的所有内容,他减少了传输文件所需要的时间
war文件的优点
- 节省时间:war文件将所有文件合并为一个文件,所以在从客户端传输到服务端时需要更少的时间
Servlet的工作模式 客户端发送请求到服务器
服务器启动并调用Servlet,Servlet根据客户端请求生成响应传给服务器
服务器响应给客户端
- 当服务器收到请求后,服务器检查Servlet
- 是否为第一次请求,如果是
- 加载Servlet类
- 实例化Servlet类
- 调用init方法传递ServletConfig对象
- 如果不是
- 调用Service方法并传递请求和响应对象
- Web容器在需要删除Servlet时调用destory方法,如关闭服务器,取消部署项目
-
将请求与web.xml中的Sefvlet进行映射
-
为请求创建请求对象或者响应对象
-
如果是第一次请求,则先调用init初始化方法,然后调用service方法
-
公共service方法调用内部受保护的service方法,并将请求和响应对象转换为http类型的,
- 如:ServletResponse->HttpServletResponse
-
受保护的service方法根据请求类型调用doXXX方法
-
doXXX方法生成响应,并将其传递给服务器
-
发送响应后,web容器将删除请求和响应对象,
注意:两个Service方法的区别
/** * 从service方法接收请求,并根据传入的http请求类型将请求发送到doXXX()方法。 * @param req 请求 * @param resp 响应 */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } /** * 通过将请求和响应对象转换为http类型后,将请求调度到受保护的service方法。 * @param req 请求 * @param res 响应 */ @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { super.service(req, res); }
公有的service方法将ServletReques对象转换为Http类型的,然后调用私有的Service方法
Servlet主要有4个jar包
javax.Servlet 其中包含定义Servlet和Servlet容器之间契约的类和接口
javax.servlet.http 其中包含了http servlet和Servle容器之间的关系
javax.Servlet.annotation 其中包含标注Servlet,Filter,Listener的标注,他还为被标注原件提供元数据
javax.Servlet.descriptor 其中包含提供程序化登录web应用程序的配置信息的类型
接口有:Servlet、ServletRequest、Servletresponse、ServletContext
ServletConfig、Filter、ServletDescriptor
抽象类:GenericServlet实现了Servlet
Servlet技术的核心是Servlet,它是所有Servlet类必须直接或者间接实现的一个接口。
在编写实现Servlet的Servlet类时,直接实现它。在扩展实现这个这个接口的类时,间接实现它
其中,init( ),service( ),destroy( )是Servlet生命周期的方法。
代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。Servlet容器(例如TomCat)会根据下面的规则来调用这三个方法:
1.init( ),当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,
但是这个方法在后续请求中不会在被Servlet容器调用。我们可以利用init( )方法来执行相应的初始化工作。
调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。
2.service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。就像人一样,需要不停的接受老板的指令并且“工作”。
第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,
然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。
3.destory,当要销毁Servlet时,Servlet容器就会调用这个方法。
在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。
Servlet接口
Servlet接口定义了Servlet和Servlet容器之间的契约,这个契约是:
Servlet容器将Servlet类载入内存、并产生Servlet实例和调用他的方法
注意:
在一个应用程序中每种Servlet类型只能有一个Servlet实例
-
Servlet接口有5个方法,3个生命周期方法和2个非生命周期方法
-
Servlet接口5中方法分别为:init、service、destroy是Servlet的生命周期方法,这些方法由web容器调用
方法 描述 public void init(ServletConfig config) Servlet的初始化函数,服务启动时调用 public ServletConfig getServletConfig() 返回ServletConfig对象 public void service(ServletRequest servletRequest, ServletResponse servletResponse) Servlet的服务方法,在init初始化后,只会调用这个方法,直到destory销毁,由web容器的每个请求调用 public String getServletInfo() 返回有关servlet的信息,如作者,版权,版本等。 public void destroy() 仅被调用一次,并且表明servlet正在被销毁
- ServletConfig接口获取的是当前Servlet的配置信息
- servletconfig对象是由每个servlet的web容器创建的,这个对象用于从web.xml中获取配置信息,获取的是该Servlet的配置信息
- 它是Servlet的init函数的参数,可以通过Servlet的 getServletConfig() 方法获得
方法 | 描述 |
---|---|
public String getInitParameter(String name) | 返回指定参数名称的参数值 |
public Enumeration getInitParameterNames() | 返回所有初始化参数名称的枚举。 |
public String getServletName() | 返回servlet的名称。 |
public ServletContext getServletContext() | 返回Srvletconfig对象 |
- ServletContext度下行由web服务器在部署项目时创建,该对象可用于从web.xml文件获取配置信息
- 每个web应用程序只有一个ServletContext对象,如果有信息要共享给多个servlet对象使用,最好在web.xml中使用content-param元素提供
- 同一个WEB应用程序中的所有Servlet共享同一个 ServletContext 对象(或者叫application对象)
- ServletContext获取的是当前web应用程序的配置信息
- 优点:
- 如果有任何信息要共享给所有的servlet使用,并且要让他容易维护,最好的办法就是在web.xml中提供这些信息,所以如果信息要修改,直接在web.xml中修改,而不需要修改servlet代码
- 作用
- ServletContext对象提供容器和Sevlet之间的接口
- 使用ServletContext对象在web.xml文件获取配置信息
- ServletContext对象可以用于程序间的通信
- ServletContext可以用于获取、设置、删除web.xml文件中的属性
- 因为有了ServletContext对象,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。前者将对象保存在ServletContext中的一个内部Map中
- 方法
方法 | 描述 |
---|---|
String getServletName(); | 返回Servlet的名称 |
Enumeration getInitParameterNames() | 返回所有初始化参数的枚举 |
String getInitParameter(String name) | 返回指定参数名称的参数值 |
getRealPath(String relativePath) | 由相对路径获取当前web应用的某一个文件在服务器上的绝对路径 |
getContextPath() | 返回Context的路径,返回请求上下文的请求URI部分,web应用的名称 |
getResourceAsStream(String path) | 获取当前web应用的某个文件对应的输入流,path一定要用相对于当前web应用根目录的路径 |
ServletContext getServletContext() | 返回ServletContext对象 |
setAttribute(String name,Object object) | 设置一个新的属性 |
Object getAttribute(String name) | 得到指定名称的属性的值 |
removeAttribute(String name) | 从servlet上下文中删除给定名称的属性 |
-
getContextPath()
-
例如:
http://localhost:8080/blue/response.jsp
-
例如:
http://localhost:8080/java_web_war/demo
request.getContextPath() 返回的就是 /blue和/java_web_war
-
-
getRealPath(String relativePath)
- context.getRealPath(“/”),返回的是
- D:\Tomcat\apache-tomcat-9.0.62\webapps\java_web_war\
- 由此可见,就是返回某一个文件在web服务器上的路径
-
GenericServlet类实现了Servlet、ServletConfig、Serializable接口
-
GenericServlet类可以处理任何类型的请求,因此他与协议无关
-
可以通过继承
GenericServlet
类并提供服务方法的实现来创建通用的`servlet -
其中,GenericServlet抽象类相比于直接实现Servlet接口,有以下几个好处:
- 为Servlet接口中的所有方法提供了默认的实现,需要什么就直接改什么,不再需要把所有的方法都自己实现
- 提供方法,包围SevletConfig对象中的方法
- 将jinit方法中的ServletConfig参数赋值给了一个内部的ServletConfigt对象,不需要自己去维护ServletConfig了
-
在GenericSevlet类中还有一个无参的init方法:
- GenericServlet是一个抽象类,抽象类是无法被直接实例化的,需要被继承,当继承的会后就会发生方法覆盖的问题,如果在类中覆盖了GenericServlet抽象类的init方法,那么就需要手动去维护ServletConfig对象了还得使用super.init(ServletConfig)方法去调用父类中的这个方法来保存ServletConfig对象,这样就会很麻烦,这个无参的init方法就是用来解决上述问题的
-
方法
方法 | 描述 |
---|---|
void log(String msg) | 在servlet日志文件中写入给定的消息。 |
void log(String msg,Throwable t) | 将说明性消息写入servlet日志文件和堆栈跟踪。 |
- HttpServlet抽象类继承了GenericServlet类
- HttpServletRequest接口继承了ServletRequest接口
- HttpServletResponse接口继承了ServletResponse接口
- 另外还有httpSession接口
-
HttpServlet类扩展了GenericServlet类并实现了serializable接口,它提供了http特定的方法
-
HttpServlet抽象类覆盖了GenericServlet抽象类中的Service( )方法,并且添加了一个自己独有的Service(HttpServletRequest request,HttpServletResponse方法。
-
HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象。之所以能够这样强制的转换,是因为在调用Servlet的Service方法时,Servlet容器总会传入一个HttpServletRequest对象和HttpServletResponse对象,预备使用HTTP。
-
转换之后,service方法把两个转换后的对象传入了另一个service方法
-
优点:
-
HttpServlet有两个特性是GenericServlet所不具备的:
1.不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。 2.使用的是HttpServletRequest和HttpServletResponse对象。
-
-
ServletRequest 和 ServletResponse 是service()的两个参数,其中 ServletRequest 封装了客户的请求信息,而 ServletResponse 将作为servlet的输出内容
-
HttpServletRequest 是ServletRequest的一个子接口,包含了大量可以获取HTTP请求相关的方法。它的实现也是由容器提供的
-
Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。
- 获取请求参数
方法 描述 String getParameter(String name) 根据请求参数的键返回请求参数的值,如果没有返回null,若有多个值,则只返回第一个 String[] getParameterValues(String name) 根据参数名字返回请求参数对应的字符串数组,如果没有返回null Enumeration getParameterNames() 返回所有参数名字的枚举 Map getParameterMap() 返回请求参数的键值对 getQueryString() 和get方法一起使用,返回?后的请求参数,如果dopost方法总调用则会返回null - 获取服务器信息
方法 描述 String getServerName() 获取服务器名字 int getServerPort 获取服务器端口号 get ServletPath() 获取服务器的访问地址,如/loginServlet - 获取客户端信息
方法 描述 String getRemoteAddr 获取客户端的ip地址 String getRemoteHost 获取客户端的主机名 - 获取请求头信息
方法 描述 getRequestURI() 获取请求url getRequestURL() 获取请求URL,URL包含URI,URI不包含站点信息 getMethod() 获取请求方式 getProtocol() 获取http协议的版本 getHeaderNames() 获取请求头的枚举 getHeader(name) 根据请求头的键获取值 Cookie[] getCookies(); 返回一个cookie对象数组 long getDateHeader(String name) Map getParameterMap() 获取请求参数映射的Map对象 - 获取session对象
HttpSession getSession();//返回与这个请求相关的会话对象
-
HttpServletResponse封装了响应信息
-
javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,
-
Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法
-
ServletResponse隐藏了向浏览器发送响应的复杂过程
- 在Service API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。 由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。
-
方法:
方法 描述 setContentType() 设置响应内容的类型 void addCookie(Cookie var1); 给响应头添加cookie void addHeader(String var1, String var2); 添加一个响应头 addIntHeader(String name, int value) addDateHeader(String name, long date) void sendRedirect(String var1) throws IOException; 发送一个响应码,浏览器将跳转到某处 void setStatus(int var1); 设置响应行的状态码 PrintWriter getWriter() 获得响应字符流 ServletOutputStream getOutputStream() 获得字节流 sendRedirect() 请求重定向 sendError(int sc) 发送一个错误状态码 -
响应内容类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eckBlw0g-1651480567443)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220420141954010.png)]
-
请求重定向
HttpServletResponse
接口的sendRedirect()
方法可以用于将响应重定向到另一个资源,资源可能是servlet
,jsp
或html
文件 - getWriter
- 获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
注意:虽然response对象的getOutSream ()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。
RequestDispatcher转发、请求分发-
代表的是请求的派发者
-
RequestDispatcher 实质是一个接口
-
Dispatcher有两个动作 forword和include,客户端对于 任何一个请求,可以根据不同的业务逻辑,选择不同的处理办法
- 请求的是谁,谁就自己处理并响应,当请求的是一个html页面,则web浏览器显示html页面的内容
- 使用RequestDispatcher可以让其他资源参与进来,协同完成响应,这是RequestDispatcher的主要作用
-
RequestDispatcher的特点:
- 浏览器上显示的url是最先请求的目标资源的URL,不会因为使用forword和include方法改变,
- 因此forword和include的调用对于用户来说是透明的
-
forword
- 这个方法将请求从一ge Servlet或者jsp目标资源上转发到服务器上的另一个资源(Servlet,jsp,html,资源必须是当前web上下文中的,并让其他的资源去响应生成数据)
-
include
- RequestDispatcher.include(request, response)调用者指定一个被包含的资源,将这个包含的资源(JSP,Servlet,HTML)的响应数据包含到自己的响应体中。被包含的数据是在服务器上经过运行产生的,因此是动态包含,而不同于JSP中的include指令,它是JSP转译期的静态包含
- 在响应中包含资源的内容(
servlet
,JSP
页面或HTML
文件)。
-
请求转发
-
sendRedirect()
- 转发和重定向的区别
-
地址栏变化
所以,如果想要在多个页面使用相同的request对象,那么只能使用转发,而不能使用重定向.
转发不会改变地址栏中的URL,而重定向则会改变
跳转范围
转发只能访问到当前web应用中的内容,而重定向则可以访问到任意web应用中的内容
request对象作用范围
转发后,在转发后的页面中仍然可以使用原来的request对象,而重定向,原来的request对象则失去作用
- 前面我们讲了,一个servlet在服务器中只会存在一个实例,不论是有多少访问,都掉用的同一个实例,也就是单实例多线程的.这就存在着一定的线程安全问题,比如说,我在servlet中定义了一个全局变量,那么这个变量的值很有可能不是我期待的值,所以,在servlet中要尽量避免使用全局变量.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)