一、Servlet
1、概念介绍
servlet 介绍
简单来说servlet是运行在服务器上的java程序
Servlet 作用
通俗来讲servlet专门用来接收客户端的请求,专门接收客户端的请求数据,然后调用底层service处理数据并生成结果
浏览器http请求——》tomcat服务器——-》到达servlet—–》执行doget,dopost方法—-》返回数据
2、Servlet 三大作用域
(1)request:一个请求链,每一个请求都会创建一个request,作用域为当前的请求链,一般用于同一请求链之间不同页面的参数传递,如表单中的值传递。
(2)session:Tomcat(服务器)会为每个会话创建一个session对象,作用域:session的数据只能在当前会话中的所有servlet共享(会话范围:如某个用户从首次访问服务器开始,到用户关闭浏览器结束),HttpSession底层依赖Cookie。(默认存在30分钟)
(3)application(ServletContext): 服务器会为每个web应用创建一个ServletContext对象,而ServletContext对象的创建时在服务器启动时完成的,在服务器关闭时销毁的, 作用:在整个web应用的动态资源之间共享数据。
(1)request
**request(请求对象)**:可以获取客户端ip、请求参数、请求头、请求URL等
getHeader(String name)获取请求头(单头)
getIntHeader(String name)获取单值int类型的请求头
getContextPath();获取项目名
getParamter(String name)获取指定名称的请示参数值
请求转发、包含和重定向
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 向 request 设置值
request.setAttribute("name", ".xiaoming");
//请求转发
request.getRequestDispatcher("/index.jsp").forward(request, response);
//请求包含
request.getRequestDispatcher("/index.jsp").include(request, response);
//重定向
response.sendRedirect("/index.jsp");
}
请求转发、包含和重定向区别
有时候一个请求链需要多个servlet完成,所以需要在一个servlet转发到另一个servlet。
请求转发:有下一个Servlet完成响应体,当前Servlet可以设置响应头。如response.setHeader(“pragma”, “no-cache”);
请求包含:由两个Servlet共同完成没有完成的响应体。
请求转发和重定向的区别:
请求次数:请求转发是一个请求一个响应,而重定向是两次请求两次响应
地址栏:请求转发和请求包含都是地址栏不会发生变化,而重定向地址栏会发生变化,显示后一个请求的地址。
范围:请求转发只能转发到本项目其他的Servlet,重定向不但能定向到本项目,还能定向到其他项目
路径:因为请求转发和请求包含都是服务端行为,所以转发时只需要给出转发的Servlet路径,而重定向需要给出requestURL(请求路径),也就是需要包括项目名。
效率:请求转发和重定向比较是请求转发的效率高,因为请求转发是一个请求。
根据需求选择,如果需要地址栏发生变化,使用重定向,而需要在下一个Servlet中获取request域中的数据时,使用请求转发或包含。
总结:使用作用域传递或存储数据需要根据项目需要来选择不同的域获取数据或保存数据,只有掌握它们的生命周期、作用范围才能正确选择作用域。
request的Parameter和Attribute
- getParameter得到的都是String类型的。或者是http://a.jsp?id=123中的123,或者是某个表单提交过去的数据。
- getAttribute则可以是对象。
- getParameter()是获取POST/GET传递的参数值;
- getAttribute()是获取对象容器中的数据值;getAttribute只能收到程序用setAttribute传过来的值。
- getParameter:用于客户端重定向时,即点击了链接或提交按扭时传值用,即用于在用表单或url重定向传值时接收数据用。
- getAttribute:用于服务器端重定向时,即在sevlet中使用了forward函数,或struts中使用了mapping.findForward。
区别:
- 来源不同: 参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中
提供的,若是POST方法是从请求体(request body)中提供的;
属性(attribute)是服务器端的组件(JSP或者Servlet)利用requst.setAttribute()设置的 - 操作不同: 参数(parameter)的值只能读取不能修改,读取可以使用request.getParameter()读取;
属性(attribute)的值既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute() - 数据类型不同: 参数(parameter)不管前台传来的值语义是什么,在服务器获取时都以String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如一个对象。
属性(attribute)的值可以是任意一个Object类型。
共同点
二者的值都被封装在request对象中。
(2)session
(3)servletContext 简单案例
想要网站所有资源被访问时都要给访问量进行累加,可以使用ServletContext对象来完成这一功能,首先创建一个用来报存访问量的Integer类型的变量,使用ServletContext对象的SetAttribute方法将它保存到域中,这样所有的Servlet都可以访问到。资源被第一次访问时,创建一个变量,设置值为1,保存到ServletContext域中,从第二次访问之后,可以从ServletContext域中获取这个变量进行累加。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取 ServletContext 对象
ServletContext application = this.getServletContext();
// 获取 ServletContext 中的 count
Integer count = (Integer) application.getAttribute("count");
if (count == null) { //判断是否空,为空的话创建变量赋值并保存到域中
application.setAttribute("count", 1);
} else { //不为空则在原有的基础上加一
application.setAttribute("count", count + 1);
}
//设置编码
response.setContentType("text/html;charset=utf-8");
}
3、生命周期
servlet:servlet的生命周期始于它被装入web服务器的内存时,并在web服务器终止或重新装入servlet时结束。servlet一旦被装入web服务器,一般不会从web服务器内存中删除,直至web服务器关闭或重新结束。
(1) 装入:启动服务器时加载Servlet的实例;
(2) 初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有init()方法负责执行完成;
(3) 调用:从第一次到以后的多次访问,都是只调用doGet()或doPost()方法;
(4) 销毁:停止服务器时调用destroy()方法,销毁实例。
filter:(一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy(),空实现也行)
(1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
(2)、每一次请求时都只调用方法doFilter()进行处理;
(3)、停止服务器时调用destroy()方法,销毁实例。
4、doService()
Serlvet接口只定义了一个服务方法就是service
,而HttpServlet
类实现了该方法并且要求调用下
列的方法之一︰
- doGet: 处理GET请求
- doPost :处理POST请求
当发出客户端请求的时候,调用service方法并传递一个请求和响应对象。Servlet首先判断该请求是
GET操作还是POST操作。然后它调用下面的一个方法: doGet或 doPost。如果请求是GET就调用
doGet方法,如果请求是POST就调用doPost方法。
doGet和doPost都接受请求(HttpServletRequest
)和响应(HttpServletResponse
)。
get和post这是http协议的两种方法,另外还有head, delete等
这两种方法有本质的区别,get只有一个流,参数附加在url后,大小个数有严格限制且只能是字符
串。post的参数是通过另外的流传递的,不通过url,所以可以很大,也可以传递二进制数据,如文件
的上传。
在servlet开发中,以doGet()
和doPost()
分别处理get和post方法。
另外还有一个doService()
,它是一个调度方法,当一个请求发生时,首先执行doService()
,不管是
get还是post。在HttpServlet这个基类中实现了一个角度,首先判断是请求时get还是post,如果是
get就调用doGet(),如果是post就调用doPost()。你也可以直接过载doService()方法,这样你可以
不管是get还是post。都会执行这个方法。
service()
是在javax.servlet.Servlet接口中定义的,在 javax.servlet.GenericServlet 中实现了这个
接口,而doGet/doPost则是在javax.servlet.http.HttpServlet中实现的,
javax.servlet.http.HttpServlet是 javax.servlet.GenericServlet 的子类。所有可以这样理解,其
实所有的请求均首先由service()
进行处理,而在javax.servlet.http.HttpServlet的service()方
法中,主要做的事情就是判断请求类型是Get还是 Post,然后调用对应的doGet/doPost 执行.
doGet:处理GET请求
doPost:处理POST请求
doPut:处理PUT请求
doDelete:处理DELETE请求
doHead:处理HEAD请求
doOptions:处理OPTIONS请求
doTrace:处理TRACE请求通常情况