Servlet
学习目标
HTTP协议
HTTP协议(Hyper Text Transfer Protocol–超文本传输协议)是一个客户端请求和响应的标准协议。
协议详细规定了浏览器和万维网服务器之间互相通信的规则
通信规则规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式
客户端发送给服务器的格式叫"请求协议";服务器发送给客户端的格式叫"响应协议"
1 书写格式
http://127.0.0.1:8080/myweb/servlet01?name=zhangsan&pwd=123456
http://IP(主机名/域名):端口/访问的资源路径?键值对1&键值对2
2 HTTP协议的特点
1、支持客户/服务器模式
2、简单快速(请求时只需方法(GET/POST)和路径)
3、灵活(允许传输任意类型的数据对象)
4、无连接(每次连接只处理一个请求)
5、无状态(对事务处理没有记忆能力)
3 URI和URL
URI(Uniform Resource Identifier),统一资源标识符,用来唯一的标识一个资源
URL(Uniform Resource Locator),统一资源定位符,是一种特殊类型的 URI,包含了用于查找某个资源的足够的信息的格式
http://IP[:post]/[abc_path]
http :通过 HTTP 协议来定位网络资源
IP:合法的 Internet 主机域名或 者 IP 地址
port :指定一个端口号,为空则使用缺省端口 80
abs_path :指定请求资源的 URI
4 HTTP请求
HTTP 请求由三部分组成,分别是:请求行、请求头、请求正文
请求行格式:Method Request-URI HTTP-Version CRLF
Method:请求方法
Request-URI:统一资源定位符
HTTP-Version:请求的HTTP协议版本
CRLF:回车和换行
5 HTTP响应
在接收和解释请求消息后,服务器返回一个 HTTP 响应消息
HTTP 响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
6 消息头
HTTP 消息由客户端到服务器的请求和服务器到客户端的响应组成
请求消息和响应消息都是由开始行、消息报头、空行、消息正文组成
请求消息的开始行为请求行
响应消息的开始行为状态行
每一个报头域都是由 名字+":"+空格+值 组成,消息报头域的名字是大小写无关的
请求头
请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息
Referer:该请求头指名请求从哪里来
响应头
响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和 对 Request-URI 所标识的资源进行下一步访问的信息
Location:用于重定向接受到一个新的位置
response.sendRedirect("http://www.baidu.com");
Refresh:自动跳转
Tomcat服务器
Tomcat 是一个符合JavaEE Web标准的最小的Web容器,所有的JSP程序要有WEB容器的支持才能运行,而且在给定的 WEB 容器里面都会支持事务处理操作
Tomcat 就是一个运行Java的网络服务器,底层是Socket的一个程序,也是JSP和Servlet的一个容器
Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器
Tomcat下载地址:http://tomcat.apache.org/
Tomcat 运行时需要JDK的支持,所以要安装Tomcat服务器必须先配置【JAVA_HOME】,
Tomcat目录结构:
-
bin:启动和关闭 tomcat 的 bat 文件 -
conf:配置文件 server.xml 该文件用于配置 server 相关的信息 web.xml 文件配置与 web 应用(web 应用相当于一个 web站点) tomcat-user.xml 配置用户名密码和相关权限 -
lib:该目录放置运行 tomcat 运行需要的 jar 包 -
logs:存放日志,当我们需要查看日志的时候,可以查询信息 -
webapps:放置我们的 web 应用 -
work 工作目录:该目录用于存放 jsp 被访问后生成对应的 server 文件和.class 文件
启动Tomcat服务器:双击startup.bat 文件
关闭Tomcat服务器:双击shutdown.bat 文件
Servlet的实现
Servlet(Servlet Applet) 是 服务端小程序
使用Java语言编写的服务端程序,可以生成动态的WEB页面
Servlet 主要运行在服务器端,并由服务器调用执行, 是一种按照 Servlet 标准来开发的类
Servlet 本质上也是 Java 类,但要遵循 Servlet 规范进行编写,没有 main()方法,它的创建、使用、销毁都由 Servlet 容器进行管理
Servlet 是和 HTTP 协议是紧密联系的,其可以处理 HTTP 协议相关的所有内容
Servlet容器:提供了Servlet功能的服务器,如Tomcat、Jetty
1 实现Servlet规范
要实现Servlet规范,就要继承HttpServlet类
package com.xxxx.servlet;
import javax.servlet.http.HttpServlet;
public class Servlet01 extends HttpServlet {
}
2 重写 service 方法
在规范中有一个叫做 service的方法,专门用来做请求处理的操作,业务代码则可以写在该方法中
package com.xxxx.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 Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("Hello Servlet!");
}
}
3 设置注解
在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源
开发servlet项目,使用**@WebServlet**将一个继承于javax.servlet.http.HttpServlet 的类定义为Servlet组件
在Servlet3.0中 , 可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的 Servlet
package com.xxxx.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ser01")
import java.io.IOException;
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("Hello Servlet!");
}
}
注解@WebServlet("/ser01")表示该Servlet默认的请求路径为…/cer01
Servlet的工作流程:
1、通过请求头获知浏览器访问的是哪个主机
2、通过请求行获取访问的是哪一个web应用
3、通过请求行中的请求路径获知访问的是哪个资源
4、通过获取的资源路径在配置中匹配到真实的路径
5、 服务器创建servlet对象
6、调用service(request, response)方法来处理请求和响应的操作
7、调用service完毕后返回服务器 由服务器讲response缓冲区的数据取出,以http响应的格式发送给浏览器
Servlet的生命周期
Servlet没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控制和调度
生命周期指的是 servlet 容器何时创建 servlet 实例、何时调用其方法进行请求的处理、 何时销毁其实例的整个过程
1.创建实例:init() 方法
public void init(ServletConfig config) throws ServletException { System.out.println("实例创建了...");
}
2.处理请求:service() 方法
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("服务调用了...");
}
3.销毁实例:destroy() 方法
public void destroy() {
System.out.println("实例销毁了...");
}
HttpServletRequest对象
用来接收客户端发送过来的请求信息
service()方法中形参接收的是 HttpServletRequest 接口的实例化对象,表示该对象主要应用在 HTTP 协议上,该对象是由 Tomcat 封装好传递过来
HttpServletRequest 是 ServletRequest 的唯一子接口
问:既然只有一个子接口为什么不将两个接口合并为一个?
从长远上讲:现在主要用的协议是 HTTP 协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承 ServletRequest 接口就行了
1 接受请求
常用方法:
方法 | 描述 |
---|
getRequestURL() | 获取客户端发出请求时的URL | getRequestURI() | 获取请求行中的URI | getQueryString() | 获取请求行中的参数部分 | getMethed() | 获取客户端请求方式 | getProtocol() | 获取HTTP版本号 | getContextPath() | 获取项目名 | getParameter() | 获取指定名称的参数 | getParameterValues(String name) | 获取指定名称参数的所有值 |
2 请求乱码问题
方式1:只针对POST请求:(在接收所有的数据之前设定)
request.setCharacterEncoding("UTF-8");
方式2:
new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
3 请求转发
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出
实现方式如下,达到多个资源协同响应的效果
request.getRequestDispatcher(url).forward(request,response)
4 request作用域
在一次请求中有效,即服务器跳转有效
request.setAttribute(String name, String value);
request.getAttribute(String name);
request.removeAttribute(String name);
HttpServletResponse对象
用于服务器对客户端的请求进行响应,将 Web 服务器处理后的结果返回给客户端
service()方法中形参接收的是 HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法
1 响应数据
接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流
有两种形式:
getWriter():获取字符流(只能响应字符)
getOutputStream():获取字节流(能响应所有数据)
注意:两者不能同时使用
字符流输出
PrintWriter pw = response.getWriter();
pw.write("Hello");
pw.write("<h2>Hello</h2>");
字节流输出
ServletOutputStream out = response.getOutputStream(); out.write("Hello".getBytes());
out.write("<h2>Hello</h2>".getBytes());
2 响应乱码问题
getWriter()的字符乱码
对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文
解决:
只能在服务器端告知服务器使用一种能够支持中文的编码格式,比如我们通常用的"UTF-8"
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write("<h2>你好</h2>");
只要保证发送端和接收端的编码一致就不会有乱码
getOutputStream()的字节乱码
当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码
response.setContentType("text/html;charset=UTF-8");
response.setHeader("content-type","text/html;charset=UTF-8");
ServletOutputStream out = response.getOutputStream();
out.write("<h2>你好</h2>".getBytes("UTF-8"));
总结:
要想解决响应的乱码,只需要保证使用支持中文的编码格式,并且保证服务器端和客户端使用相同的编码方式即可
3 重定向
重定向是一种服务器指导,客户端的行为,重定向当中有两个请求存在
理解:
客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址,当客户端接收到响应后,会立刻自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成
response.sendRedirect("index.jsp");
第一次请求获得的响应码为 302,并且含有一个 location 头信息。并且地址栏最终看到的地址是和第一次请求地址不同的,地址栏已经发生了变化
4 请求转发与重定向的区别
相同点:都能实现页面跳转
不同点:
请求转发 | 重定向 |
---|
req.getRequestDispatcher(url).forward(req,resp) | resp.sendRedirect(url) | 服务器端行为 | 客户端行为 | 一次请求 | 两次请求 | 地址栏不发生变化 | 地址栏发生变化 | 只能在项目内跳转 | 可以跨域访问 |
注:两者都可进行跳转,根据实际需求选取
明晚继续更后半部分,谢谢观看,来个一键三连呗!
|