Servlet
1.Servlet简介
1.1.为什么使用Servlet
- 以登录为例,如需实现该功能,需要将HTML[jsp] 中的数据,提交到Java代码中,在通过jdbc技术与数据库进行交换.从而实现该功能.
- 需要使用Servlet实现将HTML[JSP] 中 的数据 , 提交到Java代码中 .
1.2 Servlet 简介
- 如果把Web应用比作一个餐厅,Servlet就是餐厅中的服务员——负责接待顾客、上菜、结账。
- Servlet指的是javax.servlet.Servlet接口及其子接口,也可以指实现了Servlet接口的实现类。
- Servlet可以理解为,具有URL特性的Java代码。
- 特点
- Servlet的实例对象由Servlet容器负责创建;
- Servlet的方法由容器在特定情况下调用;
- Servlet容器会在Web应用卸载时销毁Servlet对象的实例。
2.Servlet之helloWorld
-
① 搭建Web开发环境
② 创建动态Web工程
③ 创建javax.servlet.Servlet接口的实现类:com.atguigu.servlet.MyFirstServlet
④ 在service(ServletRequest, ServletResponse)方法中编写如下代码,输出响应信息
⑤ 在web.xml配置文件中注册MyFirstServlet
3.Servlet工作原理
- 浏览器发送请求【请求MyFirstServlet】
- 请求web.xml中<servlet-mapping>中的<url-pattern>/MyFirstServlet</url-pattern>
- 通过<servlet-mapping>映射<servlet>,从而找到相应全类名
- 执行MyFirstServlet中的相应方法【service()】
4.Servlet生命周期[面试]
- 构造器
- 执行时机 : 第一次接收请求执行 , 创建Servlet对象.
- 执行次数 : 在整个生命周期中 , 只执行一次 .
- init()
- 执行时机 : 第一次接收请求执行 , 执行构造器之后执行,初始化Servlet【如:初始化参数】。
- 执行次数 : 在整个生命周期中 , 只执行一次 .
- servlet()
- 执行时机 : 每次接受请求时,都会执行 . 接受请求 , 做出相应.
- 执行次数 : 在整个生命周期中 , 只执行n 次 .
- destroy()
- 执行时机 : 在关闭服务器[重启]时 , 执行destroy()方法,销毁Servlet对象
- 执行次数 : 在整个生命周期中, 只执行一次.
口述版:
扩展:
- Servlet是单例:
- 如添加如下配置,启动服务器成功后,立即创建Servlet并执行init()初始化。其他方法不变。
<!--表示一个Servlet程序-->
<servlet>
<!--
servlet-name 标签别名(一般默认是类名)
-->
<servlet-name>MyFirstServlet</servlet-name>
<!--
servlet-class 是全类名
-->
<servlet-class>com.atguigu.servlet.MyFirstServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
servlet-mapping : 是配置访问的地址
-->
<servlet-mapping>
<!--
servlet-name标签 表示当前配置的地址给哪个Servlet程序使用
-->
<servlet-name>MyFirstServlet</servlet-name>
<!--
url-pattern 是访问地址(以斜杠打头) </br>
斜杠表示: http://ip:port/工程路径/ </br>
/MyFirstServlet 就表示:http://ip:port/工程路径/MyFirstServlet </br>
-->
<url-pattern>/My FirstServlet</url-pattern>
</servlet-mapping>
5.ServletConfig与ServletContext
5.1 ServletConfig对象
- 概述: ServletConfig封装Servlet配置信息,每个Servlet都有唯一对应的ServletConfig对象
- 作用:
- getServletName() : 获取servlet名称
- getServletContext() : 获取Servlet上下文对象
- getInitParamenter() : 获取Servlet初始化参数
5.2 ServletContext
-
概述:ServletContext是Servlet上下文对象,代表当前web应用。在服务器启动时被创建,web应用卸载时销毁。
-
作用:
① 获取项目的上下文路径(带/的项目名): getContextPath()
② 获取虚拟路径所映射的本地真实路径:getRealPath(String path)
③ 获取WEB应用程序的全局初始化参数(基本不用)
④ 作为域对象共享数据【共4个域,聚齐后再讲】
6.最终创建Servlet方式
手动创建Servlet方式不足:
- 必须实现接口中所有方法[只关注Servlet()即可]
- 容易忽略注册细节
6.1 最终创建Servlet方式
-
EndServlet : HttpServlet : GenericServlet : Servlet
-
GenericServlet作用
- 提供两个对象的获取方法
- getServletConfig()
- getServletContext()
- 将service()方法,抽象化【在子类中只关注【重写】service()即可】
- 提供两个对象的获取方法
-
HttpServlet作用
-
override service()【重写service()】
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest) req; response = (HttpServletResponse) res; } catch (ClassCastException e) { throw new ServletException("non-HTTP request or response"); } service(request, response); }
-
overload service()【重载service】
public void service(HttpServletRequest request,HttpServletResponse response){ //获取请求方式 String method = request.getMethod(); if(method.eq("GET")){ doGet(request,response); }else if(method.eq("POST")){ doPost(request,response); }.... //PUT|DELETE }
-
7.request[请求]与response[相应]
7.1 request 对象
-
类型:HttpServletRequest
-
定义: 相当于浏览器向服务器发送报文 , 封装到request域中.该对象由web容器
[web服务器] 创建 , 以参加的形式传入到service() 方法中 , 最终传入到最终传入doPost()和doGet()中。
-
作用:共5个作用
-
获取请求参数
什么是请求参数?
-
<a href=“xxxServlet?paramName=paramValue&pn2=pv2…”>xxx</a>
-
<form action="" method=“post”>
…
</form>
getParameter():获取单个参数
getParameterValues():获取多个参数
-
-
获取URL信息
- request.getScheme():获取协议名
- request.getServerName():获取服务器名称
- request.getServerPort():获取服务器端口号
- request.getContextPath():获取上下文路径【带/项目名】
-
获取请求头信息
- request.getHeader():获取单个请求头数值
- request.getHeaders():获取多个请求头数值
-
转发【路径跳转】
-
域对象【共4个,聚齐再讲】
-
7.2 response 对象
-
类型:HttpServletResponse
-
定义:相当于服务器向浏览器发送的响应报文,封装到response对象中。该对象由web容器【web服务器】创建,以参数的形式传入到service()方法中,最终传入doPost()和doGet()中。
-
作用:
-
获取响应流,响应数据
//获取响应流,响应数据 PrintWriter writer = response.getWriter(); writer.write("login success!登录成功!");
-
设置响应头
//设置响应头 response.setHeader("Content-Type","text/html;charset=UTF-8");
-
重定向【路径跳转】
//重定向【路径跳转】 response.sendRedirect("login_success.html");
-
8.转发与重定向区别[面试题]
-
转发地址栏不变,重定向地址栏改变
-
转发可以携带request对象,重定向不能携带requet对象
-
转发浏览器发送一次请求 , 重定向浏览器发送两次请求
-
转发可以访问WEB-INF下资源,重定向不能访问
9.JavaWeb中乱码的问题
9.1 基本概念
- 字符集:就是各种字符的集合,包括汉字,英文,标点符号等等。各国都有不同的文字、符号。这些文字符号的集合就叫字符集。
- 编码 : 将字符 转换 成二级制 , 过程称为编码
- 解码 : 将二进制数转换为字符 ,过程称为解码
- 乱码: 编码和解码不一致 , 出现乱码的现象
9.2 乱码种类
- 请求乱码 : 浏览器向服务器发送数据时 , 出现的乱码
- 浏览器编码 , 服务器解码不一致导致的
- 响应乱码:服务器向浏览器做出响应时,出现乱码
- 服务器编码 , 浏览器解码不一致导致的
9.3浏览器与服务器默认字符集
- 服务器编码与解码默认一致为 : ISO-8859-1[不支持中文]
- 浏览器
- 浏览器编码默认 : UTF-8 [支持大量中文 , 大陆推荐使用的字符集]
- 浏览器默认解码 : GBK [GB2312 : 支持少量中文]
9.4 解决乱码[三行代码解决请求与响应乱码]
-
解决请求乱码
-
GET请求
-
思路 : 设置URL字符集修改8080端口号位置(tomcat->conf->server.xml),进行设置】
-
代码 :
<Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
-
-
-
解决相应乱码
- POST请求
- 思路 : 将服务器解码设置为 : UTF -8 [浏览器编码 : UTF-8 , 与服务器解码 : ISO-8859-1 , 不一致]
- 代码 : request.setCharacterEncoding(“UTF-8”);
- POST请求
-
解决相应乱码
-
思路&代码 : [服务器编码 : ISO-8859-1 与浏览器解码 : GBK不一致]
-
思路 : 将服务器编码设置为 : GBK
- 代码 : response.setCharacterEncoding(“GBK”);
-
思路:将服务器编码与浏览器解码均设置为UTF-8【推荐使用】
-
代码:
response.setHeader("Content-Type","text/html;charset=UTF-8"); response.setContentType("text/html;charset=UTF-8");//【推荐使用】
-
-
10.Javaweb中路径问题
问题:使用转发跳转路径时,由于转发特点【地址栏不变】,导致路径中使用[…/]可能出现404,不使用[…/]也可能出现404。
所以:使用相对路径不可靠,建议使用【绝对路径】
10.1 什么是绝对路径
- 以/开头的路径,称之为绝对路径。
10.2 [/] 代表的语义
- 服务器解析【/】,【/】代表当前web应用路径:http://localhost:8080/day06_servlet
- 以下两种情况,由服务器解析【/】
- 书写在web.xml中的【/】,由服务器解析
- 转发
- 以下两种情况,由服务器解析【/】
- 浏览器解析【/】,【/】代表当前服务器路径:http://localhost:8080
- 以下两种情况,由浏览器解析【/】
- 书写在html中的【/】,由浏览器解析
- 重定向
- 以下两种情况,由浏览器解析【/】
10.3 代码
-
html[jsp]
<base href="/day06_servlet/"> <form action="LoginServlet" method="get"></form> <a href="index.html">回首页</a>
-
servlet
response.sendRedirect(request.getContextPath()+"/pages/regist.html"); request.getRequestDispatcher("/pages/regist_success.html").forward(request,response);