栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

关于Servlet总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于Servlet总结

1. Servlet 1.1 什么是servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和生成数据,生成动态Web内容。**(百度百科的解释)

1.2 Servlet工作流程

1.3 Servlet 接口中定义的方法
public interface Servlet {
    void init(ServletConfig var1) throws ServletException;  // servlet初始化方法

    ServletConfig getServletConfig(); 

    void service(ServletRequest var1, ServletResponse var2) 
    throws ServletException, IOException;  // servlet调用service()方法处理客户端请求

    String getServletInfo();

    void destroy(); // servlet销毁
}
1.4 Servlet 的工作原理

首先应该了解Tomcat,Tomcat 是Web应用服务器,是一个Servlet/JSP容器。 Tomcat 作为Servlet容器,负责处理客户端请求,把请求传送给Servlet,并将Servlet的响应传送回给客户端。

Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。但是要注意的是,在一个应用程序中,每种Servlet类型只能有一个实例。

用户请求使Servlet容器调用Servlet的Service()方法,并传入一个ServletRequest对象和一个ServletResponse对象。ServletRequest中封装了当前的Http请求,因此,开发人员不必解析和操作原始的Http数据。ServletResponse表示当前用户的Http响应,程序员只需直接操作ServletResponse对象就能把响应轻松的发回给用户。

对于每一个应用程序,Servlet容器还会创建一个ServletContext对象。ServletContext:全局作用域对象。

这个对象中封装了上下文(应用程序)的环境详情。每个应用程序只有一个ServletContext。每个Servlet对象也都有一个封装Servlet配置的ServletConfig对象。

1.5 Servlet 的生命周期

init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。

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容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。

1.6 web.xml中load-on-startup的作用

我们在web.xml中配置servlet的时候会有个属性

  1. load-on-startup 元素标记容器是否应该在web应用程序启动的时候就加载这个servlet,(实例化并调用其init()方法)。
  2. 它的值必须是一个整数,表示servlet被加载的先后顺序。
  3. 如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。
  4. 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。

为什么需要映射?

我们写的是Java程序,但是要通过浏览器(客户端)访问,而浏览器(客户端)需要请求访问web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给一个浏览器能够访问的路径。

1.7 为什么创建的servlet是继承自httpServlet,而不是直接实现Servlet接口?

查看源码,httpServlet的继承结构。

httpServlet继承GenericServlet。懂的人就应该知道,GenericServlet(通用Servlet)的作用是什么?大概的就是将实现Servlet接口的方法,简化编写servlet的步骤,一句话就是简化开发。GenericServlet内的方法如下:

Servlet接口中的内容和作用,总结起来就是,三个生命周期运行的方法,获取ServletConfig,而通过ServletConfig又可以获取到ServletContext。

而GenericServlet实现了Servlet接口后,也就说明我们可以直接继承GenericServlet,就可以使用上面我们所介绍Servlet接口中的那几个方法了,能拿到ServletConfig,也可以拿到ServletContext,不过那样太麻烦,不能直接获取ServletContext,所以GenericServlet除了实现Servlet接口外,还实现了ServletConfig接口,那样,就可以直接获取ServletContext了。

在GenericServlet类中并没有实现service()方法,那么我们想到的是,也就是还有一个子类继承它,实现该方法,要是让我们自己写的Servlet继承GenericServlet,需要自己写service方法,那岂不是累死,并且我们可以看到,service方法中的参数还是ServletRequest,ServletResponse。并没有跟http相关对象挂钩,所以我们接着看 HttpServlet。

HttpServlet继承了GenericServlet类,通过我们上面的推测,这个类主要的功能肯定是实现service方法的各种细节和设计。

看下HttpServlet里面的service方法的实现:

这个方法就是判断浏览器过来的请求方式是哪种,每种的处理方式不一样,我们常用的就是get,post,并且,我们处理的方式可能有很多的内容,所以,在该方法内会将get,post等其他5种请求方式提取出来,变成单个的方法,然后我们需要编写servlet时,就可以直接重写doGet或者doPost方法就行了,而不是重写service方法,更加有针对性。所以这里就回到了我们上面编写servlet时的情况,继承httpServlet,而只要重写两个方法,一个doGet,一个doPost,其实就是service方法会调用这两个方法中的一个(看请求方式)。

1.8 Servlet具体开发步骤
  1. 通过继承HttpServlet父类来创建一个Servlet接口实现类

    类 extends HttpServlet implements Servlet

  2. 根据浏览器发送的请求方式,重写父类中doGet或者doPost方法来处理请求

  3. 到网站的核心配置文件(web.xml)向Tomcat注册动态资源文件

2. ServletConfig
getServletName();  //获取servlet的名称,也就是我们在web.xml中配置的servlet-name

getServletContext(); //获取ServletContext对象,该对象的作用看下面讲解

getInitParameter(String); 
//获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的只是在该servlet下的初始化参数

getInitParameterNames();
 //获取在Servlet中所有初始化参数的名字,也就是key值,可以通过key值,来找到各个初始化参数的value值。注意返回的是枚举类型

3. ServletContext

tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web配置公共信息等,通俗点讲,就是一个web项目,就存在一个ServletContext实例,每个Servlet读可以访问到它。

ServletContext实例包含了所有servlet共享的资源信息。通过提供一组方法给servlet使用,用来和servlet容器通讯,比如获取文件的MIME类型、分发请求、记录日志等。

  1. web项目中共享数据
Object getAttribute(String var1);//通过指定名称获得内容
Enumeration getAttributeNames();
void setAttribute(String var1, Object var2); 
//在web项目范围内存放内容,以便让在web项目中所有的servlet读能访问到

void removeAttribute(String var1);//通过指定名称移除内容

应用的属性相关操作,这里需要讲的是setAttribute,当设置的属性名已经存在,则会替换掉就的属性值。如果设置属性值为null,那么效果和removeAttribute是一样的。这些属性都是应用级的,在一个地方设置的属性可以被应用中其他地方使用。

  1. 整个web项目初始化参数
//这个就是全局初始化参数,每个Servlet中都能获取到该初始化值
String getInitParameter(String var1);//通过指定名称获取初始化值

Enumeration getInitParameterNames(); //获得枚举类型

web.xml 配置 整个web项目的初始化

  1. 获取web项目资源
String getRealPath(String var1); // 获取web项目下指定资源的路径

InputStream getResourceAsStream(String var1);//获取web项目下指定资源的内容,返回的是字节输入流
  1. 获取指定路径下的所有内容。
Set getResourcePaths(java.lang.String path) //获取指定路径下的所有内容。

这些都是常用的,当然ServletContext源码里面不止这些。ServletContext是容器和应用沟通的桥梁,从一定程度上讲ServletContext就是servlet规范的体现。

4. post请求和get请求的区别
GET请求方式:

1) 要求浏览器发送请求时,携带的【请求参数数量】不能超过4K
2) 要求浏览器发送请求时,必须在浏览器地址栏上将【请求参数信息】展示出来
3) 要求浏览器发送请求时,必须将请求参数信息保存在Http请求协议包中【请求头】
4) 要求浏览器在接收到服务器返回的资源文件内容后,必须将资源文件内容保存在浏览器的缓存

POST请求方式:
1)要求浏览器发送请求时,可以携带任意数量的【请求参数】
2)要求浏览器发送请求时,必须在浏览器地址栏上隐藏请求参数信息
3)要求浏览器发送请求时,必须将请求参数信息保存在Http请求协议包中【请求体】
4)禁止浏览器将服务器返回资源文件内容进行保存【阅后即焚】
5. HTTP协议请求与响应的结构 HTTP请求报文

请求报文的构成

如果是GET请求,请求体为空,如果是POST请求,请求体可以不为空。

HTTP响应报文

HTTP响应格式

响应报文的构成

6. 请求转发和重定向 重定向解决方案

1.工作原理: 用户第一次通过【手动方式】通知浏览器访问OneServlet。OneServlet工作完毕后,将TwoServlet地址写入到响应头location属性中,导致Tomcat将302状态码写入到状态行。

在浏览器接收到响应包之后,会读取到302状态。此时浏览器自动根据响应头中location属性地址发起第二次请求,访问TwoServlet去完成请求中剩余任务

2.实现命令:

response.sendRedirect("请求地址") //将地址写入到响应包中响应头中location属性

3.特征:

  1. 请求地址:
    既可以把当前网站内部的资源文件地址发送给浏览器 (/网站名/资源文件名)
    也可以把其他网站资源文件地址发送给浏览器(http://ip地址:端口号/网站名/资源文件名)

  2. 请求次数

浏览器至少发送两次请求,但是只有第一次请求是用户手动发送。
后续请求都是浏览器自动发送的。

  1. 请求方式:
    重定向解决方案中,通过地址栏通知浏览器发起下一次请求,因此通过重定向解决方案调用的资源文件接收的请求方式一定是【GET】

4.缺点:
重定向解决方案需要在浏览器与服务器之间进行多次往返,大量时间
消耗在往返次数上,增加用户等待服务时间

请求转发解决方案

1.原理:用户第一次通过手动方式要求浏览器访问OneServlet。OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet。Tomcat在接收到这个请求之后,自动调用TwoServlet来完成剩余任务

2.实现命令: 请求对象代替浏览器向Tomcat发送请求

//1.通过当前请求对象生成资源文件申请报告对象
RequestDispatcher  report = request.getRequestDispatcher("/资源文件名");// 一定要以"/"为开头
//2.将报告对象发送给Tomcat
report.forward(当前请求对象,当前响应对象)

共享资源文件分为两种:静态资源文件 与  动态资源文件
静态资源文件指的是文件内容相对固定,所有用户来访问时看到的内容都是一样的文件。
比如。HTML文件,图片文件,视频文件。
静态资源文件被访问时,服务端的资源文件调度器负责将文件内容读取出来,然后解析为二进制数据通过网络交给浏览器,
而浏览器接收后通过其内置的编译器来解释执行。
    
动态资源文件指的是文件内容可以根据用户请求不同而产生不同的变化。比如 Java中class文件。
动态资源文件(class)在被访问时,服务端的资源文件调度器是不会将class文件推送到浏览器的。
因为浏览器没有JVM无法解析执行class文件内容。
服务端的资源文件调度器会负责创建class类的实例对象,然后通过实例对象调用对应的方法处理业务。
然后将方法的处理结果作为二进制数据通过网络推送回发起请求浏览器上。

3.优点:

  1. 无论本次请求涉及到多少个Servlet,用户只需要手动通过浏览器发送一次请求
  1. Servlet之间调用发生在服务端计算机上,节省服务端与浏览器之间往返次数,增加处理服务速度

4.特征:

  1. 请求次数

    在请求转发过程中,浏览器只发送一次请求

  2. 请求地址
    只能向Tomcat服务器申请调用当前网站下资源文件地址
    request.getRequestDispathcer("/资源文件名")

  3. 请求方式

    在请求转发过程中,浏览器只发送一个了个Http请求协议包。
    参与本次请求的所有Servlet共享同一个请求协议包,因此这些Servlet接收的请求方式与浏览器发送的请求方式保持一致

请求转发和重定向的区别
1. 请求转发是一个请求一次响应,而重定向是两次请求两次响应。
2. 请求转发地址不变化,而重定向会显示后一个请求的地址。这是因为请求转发是服务器的行为,是由容器控制的转向,整个过程处于同一个请求中,因此客户端浏览器不会显示转向后的地址;但重定向是客户端的行为,重新发送了请求,整个过程不在同一个请求中,因此客户端浏览器会显示跳转后的地址。
3. 请求转发只能转发到本项目其它Servlet,而重定向不只能重定向到本项目的其它Servlet,还能定向到其它项目。
4. 请求转发是服务端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,既包含项目名。
7. HttpServletRequest HttpServletRequest介绍

公共接口类HttpServletRequest继承自ServletRequest。客户端览器发出的请求被封装成为一个HttpServletRequest对象。对象包含了客户端请求信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。

Request常用方法 1. 获得客户机信息
getRequestURL 	//方法返回客户端发出请求时的完整URL。
getRequestURI   //方法返回请求行中的资源名部分。
getQueryString  //方法返回请求行中的参数部分。
getPathInfo     //方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
getRemoteAddr   //方法返回发出请求的客户机的IP地址。
    // 可以使用request.getRemoteAddr()方法获取客户端的IP地址,然后判断IP是否为禁用IP。这种方式可以很方便的对多次密码的用户处理。
getRemoteHost   //方法返回发出请求的客户机的完整主机名。
getRemotePort   //方法返回客户机所使用的网络端口号。
getLocalAddr    //方法返回WEB服务器的IP地址。
getLocalName    //方法返回WEB服务器的主机名。
2. 获得客户机请求头
getHeader(String name) // 方法:String 根据请求头的名字获取对应的请求头的值
getHeaders(String name) //方法:Enumeration
getHeaderNames()       //方法 获取所有的请求头
3. 获得客户机请求参数(客户端提交的数据)
getParameter(String name) // 方法(常用) 根据name返回请求参数信息
getParameterValues(String name) // 方法(常用) 返回name请求参数列表(数组形式)
getParameterNames() // 方法(不常用)  返回请求参数的name属性
getParameterMap() // 返回的是一个Map类型的值,该返回值记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。(编写框架时常用)
4.获取HttpSession会话作用域对象
request.getSession(true)  // 若存在会话则返回该会话,否则新建一个会话。
request.getSession(false) // 若存在会话则返回该会话,否则返回NULL
5.获取cookie对象
cookie[] getcookies(); // 返回cookie对象数组
6.获取RequestDispatcher对象
RequestDispatcher getRequestDispatcher(String var1)
getRequestDispatcher()包含两个重要方法,分别是请求转发和请求包含。
    

请求转发

由下一个Servlet完成响应体,当前Servlet可以设置响应头(留头不留体)。举个例子,AServlet请求转发到BServlet,那么AServlet不能够使用response.getWriter() 和response.getOutputStream()向客户端输出响应体,但可以使用response.setContentType(“text/html;charset=utf-8”) 设置响应头。而在BServlet中可以输出响应体。

上图是请求转发的流程,最后返给客户端的response只是BServlet的,而AServlet的响应不会在客户端显示出来。

请求包含

由两个Servlet共同完成响应体(留头又留体)。同样用上面的例子,AServlet请求包含到BServlet,那么AServlet既可以设置响应头,也可以完成响应体。

上图是请求包含流程,因为BServelt的响应返回给AServlet时携带了responseB,所以AServlet的响应中包含了BServlet的响应,最后返给客户端的响应是两者之和。

7.获取ServletContext对象
ServletContext getServletContext();
8. HttpServletResponse HttpServletResponse对象介绍

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

Response常用方法 1. 负责向客户端(浏览器)发送数据的相关方法
getOutputStream()	// 该方法用于返回Servlet引擎创建的字节输出流对象,Servlet程序可以按字节形式输出响应正文。
getWriter()			// 该方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。
    
注意:
1.getOutputStream()和getWriter()这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

2.getOutputStream()返回的字节输出流对象,类型为:ServletOutputStream,直接输出字节数组中的二进制数据。

3.getWriter()方法将Servlet引擎的数据缓冲区包装成:PrintWriter类型的字符输出流对象后返回,PrintWriter对象只能输出字符文本内容。
2. 负责向客户端(浏览器)发送响应头的相关方法
addDateHeader(String name ,long date)	// 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
addHeader(String name,String value)		// 该方法是设置有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值
addIntHeader(String name,int value)		// 该方法是设置有多个值且值的类型为int类型的响应头
setHeader(String name,String value)		// 该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值
setDateHeader(String name,long value)	// 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
setIntHeader(String name,int value)		// 该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数
        
//设置Content-Type响应头
resp.setHeader("Content-Type","text/html;charset=utf-8");
//添加一个响应头:xxx是表示某一响应头
resp.addHeader("xxx", "123");
//通知客户端响应内容长度为888个字节
resp.setIntHeader("Context-Length", 5);
//设置过期时间为:5000毫秒
resp.setDateHeader("", 5000);
3. 负责向客户端(浏览器)发送响应状态码的相关方法
setStatus(int value)	// 设置临时定向响应码
void sendError(int var1, String var2) throws IOException;
void sendError(int var1) throws IOException;
// 使用指定的状态码向客户端但会一个错误响应,并且清空缓存区

// 执行response.sendError(500)时
// 设置错误码对应的错误页面

  500
  /index.jsp


4. 响应状态码的常量

HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:

SC_NOT_FOUND	// 状态码404对应的常量
SC_OK			// 状态码200对应的常量
SC_INIERNAL_SERVER_ERROR	// 状态码500对应的常量
5. 设置响应头控制浏览器的行为
1.定时刷新页面
response.setHeader("refresh", "5"); // 设置refresh响应头控制浏览器每隔5秒钟刷新一次
2.禁止缓存当前文档内容
response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
6 .重定向

什么是重定向?

一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。

public class RedirectResponse extends HttpServlet{
 
    private static final long serialVersionUID = 3903946972744326948L;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //endRedirect方法实现请求重定向
        resp.sendRedirect(req.getContextPath() + "/index.jsp");
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号