服务器概述

JavaWeb的软件服务器的分类

  1. http服务器,用于运行静态的网页(html)
  2. Web服务器,实现了JavaEE部分规范(比如Servlet/JSP),没有实现 JavaEE 中的 EJB 规范.
  • 如:Tomcat(java 代码写的,开源的服务器),Jetty 等.
  1. 应用服务器,实现了 JavaEE 全部的规范,支持 EJB 的.
  • 如:TomEE,GlassFish,JBoss,Weblogic,WebSphere

Servlet 容器为 JavaWeb 应用提供运行时环境,主要负责

  1. 管理 Servlet 和 JSP 的生命周期(服务器帮助我们管理sevlet)
  2. 管理 Servlet 之间的共享数据。(共享作用域)

Servlet 容器也称为 JavaWeb 容器,或者 Servlet/JSP 容器

Tomcat

是一个软件,也称Servlet容器,JavaWeb容器,Servlet/JSP容器

安装

Tomcat是使用Java语言编写的一个服务器(程序),要运行Tomcat,必须得有jre
安装启动

  1. 版本选择
  • 32位的JDK —->32位的Eclipse—->32位Tomcat
  • 64位的JDK —->64位的Eclipse—->64位Tomcat
  1. 安装目录不能使中文的,并且安装路径不允许出现空格
  • 如:D:\OpenSources\Tomcat7\apache-tomcat-7.0.42,该路径称之为Tomcat的根路径
  1. 通过脚本启动 Tomcat 服务器:Tomcat根路径/bin/startup.bat
  • 必须先配置 JAVA_HOME 或者 JRE_HOME 的环境变量
  • 一般的我们只配置JAVA_HOME:JAVA_HOME=D:\OpenSources\jdk1.7.0_06_x86
  • 配置好之后,再点击 Tomcat根路径/bin/startup.bat,如果控制台没有打印重大的错误,没有一闪而过,就表示启动成功
  • Tomcat的默认端口是8080:

    访问

    协议://ip:端口/资源

  • http://服务器所在主机的IP:服务器的端口号/资源名字

若服务在本机:[http://localhost:8080/index.jsp](http://localhost:8080/index.jsp)

  • http://localhost:服务器的端口号/资源名字

    常见错误

  1. 没有成功启动Tomcat,就开始访问:无法显示此网页。查看服务是否启动成功
  2. 出现404的错误提示:HTTP Status 404
  • 当前访问的资源不存在的时候,就报404错误
  • 此时的问题,是我们自己造成的,把资源的名字写错了,或者说根本就没有此资源
  1. Tomcat成功启动之后,再去启动当前的Tomcat:Tomcat的端口已经被占用,端口冲突
  2. 如果改动了 tomcat 配置文件,想要生效,必须重启:查看日志文件,找到错误的位置,错误原因—->再修改
  3. 在XML配置文件中使用了中文,此时XML文件必须使用UTF-8的编码:XML文件: 文件内容的编码和文件本身编码要相同,都为UTF-8

    —->1 字节的 UTF-8 序列的字节 1 无效

    javaweb 项目的配置文件格式

    image.png
    直接属于根的文件,浏览器可以直接通过 **协议://ip:端口/资源名** 访问
    注意

  4. WEB-INF(大写,符号是中线)

  5. classes 一定要配置成字节码输出路径
  6. 需要使用的 jar 包,一定要放在 lib 中

    HTTP

    特点

  7. 无状态 —-> 不会记录历史访问信息,每次请求什么,就响应什么 —-> 一问一答

  8. 默认端口就是80

定义

  1. web浏览器与web服务器之间的一问一答的交互过程必须遵循一定的规则,就是HTTP协议。
  2. HTTP 是 hypertext transfer protocol(超文本传输协议)的简写,它是 TCP/IP 协议之上的一个应用层协议
  3. 定义了WEB浏览器与WEB服务器之间交换数据的过程以及数据本身的格式

约束了什么

  1. 约束了浏览器以何种格式向服务端发送数据
  2. 约束了服务器应该以何种格式来接受客户端发送的数据
  3. 约束了服务器应该以何种格式来反馈数据给浏览器
  4. 约束了浏览器应该以何种格式来接收服务器反馈的数据

版本
HTTP1.0规范:
主要内容

  1. 若请求的有N个资源,得建立N次连接,发送N次请求,接收N次响应,关闭N次连接.
  2. 每次请求的之间都要建立单独的连接,请求,响应,响应完关闭该次连接:

缺点

  • 每请求一个资源都要单独的建立新的连接,请求完并关闭连接.

解决方案

  • 在一次连接之间,多次请求,多次响应,响应完之后再关闭连接.

HTTP1.1规范:
主要内容:

  • 能在一次连接之间多次请求,多次响应,响应完之后再关闭连接.

特点

  • 在一个TCP连接上可以传送多个HTTP请求和响应
  • 多个请求和响应过程可以重叠进行
  • 增加了更多的请求头和响应头

浏览器给服务器发送数据

  • 一次请求:request

服务器给浏览器反馈数据

  • 一次响应:response

image.png
HTTP协议的版本:

  • HTTP/1.0、HTTP/1.1、HTTPS2.0.

请求消息 request

是浏览器给服务器发送的一些消息
image.png
包含三大部分

  1. 请求行:位于请求消息的第一行
  • 格式:请求方式 资源路径 HTTP版本号
  • 常用请求方式:GET和POST方式
    • Get请求方式
      • 若请求服务器上的某个资源,没有指定请求方式,则默认为GET方式
      • 可以通过GET方式向服务器传递数据。具体方式就是在URL请求路径后加上 ?,多个参数以 & 分割。
      • 比如 http://localhost:8080/a.html?username=abc&password=123
      • 注:GET请求方式,数据不安全且有URL长度限制(1K)
    • Post请求方式
      • 若使用Post请求方式传递数据,可以借助 form 表单的 method="post"
      • 数据相对安全,且长度没有限制
  1. 若干请求头:从第二行开始到下一个空行。作用:向服务器传递客户端的一些基本信息
  • Accept:浏览器可接受的MIME类型(正文内容类型)(Tomcat安装目录/conf/web.xml中查找)
  • Accept-Charset:告知服务器,浏览器支持哪种字符集
  • Accept-Encoding:浏览器能够进行解码的数据编码方式
  • Accept-Language:浏览器支持的语言。
  • Referer:当前页面由哪个页面访问过来的。
  • Content-Type:通知服务器,请求正文的MIME类型。是数据传输的编码格式
    • application/x-www-form-urlencoded
      • 默认值
      • 对应 form 表单的 enctype 属性
    • application/json;charset=UTF-8
      • 对应内容为 json 字符串
  • Content-Length:请求正文的长度
  • If-Modified-Since:通知服务器,缓存的文件的最后修改时间。
  • User-Agent:通知服务器,浏览器类型。针对不同的浏览器做兼容。
  • Connection:表示是否需要持久连接。如果服务器看到这里的值为“Keep -Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接
  • Cookie:这是最重要的请求头信息之一(会话有关)
  1. 请求实体:从第一个空行开始,后面的都是正文。(可以没有,GET方式就没有),只有POST请求才有请求实体

    响应消息 response

    服务器给浏览器的反馈信息
    image.png
    包含三大部分

  2. 响应行:位于响应消息的第一行

  • 格式: HTTP版本号 状态码 
  1. 若干响应头:从第二行开始到第一个空行
  • Location:指定转发的地址。需与302/307响应码一同使用
  • Server:告知客户端,服务器使用的容器类型 —-> Apache-Coyote/1.1
  • Content-Encoding:告知客户端,服务器发送的数据所采用的压缩格式
  • Content-Length:告知客户端正文的长度
  • Content-Type:告知客户端正文的MIME类型 —-> text/html、application/json
  • Conent-Type:text/html;charset=UTF-8
  • Refresh:定期刷新。还可以刷新到其他资源
    • Refresh:3;URL=otherurl
      • 3秒后刷新到otherurl这个页面
  • Content-Disposition:指示客户端以下载的方式保存文件。
    • Content-Disposition:attachment;filename=2.jpg
  • Expires:网页的有效时间。单位是毫秒(等于-1时表示页面立即过期)
  • Cache-Control:no-cache
  • Pragma:no-cache
    • 控制客户端不要缓存
  • Set-Cookie:SS=Q0=5Lb_nQ; path=/search服务器端发送的Cookie(会话有关)
  1. 响应实体:从第一个空行开始,后面的都是正文。调试器做了切割,单独放到响应标签中

MIME
MIME的英文全称是”Multipurpose Internet Mail Extensions” 多用途互联网邮件扩展
服务器会将它们发送的多媒体数据的类型告诉浏览器
MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型

GET和POST请求的区别

  1. GET的请求数据在地址栏,而POST不会.
  • POST比GET安全一些.
  1. POST请求的参数存放于请求实体中,而GET存放于请求行中
  2. GET方式请求的数据不能超过2K,而POST没有上限
  • 比如文件上传时,必须使用POST方式
  1. GET可以缓存,而POST没有缓存

什么时候使用get,什么时候使用post

  • 查询的时候使用使用GET,其他时候使用POST
  • 表单全部使用POST提交

发送请求的位置:

  1. 浏览器地址栏
  2. 链接的其他资源(js/css/图片)
  3. 超链接
  4. 表单提交

默认使用GET方式的地方

  1. 直接在浏览器地址栏敲回车
  2. 超链接
  3. 只有表单中使用 method=post,才是POST方式

从浏览器到服务器的响应的整个过程

  1. 在浏览器中,输入一个url地址,解析出来url的ip和端口,ip用来定位主机,端口用来定位程序
  • www.haniel.cn ——-> 变成一个ip.
  1. 建立浏览器和服务器的TCP连接
  • 三次握手.
  1. 浏览器通过端口找到服务器端的指定的程序,发送请求信息
  • 要访问该程序的资源,请求头,请求参数====>HTTP协议
  1. 通过请求信息,处理业务逻辑
  • 如果仅仅是访问一个静态的资源,直接给浏览器把资源以流的形式响应回去.
  • 如果是动态资源(通过java代码获取出来的数据),先在服务器中使用java代码,完成功能.返回一个界面,界面中包含动态的数据.
  1. 遵循HTTP协议,把数据响应给浏览器
  • 响应行,响应头,响应实体(HTML界面)
  1. 浏览器获取到响应信息,去解析
  • MIME:text/html. image/gif,浏览器的渲染.
  1. 这次请求结束之后,会保持一定的时间的连接. 超过连接时间,断开连接,下一次请求需要重新执行上面的步骤

    servlet

    必要性
  • 现在的web开发,只能给浏览器提供一些静态的资源(html,js,css….) —> 响应静态的数据
  • 需要 Servlet 来接收请求(参数),执行逻辑处理,返回对应的数据 —> 响应动态的数据 (数字、json、文件。。。)
  • 对请求进行跳转、重定向等操作

定义

  • Servlet(Server Applet)是 Java Servlet 的简称,称为服务小程序或服务连接器
  • 用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据Servlet可以响应请求,生成动态Web内容
  • 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
  • Servlet运行于支持Java的web应用服务器中
  • 从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器

结论

  1. servlet是用于生成动态的web的组件.是javaEE的一种规范.
  2. servlet也是服务器的一种资源,也可以供外界去访问.
  3. 静态资源可以直接返回给浏览器,但是如果要访问动态的资源,需要servlet(java的一个类)去执行某一些方法(获取WEB-INF中的信息). 再给浏览器返回

image.png

创建第一个servlet程序

  1. 往javaweb项目中导入jar包(javaee不是javaSE范畴,不在jdk中,因此需要导入Tomcat中实现servlet接口的包))
  2. 定义一个类,实现 **javax.servlet.Servlet** 接口
  • XxxServlet: Xxx表示是什么功能 —-> StudentListServlet
  1. 复写接口中的抽象方法
  2. 关联servlet的源码,可以看到正规的变量名
  3. 在 servlet 的 service 方法中打印一句话
  4. servlet是服务器的一个资源,必须要交给服务器去管理(Tomcat)
  • 在当前应用的web.xml中,将该servlet实现类配置成一个外界可以访问的资源.
    • <servlet> 标签中,配置的是该服务器运行的是哪个Servlet实现类,写的是该实现类的全限定类名
    • <servlet-mapping> 标签,配置的是在浏览器中该资源的名字,既 协议://ip:端口/资源名 中的部分
    • 这两个标签,由 <servlet-name> 子标签串联起来,通常为Servlet实现类的简单名

image.png

  1. 不要忘记部署应用

Servlet生命周期
生命周期时长

  • 从出生-> 死亡的过程

Servlet 的生命周期

  • 从创建对象,初始化,执行操作,销毁的过程

生命周期管理

  • Servlet 的生命周期由服务器 Tomcat 来管理调用
  • Servlet 的创建对象,初始化,执行操作,销毁 都是由 Tomcat 来管理调用.

Servlet接口中的方法

public void init(ServletConfig config) 初始化方法
public ServletConfig getServletConfig() 获取当前 Servlet 的配置信息,既存放在web.xml中的配置信息
public void service(...) 做执行操作的方法,最主要的方法
String getServletInfo() 返回作者,版权信息,版本信息(没什么作用)
public void destroy() 销毁方法,不一定能调用到(正常关闭才会执行)不要写扫尾工作的代码

注意

  • Servlet 在整个生命周期(Tomcat 启动-> Tomcat 的关闭)中是单例的.
  • 既: 只会在第一次连接时创建一个 config 对象,后面再连接,会从Tomcat的缓冲池中找出以前创建过的对象,继续进行操作
  • 因此,修改一次web.xml文件,就要重启一次Tomcat

操作流程:

  • 创建对象 —-> init方法 —->service方法,循环 —-> 销毁(不一定执行)

注意:

  • 必须给Servlet实现类提供公共无参的构造器 —-> 因此Tomcat的 server.xml 文件中,导入了该实现类的全限定类名,会使用最简单的字节码对象的newInstance方法调用公共无参构造器创建对象

Tomcat中,Servlet请求流程
image.png
Servlet对象只有一个但是 ServletRequest 和 ServletResponse 对象每次访问都要创建
文字描述

  1. 浏览器发出请求
  2. 解析url:ip:port/上下文路径/资源名
  3. 带着上下文路径,去 tomcat 的配置文件 server.xml 中查找所有的 <Context>,通过上下文路径匹配是否有对应的web应用
  • 上下文路径就是匹配web应用的
    • 找得到:得到项目的绝对路径
    • 找不到:404
  1. 拿着资源名,去对应的项目的绝对路径找项目给 tomcat 的应用配置文件 web.xml,匹配 <servlet-mapping> 下的 <url-pattern>
  2. 匹配 <url-pattern>,匹配名称是否叫 /xxx,得到 <servlet-name>,通过 <servlet-name> 得到类的全限定名.
  3. 需要判断是否是第一次访问
  • 从Tomcat的实例缓存池:Map<String,Servlet> map;
    1. if(map.get(“全限定名”) == null){
    2. // 第一次访问,执行第七步
    3. } else{
    4. // 第N次,直接执行第八步
    5. }
  1. 通过全限定名,反射创建 Servlet 对象(需要无参构造器)
  • 再创建ServletConfig对象config,调用obj的init方法,传入config.
  • 再创建ServletRequest和ServeletResponse类的对象
  • 把创建的对象放在换缓存池中.
    1. Object obj = Class.forName("cn.haniel._01_hello.Hello2Servlet").newInstance();
    2. map.put("cn.haniel._01_hello.Hello2Servlet" obj)
  1. 创建ServletRequest和ServeletResponse类的对象,调用service方法.通过处理请求,执行业务逻辑,给浏览器响应
  2. 等待下一次的访问

ServletConfig接口
web.xml文件:

  • 通过该xml文件中的标签的子标签,可以定义许多初始化参数,在启动Tomcat时,被读取到 ServletConfig 接口实现类对象中

image.png
ServletConfig接口:

  • 表示当前 Servlet中 web.xml 配置信息
  • 每个 Servlet 会有一个 ServletConfig 接口的实现类
  • Tomcat会自动创建该接口的实现类对象,读取web.xml中的内容,放到该对象中,通过其实例方法,就可以在程序中,拿到xml中的值

作用:

  • 可以将Java代码中,原本写死又频繁修改的东西,写成web.xml文件的初始化参数,解决了硬编码问题
  • ServletConfig接口对象的实例方法 | String getServletName() | 获取当前Servlet的中的内容 | | —- | —- | | ServletContext getServletContext() | 获取上下文对象,一个应用就只有一个上下文对象 | | String getInitParameter(String name) | 获取指定名称的初始化参数值 | | Enumeration<String> getInitParameterNames() | 获取所有的初始化参数的名称 |

方法详解:
getInitParameter(String name) 方法

  • 可以获取 web.xml文件中 <init-param> 子标签中的 <param-name> 标签和 <param-value> 标签的值
  • 既,通过 <param-name> 的值,调用 getInitParameter(String name) 方法,获取 <param-value> 标签的值

getInitParameterNames() 方法

  • 可以一次性获取所有的子标签内容,返回值为古老的集合,迭代使用古老的迭代器
  • 步骤一样,出了名字不太一样 hasnext —-> hasMoreElements,next —-> nextElement
  • 拿出名字后,就可以通过getInitParameter(String name)方法获取这个name对应的值

    1. <br />Servlet继承体系<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1774803/1634026362708-a60e7259-30f5-468a-9297-76ebeff8ae2c.png#clientId=u3bc11fe4-4c15-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=441&id=u1c69a0e5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=378&originWidth=575&originalType=url&ratio=1&rotation=0&showTitle=false&size=23767&status=done&style=shadow&taskId=u9b782e4e-5b87-436c-b190-2d6cc82eef6&title=&width=671)<br />问题1
  • 每个Servlet 都需要去实现5个方法,而我们可能需要重写的就2个方法 —-> service方法和init方法

解决方法

  • 写一个GenericServlet类,去实现Servlet接口,该类中,不需要有具体的实现,我们自己的servlet去继承个该类即可,复写service方法即可.
  • Tomcat中已经为我们写好了这个 GenericServlet 类,不仅实现了 Servlet,而且实现了 ServletConfig,并将Service方法设置为抽象方法,

问题2

  • 目前Servlet 只能处理一般的请求和响应(没有实现任何协议),而我们做 BS 是和浏览器打交道,需要的是遵循 HTTP 协议的请求和响应

解决方法

  • 遵循了HTTP协议的请求和响应类是普通请求和响应类的子类,可以创建一个HttpServlet类
  • 该类中将普通的 ServletRequest 和 ServletResponse 强转成 HttpServletRequestHttpServletResponse 类(大转小,需强转)

问题3

  • 以后存在多个需要执行的Servlet实现类,且各个实现类有较大的重复代码

解决方法

  • 此时可以将多个Servlet实现类的共同代码抽取成一个BaseServlet类,各个实现类去继承它

Servlet继承体系源码详解
image.png
书写模板

  • 以后要写,就自己一个类继承HttpServlet,如果有多个,且有共同代码,就写一个BaseServlet
  • image.png

模板注意事项

  • 一定要删除出现的 super 语句,否则因为底层代码在抛405错误的原因,浏览器会一直收到405错误
  • 在该模板中,因为 getInitParameterNames 中已经覆盖获取额外写了关于ServletConfig的方法,因此要获取 ServletConfig 对象,直接调用使用 getServeletConfig() 方法,也可以直接就使用 getInitParameter() 或者 getInitParameterNames() 方法,

结论

  • 建类去继承 HttpServlet 覆盖需要的方法就行了

Servlet细节
映射细节

  1. 可以给一个servlet资源设置,但是必须要保证唯一性必须要保证以 **/** 开头
  2. <servlet-name> 一般都是使用 servlet 的简单名字,
  • 中的一定要匹配上
  • servlet-name 不能叫做default.
  • 如果将项目中的web.xml中的某个 servlet-name 叫成 default,会导致静态资源没办法访问
    • 因为在 tomcat 的配置文件 Tomcat/conf/web.xml 中,该文件是当前服务器所有的项目都可以公用的信息.
    • 在其中默认配置了一个 DefaultServlet他的 servlet-name 就是 defalut,这个Servlet的作用就是处理静态资源(html/css/js)
    • 一旦在项目中的web.xml覆盖了这个Servlet,会导致静态资源没法处理
  1. 我们可以给一个 Servlet 资源,配置多个 .或者配置多个 ,效果是一样的,让多个资源名对应一个Servlet资源
  • 注意: 多个一定不能重名,否则Tomcat启动会挂掉
  1. 可以给配置通配符
  • * 表示任意个数的字符 | <url-pattern>/*</url-pattern> | 写什么都能访问到这个Servlet资源,必须以/开头 | | —- | —- | | <url-pattern>/hello/*</url-pattern> | 只要以/hello/打头,就能访问到这个Servlet资源 | | <url-pattern>*.do</url-pattern> | 只要后面有.do,就能访问到该Servlet资源 |
  1. 欢迎页面的配置
  • Tomcat的 config/web.xml 中配置了默认的欢迎页面名字
  • 如果我们的欢迎页面不叫这些名字,不要去这里修改,直接在项目的web.xml文件中重写就行,会自动覆盖

image.png

  1. 服务器启动初始化Servlet配置
  • 如果项目有需求: 在项目中写比较多的初始化代码
    • 问题
      • 第一个访问的客户访问速度很慢,因为要创建ServletConfig对象
    • 解决方法
      • 让初始化代码(init()方法)在服务器启动时就执行,而不是在第一个用户访问时才初始化执行
    • 配置
      • 在项目的 web.xml 的 当前 <servlet> 中加入<load-on-startup>1</load-on-startup> 来配置当前 Servlet 的启动优先级
      • <load-on-startup>1</load-on-startup> 只要配置的中间的数值为正,就会在启动服务器时执行初始化代码
      • 多个 <servlet> 中,<load-on-startup>1</load-on-startup> 中间的数值越小,优先级越高

Servlet3.0新特性(注解配置)
传统方式

  • 之前的Servlet操作,需要配置8行代码才可以使用

image.png

  • 配置数据较多,大部分都是重复的代码

注解使用

  • 在 Servlet 的类上去贴一个标签 **@WebServlet(path)**,path是一个字符串,相当于 <url-pattern> 中的数据
  • 注解需要第三方程序支持才有作用,因此需要在项目中的 web.xml 中开启该第三方程序
    • 修改 web.xml,让其不忽略扫描注解
    • metadata-complete=”true” 忽略扫描Servlet上的注解.
    • metadata-complete=”false” 不忽略扫描Servlet上的注解(要扫描),为缺省值.

image.png

  • XML和注解如何抉择
    • XML:解除硬编码,维护性高; 配置繁琐.
    • 注解:配置简单,明了,存在硬编码; 维护性低.

Servlet 线程安全问题
servlet对象是tomcat服务器帮助我们创建的对象,而且只会创建一次 —-> 单例的
在整个应用中,只存在一个servlet对象。所有的浏览器(不同的线程)来访问当前的 servlet,其实都是访问的同一个对象
可能出现的线程安全问题

  • 如果在当前servlet中,包含有成员变量的话,那么所有的线程访问的成员变量就是共享数据,就会有线程安全问题

解决方案

  • 不要使用成员变量即可

SingleThreadModel接口

  • 实现了该接口后,Servlet会变成单线程的,效率严重降低
  • SpringMVC,Struts1 线程不安全的.

官方 SingleThreadModel 的介绍:

  • 确保servlet每次只处理一项请求。接口不含方法。如果servlet实现了该接口,会确保不会有两个线程同时执行servlet的service方法。 servlet容器通过同步化访问servlet的单实例来保证,也可以通过维持servlet的实例池,对于新的请求会分配给一个空闲的servlet。
  • 注意:SingleThreadModel不会解决所有的线程安全隐患。 例如,会话属性和静态变量仍然可以被多线程的多请求同时访问,即便使用了SingleThreadModel servlet。建议开发人员应当采取其他手段来解决这些问题,而不是实现该接口,比如避免实例变量的使用或者在访问资源时同步代码块。
  • 该接口在Servlet API 2.4中将不推荐使用。

HttpServletRequest
ServletRequest对象

  • 表示请求对象,封装了 请求的数据 和 获取请求数据的方法 —-> 服务器不获取,提交无意义
  • 只支持普通的请求,不支持 http

HttpServletRequest

  • ServletRequest接口的子接口,专门用来处理HTTP协议的请求
  • 封装了所有的请求数据 和 获取符合http协议的数据方法
  • 以后用的都是这个

HttpServletRequest常见方法

  • 获取请求中的数据,一定要去 HttpServletRequest对 象中获取. | getMethod | 返回请求方式:如GET | | —- | —- | | getRequestURI | 返回请求行中的资源名字部分:如/test/index.html | | getRequestURL | 返回浏览器地址栏中的所有信息 | | getContextPath | 获取当前项目的上下文路径元素的path属性值,需要在server.xml的path中配置 | | getRemoteAddr | 返回发出请求的客户机的IP地址 | | getRequestURL | 返回客户端请求的完整URL(包括协议、服务器名、端口号、资源路径信息),不含查询参数。 | | getHeader | 返回指定名称的头字段的值,头字段就是浏览器调试器中查看 |

HttpServletRequest重要方法
获取表单请求参数

String getParameter(String name) 返回指定名字参数的值。
String[] getParameterValues(String name) 返回指定名字参数的多个参数值 —-> 如复选框
Enumeration getParameterNames() 返回所有参数名的Enumeration对象。
Map getParameterMap() 返回所有的参数和值所组成的Map对象,通过entry进行迭代
  • 注册案例:
    • 注意: 将表单的提交位置设置为自定义 Servlet 实现类的资源位置,这样Servlet才能获取到这些提交的数据
    • image.png
  • 问题
    • 使用get,不会产生乱码
    • 使用post,会产生乱码
  • 使用post方法产生的中文乱码
    • 原因
      • 编码格式和解码格式不一致.
      • 编码格式:utf-8
      • 解码格式:服务器默认的解码格式是iso-8859-1.
    • 解决方法1
      • 使用错误的解码格式重新编码.编码成正确的byte数组,使用正确的编码格式进行解码
      • image.png
    • 解决方法1 的问题
      • 如果有多个参数需要显示代码,则每个参数需要多写两行代码 —-> 重复代码多
    • 解决方法2
      • 对于Tomcat8.0以前的版本,server.xml 中存在编码配置,可以将ISO-88590改为UTF-8
      • image.png
      • 但是该方法只能解决get请求的中文乱码不能解决post请求的中文乱码
      • Tomcat8.0以后,get请求没有中文乱码问题
    • 解决方法3
      • 使用自带的api,解决编码问题,适用于post
      • 在获取所有的参数之前,告知服务器,使用规定的格式去取参数
      • image.png
      • 注意: 一定要在获取所有的参数之前就告知,不管这些参数是不是中文

HttpServletResponse
ServletResponse对象

  • 表示响应对象,封装了做响应相关的相关方法
  • 只支持普通的响应,不支持 http

HttpServletResponse

  • HttpServletResponse接口的子接口,专门用来处理HTTP协议的响应
  • 符合http协议的响应方法
  • 以后用的都是这个

常用方法

ServletOutputStream getOutputStream() 获取字节输出流.
java.io.PrintWriter getWriter() 获取字符输出流.
  • 获得了输出流对象之后,就可以调用该对象的方法,对浏览器发送数据
    1. PrintWriter out = resp.getWriter();
    2. out.print("<html><body><h3>Hello World</h3></body></html>");
  • 注意

    • 上面两个方法,在同一个时刻,只能使用一个,不能共存,否则报错,要么字符串,要么字节

辅助方法

response.setContentType(“text/html”) 设置输出的MIME类型(内容的类型) 指定发送给浏览器的是什么东西,让浏览器正确渲染,如例子中返回的是html格式的文本
response.setCharacterEncoding(“UTF-8”) 设置输出数据的编码方式 告知浏览器,发送过去的数据是utf-8字符集,让其正确解码,避免乱码
response.setContentType(“text/html;charset=utf-8”) 可以将上述两行代码合并成一行代码 一定要写在HttpServletResponse对象的所有的操作之前