1 http :超文本传输协议,是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,成熟的版本是HTTP1.0和1.1,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用
2 特点
支持客户端/服务器模式简单快速: 只需传送请求方式和路径,每种请求方式规定了客户端与服务器联系的类型不同灵活: HTTP 允许传输任意类型数据无状态: 对事物的处理没有记忆能力3 HTTP1.0/HTTP1.1
http 1.0 版本 http1.0 只有get/post/Head 这几种请求方式, 请求数据时, 客户端与服务端3次握手,然后建立tcp 链接,一个Tcp 链接只能传送一个请求和响应,响应结束后,关闭tcp 链接,下一次请求重新建立tcp 链接然后和上面一样
http 1.1 版本 http 1.1 新增了delete options 等几种请求数据的方式,客户端和服务端三次握手后,建立tcp 链接,一个tcp 链接 可以传送多个请求和响应,这样就减少了握手和建立tcp和关闭tcp链接的消耗,传输更快 http 1.1 支持持久链接 请求头有一个connection 参数,参数值是close/keep-alive 意思是本次请求处理完后,服务器是关闭该tcp链接还是继续使用该链接
4: HTTP消息:HTTP请求消息和HTTP响应消息
1:http请求由三部分组成,分别是:请求行、请求头、实体内容 请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下: Method Request-URI HTTP-Version CRLF 其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符) eg. GET http://baidu.com HTTP1.1请求方式有 GET 请求获取Request-URI所标识的资源POST 在Request-URI所标识的资源后附加新的数据HEAD 请求获取由Request-URI所标识的资源的响应消息报头PUT 请求服务器存储一个资源,并用Request-URI作为其标识DELETE 请求服务器删除Request-URI所标识的资源TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断CONNECT 保留将来使用OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求2: http请求头: 主要是向服务器传递附加消息,类如数据类型,压缩方法,语言等
参考博客:http请求头
2: HTTP响应消息:是由三个部分组成,分别是:状态行、响应消息头、响应正文状态行:有HTTP版本,一个表示成功或错误的整数代码,对状态码进行描述 格式: HTTP-Version Status-Code Reason-Phrase CRLF\
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述 状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求 常见错误有
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
常见错误 HTTP响应消息头
响应消息头
Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。 Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iCsbVDnL-1572505272055)(servlet基础http_files/无标题.png)]\
servlet的请求首先会被HTTP服务器(Apache)接受,HTTP服务器只负责静态HTML页面的解析,对于Servlet的请求转交给Servlet容器(tomcat),servlet容器会根据文件的映射关系,调用相应的Servlet,Servlet把相应的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端
特点
高效。在服务器上仅有一个Java虚拟机在运行,它的优势在于当多个来自客户端的请求进行访问时,Servlet为每个请求分配一个线程而不是进程。方便。Servlet提供了大量的实用工具例程,例如处理很难完成的HTML表单数据、读取和设置HTTP头、处理Cookie和跟踪会话等跨平台。Servlet是用Java类编写的,它可以在不同的操作系统平台和不同的应用服务器平台下运行。灵活性和可扩展性。采用Servlet开发的Web应用程序,由于Java类的继承性、构造函数等特点,使得其应用灵活,可随意扩展。共享数据。Servlet之间通过共享数据可以很容易地实现数据库连接池。它能方便地实现管理用户请求,简化Session和获取前一页面信息的操作。而在CGI之间通信则很差。由于每个CGI程序的调用都开始一个新的进程,调用间通信通常要通过文件进行,因而相当缓慢。同一台服务器上的不同CGI程序之间的通信也相当麻烦。安全。有些CGI版本有明显的安全弱点。即使是使用最新的标准和PERL等语言,系统也没有基本安全框架。而Java定义有完整的安全机制,包括SSL\CA认证、安全政策等规范。生命周期 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTLBaeAz-1572505272057)(servlet基础http_files/Image.png)] (1) 装载Servlet,这一项操作一般是动态执行的。然而,Servlet通常会提供一个管理的选项,用于在 Servlet启动时强制装载和初始化特定的Servlet (2) Server创建一个Servlet实例 (3) Server调用Servlet的init方法 (4) 一个客户端请求到达Server (5) Server创建一个请求对象 (6) Server创建一个响应对象 (7) Server激活Servlet的service方法,传递请求和响应对象作为参数 (8) service方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息 (9) service方法使用响应对象的方法。将响应传回Server,最终到达客户端。Service方法可能激活其他方法以处理请求。如doGet,doPost或其他程序员自己开发的方法 (10) 对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此servlet的service方法,将这两个对象作为参数传递给它,如此重复以上的循环,但无需再次调用init方法,Servlet一般只初始化一次 (11) 当Server不再需要Servlet时,比如当Server要关闭时,Server调用Servlet的Destroy()方法。(在Servlet整个生命周期中init(),destory()只被调用一次)
我们发现,HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象。之所以能够这样强制的转换,是因为在调用Servlet的Service方法时,Servlet容器总会传入一个HttpServletRequest对象和HttpServletResponse对象,预备使用HTTP。因此,转换类型当然不会出错了。 Service(HttpServletRequest request,HttpServletResponse)源码
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); long lastModified; if (method.equals("GET")) { lastModified = this.getLastModified(req); if (lastModified == -1L) { this.doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader("If-Modified-Since"); if (ifModifiedSince < lastModified) { this.maybeSetLastModified(resp, lastModified); this.doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("HEAD")) { lastModified = this.getLastModified(req); this.maybeSetLastModified(resp, lastModified); this.doHead(req, resp); } else if (method.equals("POST")) { this.doPost(req, resp); } else if (method.equals("PUT")) { this.doPut(req, resp); } else if (method.equals("DELETE")) { this.doDelete(req, resp); } else if (method.equals("OPTIONS")) { this.doOptions(req, resp); } else if (method.equals("TRACE")) { this.doTrace(req, resp); } else { String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[]{method}; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg); } }我们会发现在service方法中还是没有任何的服务逻辑,但是却在解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete。这7种方法中,每一种方法都表示一个Http方法。doGet和doPost是最常用的。所以,如果我们需要实现具体的服务逻辑,不再需要覆盖service方法了,只需要覆盖doGet或者doPost就好了。
1:根据用户请求方式的不同,重新相应的doXxx()方法 2: 通过 service(ServletRequest req, ServletResponse res)方法将请求和响应强转为HttpServletRequest, HttpServletResponse 类型对象
采用GET方式访问的有:直接输入某个URL或者单击网页上的超链接,如果将网页上的<form>标签的method设置为GET或则不设置(默认是get)当用户提交时是get方式传输\
采用post方式访问的有:,如果将网页上的<form>标签的method设置为post,当用户提交时是get方式传输
Servlet的多重映射是指同一个Servlet可以被映射成多个虚拟路径,客户端可以用多个路径实现对同一个Servlet路径的访问
配置多个<servlet-mapping>元素 <servlet-mapping> <servlet-name>myservlet03</servlet-name> <url-pattern>/myservlet03</url-pattern> </ servlet-mapping> <servlet-mapping> <servlet-name>myservlet03</servlet-name> <url-pattern>/myser03</url-pattern> </ servlet-mapping> <servlet-mapping> <servlet-name>myservlet03</servlet-name> <url-pattern>/my03</url-pattern> </ servlet-mapping>可以通过 http://localhost:8080/projecto3/myservlet03, http://localhost:8080/projecto3/myser03, http://localhost:8080/projecto3/myt03,访问同一个servlet
在一个<servlet-mapping>元素中配置多个,<url-pattern>子元素 <servlet-mapping> <servlet-name>myservlet03</servlet-name> <url-pattern>/myservlet03</url-pattern> <url-pattern>/my03</url-pattern> <url-pattern>/my3</url-pattern> </servlet-mapping>可以通过 http://localhost:8080/projecto3/myservlet03, http://localhost:8080/projecto3/myser03, http://localhost:8080/projecto3/myt03,访问同一个servlet
HttpServlet类继承了GenericServlet类,而GenericServlet类实现了ServletConfig接口
容器初始化一个Servlet类型的对象时,会为这个Servlet对象创建一个ServletConfig对象
ServletConfig对象中包含了Servlet的初始化参数信息
代表当前Servlet的配置信息,每一个Servlet都有其唯一对应的ServletConfig
ServletConfig对象还与ServletContext对象关联
ServletConfig接口中定义了以下方法:
◆String getInitParameter(String name):根据给定的初始化参数,返回匹配的初始化参数值。 ◆ Enumeration getInitParameterNames():返回一个Enumeration对象,该对象包含了所有存放在web.xml中<web-app>元素<servlet>子元素<init-param>中的所有的初始化参数名。 ◆ServletContent getServletContext():返回一个servletContext()对象, ◆ Sting getServltName():返回servlet的名字,即web.xml中的相对应的servlet的子元素<servlet-name>的值。如果没有配置这个子元素,则返回servlet类的全局限定名。结果
encoding:UTF-8 encoding:UTF-8当tomcat启动时,会为每个web应用创建一个唯一的ServletContext对象代表当前Web应用.该对象不仅封装了当前web应用的所有信息,而且实现了多个servlet的数据共享。\
在每个项目中可以有多个Servlet程序,每个Servlet程序都是独立的。Servlet中的配置信息可以使用ServletConfig获取,而当前这个项目的配置信息,就必须使用描述这个项目的ServletContext对象获取。 常用方法
public Object getAttribute(String name); 返回 Servlet 环境对象中指定的属性对象。如果该属性对象不存在,返回空值。这个方法允许访问有关这个 Servlet 引擎的在该接口的其他方法中尚未提供的附加信息。
public Enumeration getAttributeNames(); 返回一个 Servlet 环境对象中可用的属性名的列表。
public void setAttribute(String name, Object o); 给予 Servlet 环境对象中你所指定的对象一个名称。
public void removeAttribute(String name); 从指定的 Servlet 环境对象中删除一个属性。
public String getRealPath(String path); 一个符合 URL 路径格式的指定的虚拟路径的格式是: /dir/dir/filename.ext。 用这个方法 ,可以返回与一个符合该格式的虚拟路径相对应 的真实路径的 String。这个真实路径的格式应该适合于运行这个 Servlet 引擎的计算机(包括其相应的路径解析器) 。 不管是什么原因, 如果这一从虚拟路径转换成实际路径的过程不能执行, 该方法将会返回一个空值。
public URL getResource(String uripath); 返回一个 URL 对象,该对象反映位于给定的 URL 地址(格式:/dir/dir/filename.ext ) 的Servlet 环境对象已知的资源。 无论 URLStreamHandlers 对于访问给定的环境是不是必须的 ,Servlet 引擎都必须执行。如果给定的路径的 Servlet 环境没有已知的资 源,该方法会返回一个空值。这个方法和 java.lang.Class 的 getResource 方法不完全相同。 java.lang.Class 的 getResource 方法通过装载类来寻找资源。而这个方法允许服务器产生环境变量给任何资源的任何 Servlet, 而不必依赖于装载类、特定区域等等。
public InputStream getResourceAsStream(String uripath); 返回一个 InputStream 对象,该对象引用指定的 URL 的 Servlet 环境对象的内容。如果没找到 Servlet 环境变量,就会返回空值,URL 路径应该具有这种格式:/dir/dir/filename.ext 。这个方法是一个通过 * getResource 方法获得 URL 对象的方便的途径。请注意,当你使用这个方法时,meta-information(例如内容长度、内容类型)会丢失。
乱序输出,因为servletContext.getInitParameterNames()的返回值是一个枚举类型的迭代器Enumeration
参考博客
参考博客
参考博客