目录
Servlet简介
1、Servlet的生命周期
2、Servlet的运行原理
Servlet的组织结构
3、Servlet处理HTTP协议/请求方式
Servlet处理参数值
Servlet如何处理HTTP协议
请求方式
转发器
4、Servlet处理请求资源路径
Servlet组件的合并
5、重定向
6、异常错误处理
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Servlet 的生命周期可分为:实例化,初始化,就绪,销毁。
init(): 在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。
service(): 它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。Servlet的工作过程
阶段1:实例化
即容器调用构造器创建Servlet对象.
时机1:容器收到请求后,创建Servlet对象
时机2:容器启动后,立即创建Servlet对象
web.xml中需要配置
1
阶段2:初始化
容器在创建Servlet对象后,会立即调用init方法进行对象的初始化。一般情况下,我们不需要重写此方法,因为父类型GenericServlet里提供了init方法的实现逻辑。此方法保存了另外一个对象ServletConfig的引用,如果你想初始化一些自定义的属性,我们可以将初始化的值配置在web.xml里。
company 华育兴业 通过ServletConfig提供的 getInitParameter(String name)来获取值
public void init() throws ServletException { System.out.println("----初始化"); ServletConfig config = getServletConfig(); String company = config.getInitParameter("company"); }
阶段3:就绪
初始化之后,容器调用Servlet对象的service方法进行资源分配。
阶段4:销毁
容器会根据自己的算法来进行Servlet对象的销毁,销毁前一定会调用destroy()方法。因此我们可以重写此方法来完成一些业务逻辑。卸载程序时,一定会销毁Servlet对象public void destroy() { System.out.println("程序卸載了"); }
练习代码:
public class HelloServlet extends HttpServlet{
private String company;
private String manager;
public HelloServlet() {
System.out.println("创建servlet对象");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("处理业务逻辑");
System.out.println("company:"+company);
System.out.println("manager:"+manager);
}
@Override
public void init() throws ServletException {
System.out.println("----初始化");
ServletConfig config = getServletConfig();
company = config.getInitParameter("company");
manager = config.getInitParameter("manager");
}
@Override
public void destroy() {
System.out.println("程序卸載了");
}
}
- 浏览器依据IP和PORT与服务器建立连接
- 发送请求数据包到服务器
- 服务器创建Servlet组件对象
- 使用HttpServletRequest处理请求数据包(读取页面上的数据)
- 使用HttpServletResponse封装响应数据(将程序中的数据发送到页面上)
- 服务器发送响应数据包
- 浏览器进行解析,生成页面
appName
---》WEB-INF
---》classes
---》xxx.class文件
---》lib(可选)
---》web.xml
---》index.html(可选)
Servlet处理页面上出入的值request调用下面方法
处理1:1形式的参数与参数值
String getParameter(String name)
如果name不存在,返回null
处理1:M形式的参数与参数值
String[] getParameterValues(String name)
如果name不存在,返回null
当浏览器向服务器端发送请求后,服务器端会维护两个对象,用来封装和处理请求数据包的数据,及其响应数据。分别是HttpServletRequest和HttpServletResponse对象
1、HttpServletRequest对象封装和处理请求数据包的数据(接收页面发来的数据)
提供了以下方法
String getParameter(String name)
String[] getParameterValues(String name)
String getHeader(String str)
EnumrationgetHeaders()
RequestDispatcher getRequestDispatcher(String url)
.......
2、HttpServletResponse对象封装和处理服务端要响应给浏览器的数据(将封装好的数据发送给浏览器)
提供了以下方法
void setContentType(String str)
void sendRedirect(String url)
.......
浏览器向服务器发送请求的种类有八种:
GET,POST,OPTIONS,HEAD,PUT,DELETE,TRACE,CONNECT
(1)常用的两种get和post
get:向特定资源发送请求(如返回登陆界面),在地址栏上直接写地址,表单的默认提交
post:向指定资源提交数据(提交表单,上传文件),要想使用此种方式提交,表单的method属性设置POST
(2)两者的区别
get:提交的数据会显示在地址栏上,数据量小,最多为4kb。不安全
post:提交的数据不会在地址栏上显示。因此我们可以提交大量的数据,相对安全
概念:一个web组件将未完成的任务交给另一个web组件继续做,通常是一个servlet将数据获取之后转交给jsp进行展现.
下面讲的是三种转发中较为常用的一种转发方式和步骤
转发步骤:
1、绑定数据
request.setatteribute(string name,obj) name绑定名 obj:绑定值 服务器端使用
2、获取转发器
requestdispatatcher rd = request.getrequestdispatcher(string url) url 要转发到的路径
3、启动转发
rd.forward(request,response)
注:转发的本质是一个web组件通知容器调用另外一个web组件,(即调用service方法,所以需要传递request,response)
页面获取数据:
obj request.setAttribute(string name);//依据绑定名获取绑定值,返回时时object类型的,需要强转后使用
练习代码:
protected void service(HttpServletRequest req, HttpServletResponse resp){
//服务器端
String str = "转发器测试";
/** 绑定数据*/
req.setAttribute("key", emp);
/** 获取转发器*/
RequestDispatcher rd = req.getRequestDispatcher("emplist.jsp");
/**启动转发*/
rd.forward(req, resp);
}
/**========================================================================*/
//页面
<% String str = (String) request.getAttribute("key"); %>
web.xm基礎l配置
count
com.hyxy.session.CountServlet
count
/count
1、什么是请求资源路径
浏览器中的网址 http://ip:port/appName/url-pattern,请求资源路径:appName/url-pattern
2、处理原理
浏览器依据ip和port确定服务器,之后依据appName确定应用程序所在的目录,servlet容器默认浏览器请求的是一个Servlet组件, 所以会校验web.xml里的url-pattern,进行匹配,执行相关的Servlet组件。
3、精确匹配
服务器在进行web.xml里的url-pattern的校验时,会严格匹配请求路径是否一致,如果匹配成功,就会执行相关资源
如:
4、通配符匹配
通配符: * ,匹配0个或多个字符,必须使用斜杠
如:
http://ip:port/appName/abc.html 匹配成功
http://ip:port/appName/service/add.html 匹配成功
http://ip:port/appName/listEmp 匹配成功
5、后缀匹配
在写web.xml里的url-pattern的值时,我们可以使用“ * . ” 后缀的方式,后缀可以是1或多个字符组成的。
如:
http://ip:port/appName/abc.html 匹配失败
http://ip:port/appName/emp/abc.action 匹配成功
http://ip:port/appName/listEmp.action 匹配成功
优先级: 精确匹配最高
假如:web.xml中有三个Servlet组件,其url-pattern如下
浏览器地址:http://ip:port/appName/abc.do 会执行精确匹配的Servlet组件如果精确匹配,通配符匹配,后缀匹配都没有成功,容器会查找是否有此文件,如果有此文件,打包数据返回给浏览器。如果没有,返回404.
一般情况下,Servlet组件充当的角色为控制角色,控制角色的
作用是接收请求后进行分发到不同的资源里。因此一个Servlet就可以
对请求资源路径进行分析,使用分支结构来处理不同的资源。
如何合并:
(1)采用后缀匹配进行修改web.xml
(2)获取请求资源路径进行分析,然后使用if分支进行处理
1.概念:服务器处理完业务逻辑后,向浏览器发送一个状态码302,同时发送一个消息头Location,此消息头的值是一个新地址。当浏览器接收这些信息后,会立即向服务器发送该地址的请求
2、重定向的原理:可以参考:https://blog.csdn.net/kobejayandy/article/details/13745545
3、如何重定向
response.sendRedirect(String url) url:是重定向的新地址
4、重定向的特点
地址栏的地址会发生改变。
重定向之前不能关闭流
两次请求不共享request和response对象
错误代码及其解决方法:
服务器在处理完业务逻辑后,会响应浏览器,响应的内容包含了状态编码(数字类型)
200:表示成功处理业务。
404:服务器处理的路径存在问题,找不到相关请求资源
如:
(1)在地址栏上的路径有问题(大小写不对)
(2)
(3)两个servlet-name不一致
(4)没有部署项目
(5)项目的组织结构有问题
405:容器找不到Servlet组件的service方法
(1)方法名写错
(2)方法的参数类型有问题
(3)方法的异常,返回值有问题
500:容器找不到Servlet组件
(1)没有继承HttpServlet或实现Servlet接口
(2)
(3)service里的逻辑出现了问题
处理中文参数值
中文会出现乱码,原因是编码与解码的字符集不一致造成
中文乱码解决方式
方式1:服务端先编码再解码,适合 get/post req.setCharacterEncoding("utf-8") 服务器端默认使用iso-8859-1解码浏览器端常用的为utf-8进行编码
方式2:只适合post request.setCharacterEncoding("utf-8") 位置:处理请求参数前
发送响应时:
response.setContentType("text/html;charset=utf-8") 位置:写在获取流之前
再写代码时先将request.setCharacterEncoding("utf-8")和response.setContentType("http/html;charset=utf-8") 写上这样就能避免出现乱码