兴趣爱好Javajava学习笔记- web基础六(Servlet)
执笔简介
- Servlet 是 JavaEE 规范之一。规范就是接口
- Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器
- Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端
URL地址到Servlet程序访问
生命周期
执行 Servlet 构造器方法,执行 init 初始化方法,是在第一次访问的时候创建 S ervlet 程序会调用
执行 service 方法,每次访问都会调用
执行 destroy 销毁方法,,在 web 工程停止的时候调用
Servlet类的继承体系
ServletConfig类
作用
xml中配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>username</param-name> <param-value>root</param-value> </context-param> <context-param> <param-name>password</param-name> <param-value>123456</param-value> </context-param>
<servlet> <servlet-name>ServletTest</servlet-name> <servlet-class>com.study.servlet.ServletTest</servlet-class>
<init-param> <param-name>username</param-name> <param-value>root</param-value> </init-param> </servlet>
<servlet-mapping> <servlet-name>ServletTest</servlet-name>
<url-pattern>/ServletTest</url-pattern> </servlet-mapping> </web-app>
|
Servlet:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ServletTest implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("2. init初始化方法"); //1. 可以获取Servlet程序的别名servlet-name值 System.out.println(" ServletTest程序的别名:" + servletConfig.getServletName()); //2. 获取初始化参数init-param System.out.println(" 初始化参数username的值:" + servletConfig.getInitParameter("username")); System.out.println(" 初始化参数url的值:" + servletConfig.getInitParameter("url")); //3. 获取ServletContext对象 System.out.println(servletConfig.getServletContext()); } }
|
httpServlet:
继承httpServlet 进行重写init() 方法需要调用父类的init() 不然后面获取会空指针异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class ServletTest2 extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { // 这里需要调用父类的init() 不然后面获取会空指针异常 /** * public void init(ServletConfig config) throws ServletException { * this.config = config; * this.init(); * } * * 重写后这里父类GenericServlet中的init() config无法进行保存 */ super.init(config); System.out.println("重写init方法,执行一些操作"); } }
|
ServletContext类
- ServletContext 是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,只有一个 ServletContext 对象实例
- ServletContext 对象是一个域对象
- ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁
域对象
可以像 Map 一样存取数据的对象,叫域对象
域指的是存取数据的操作范围是整个 web 工程
作用
- 获取 web.xml 中配置的上下文参数 context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像 Map 一样存取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ServletContext extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 获取web.xml中配置的上下文参数context-param javax.servlet.ServletContext context = getServletConfig().getServletContext(); String username = context.getInitParameter("username"); System.out.println("ContextServlet的username是:" + username); System.out.println(" ContextServlet的password是:" + context.getInitParameter("password"));
//2. 获取当前的工程路径,格式:/工程路径 String contextPath = context.getContextPath(); System.out.println(" 当前工程路径是:" + contextPath); //3. 获取工程部署后再服务器硬盘上的绝对路径 /** * / 被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录 */ System.out.println(" 工程部署的绝对路径是:" + context.getRealPath("/")); System.out.println(" 工程部署的绝对路径是:" + context.getRealPath("/css")); } }
|
xml:
1 2 3 4 5 6 7 8 9 10
| <context-param> <param-name>username</param-name> <param-value>context</param-value> </context-param>
<context-param> <param-name>password</param-name> <param-value>root</param-value> </context-param>
|
HTTP协议
请求的HTTP格式
GET请求
请求行
请求的方式,如 GET或POST
请求的资源路径[+?+请求参数]
请求的协议的版本号 HTTP/1.1
请求头
- key : value 组成 ,不同的键值对,表示不同的含义
那些为GET请求
form 标签 method=get
a 标签
link 标签引入 css
Script 标签引入 js 文件
img 标签引入图片
iframe 引入 html 页面
在浏览器地址栏中输入地址后敲回车
POST请求
请求行
请求的方式 POST
请求的资源路径[+?+请求参数]
请求的协议的版本号 HTTP/1.1
请求头
请求体
常用请求头说明
那些为POST请求
响应的HTTP协议格式
响应行
响应头
响应体
常用响应码
- 200 表示请求成功
- 302 表示请求重定向
- 404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
- 500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
MIME类型
- MIME 是 HTTP 协议中数据类型,
- 英文全称是”Multipurpose Internet Mail Extensions” 多功能 Internet 邮件扩充服务
- 格式是“大类型/小类型”,并与某一种文件的扩展名相对应
文件 |
MIME类型 |
超文本标记语言文本 |
.html , .htm text/html |
普通文本 |
.txt text/plain |
RTF文本 |
.rtf application/rtf |
GIF图形 |
.gif image/gif |
JEPG图形 |
.jpeg,.jpg image/jpeg |
au声音文件 |
.au audio/basic |
MIDI 音乐文件 |
mid,.midi audio/midi,audio/x-midi |
RealAudio 音乐文件 |
.ra, .ram audio/x-pn-realaudio |
MPEG 文件 |
.mpg,.mpeg video/mpeg |
AVI 文件 |
.avi video/x-msvideo |
GZIP 文件 |
.gz application/x-gzip |
TAR 文件 |
.tar application/x-tar |
HttpServletRequest 类
作用
- 通过HttpServletRequest对象获取请求的信息
常用方法
1 2 3 4 5 6 7 8 9 10
| getRequestURI() 获取请求的资源路径 getRequestURL() 获取请求的统一资源定位符(绝对路径) getRemoteHost() 获取客户端的 ip 地址 getHeader() 获取请求头 getParameter() 获取请求的参数 getParameterValues() 获取请求的参数(多个值的时候使用) getMethod() 获取请求的方式 GET 或 POST setAttribute(key, value); 设置域数据 getAttribute(key); 获取域数据 getRequestDispatcher() 获取请求转发对象
|
doGet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ResponseISOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 返回中文显示不对解决方案一 System.out.println(resp.getCharacterEncoding());//默认是ISO-8859-1 // 设置服务器的字符集为UTF-8 // resp.setCharacterEncoding("UTF-8"); // // 通过响应头 设置浏览器的字符集为 UTF-8 // resp.setHeader("Content-Type","text/html;charset=UTF-8"); // 方案二 // 需要在获取流对象之前调用才有效 resp.setContentType("text/html; charset=UTF-8"); //返回数据给客户端 PrintWriter writer = resp.getWriter(); writer.write("你哈");//这里输入中文会无法显示 } }
|
POST请求中文乱码解决
1 2
| // 设置请求体的字符集为 UTF-8,从而解决 post 请求的中文乱码问题 req.setCharacterEncoding("UTF-8");
|
请求转发
- 服务器收到请求后,从一次资源跳转到另一个资源的操作
Servlet1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 请求转发可以访问 WEB-INF下的内容 // 请求转发浏览器中地址栏的地址不变 // 获取请求的参数 String username = req.getParameter("username"); System.out.println("在servlet1(柜台1) 查看参数(材料):" + username); // 盖章 并传递到servlet2去查看 req.setAttribute("key","servlet1的章"); // 问路 servlet2(柜台2)怎么走 /** * 这里必须为 /开头 因为/被解析为 http://ip:port/工程名/ 映射到IDEA代码的web目录 */ RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2"); // 请求转发 requestDispatcher.forward(req,resp); } }
|
Servlet2:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求的参数 String username = req.getParameter("username"); System.out.println("在servlet2(柜台2) 查看参数(材料):" + username); // 查看柜台1servlet1的章 Object key = req.getAttribute("key"); System.out.println("柜台1是否有章" + key); // 处理柜台2的任务 System.out.println("处理柜台2的任务"); } }
|
特点
- 浏览器地址栏没有变化
- 是一次请求
- 共享Request域中的数据
- 可以转发到WEB-INF目录下
- 不可以访问工程外的资源
base标签
1 2 3
|
<base href="http://localhost:8080/07_servlet/a/b/">
|
web中的相对路径和绝对路径
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径
1、绝对路径
2、base+相对
相对路径
. :表示当前目录
.. :表示上一级目录
资源名 :表示当前目录/资源名
绝对路径
/斜杠意义
1 2 3
| <url-pattern>/servlet1</url-pattern> servletContext.getRealPath(“/”); request.getRequestDispatcher(“/”);
|
HttpServletResponse 类
- 返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
输出流
- 字节流 getOutputStream(); 常用于下载(传递二进制数据)
- 字符流 getWriter(); 常用于回传字符串(常用)
- 网客户端回传数据:
1 2 3 4 5 6 7 8
| public class ResponseIOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException { // 要求 : 往客户端回传 字符串 数据。 PrintWriter writer = resp.getWriter(); writer.write("response's content!!!"); } }
|
响应乱码问题解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ResponseISOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 返回中文显示不对解决方案一 System.out.println(resp.getCharacterEncoding());//默认是ISO-8859-1 // 设置服务器的字符集为UTF-8 // resp.setCharacterEncoding("UTF-8"); // // 通过响应头 设置浏览器的字符集为 UTF-8 // resp.setHeader("Content-Type","text/html;charset=UTF-8");
// 方案二 // 需要在获取流对象之前调用才有效 resp.setContentType("text/html; charset=UTF-8"); //返回数据给客户端 PrintWriter writer = resp.getWriter(); writer.write("你好");//这里输入中文会无法显示 } }
|
请求重定向
- 请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Response1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 请求重定向第一种方案(不推荐) // //设置为状态为 302 // resp.setStatus(302); // // 设置响应头 将新的路径发送给客户端 // resp.setHeader("Location", "http://localhost:8888/07_servlet/response2");
// 第二种 (推荐) resp.sendRedirect("http://localhost:8888/07_servlet/response2"); } }
|
特点
- 浏览器地址会发生变化
- 两次请求
- 不共享Request中数据
- 不能访问WEB-INF下的资源
- 可以访问工程外的资源