最近面试,问了Servlet是什么,当时也没想那么多,感觉知道怎么用,用在那一层,用什么语言实现,说下与JSP的区别就可以了,但是从面试的结果来看,面试官好像不是很认可,我们不能改变别人,只能让自己无懈可击,所以在网上书上找了些资料总结一下,感觉自己写一下才是自己的东西。
一.什么是Servlet
简单的说Servlet使用Java语言实现的程序,运行于支持Java语言的Web服务器或者应用服务器中。Servlet先于JSP出现,提供和客户端动态交互的功能。Servlet可以处理来自客户端的HTTP请求,并生成响应返回给客户端。
Servlet对于Web服务器而言,就好像是Java Applet对于Web浏览器,Servlet需要加在到Web服务器并在Web服务器内执行。
使用Servlet的基本流程如下:
客户端通过HTTP提出请求。
Web服务器接受改请求并将其发给servlet。如果这个servlet尚未被加载,Web服务器将把它加载到Java虚拟机并且执行它。
Servlet将接收该HTTP请求执行某种处理。
Servlet将向Web服务器返回应答。
Web服务器将从servlet收到的应答发送给客户端。
Java Servlet API 是Servlet容器(tomcat)和Servlet之间的接口,它定义了一个Servlet的各种方法,还定义了Servlet容器传给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以我们在编写Servlet时,需要实现Servlet接口,按照其规定进行操作。
二.Servlet的优点:
1.可以移植性:
由于Servlet是用Java语言编写的,因此它可以在不同的操作系统和服务器上移植。
2.安全:
Servlet也具有类型检查特征,并利用Java的垃圾收集和没有指针的设计,使得Servlet避免了内存管理等问题。
3.高效:
Servlet加载执行后会常驻服务器内存中,当再次受到客户端的请求时,服务器会产生新的线程而不是进程为客户端服务,这样就提高了响应速度。
三.编写Servlet
在前面,我们已经知道了Servlet是什么,为什么需要Servlet?(为了实现动态网页,而不是显示静态网页),tomcat和Servlet的关系?等问题。现在手动编写一个Servlet。
1.创建一个MyServlet继承HttpServlet,重写doGet和doPost方法,也就是看请求的方法是get还是post,然后不同的处理方式来处理请求:
2.在Web.xml中配置MyServlet,为什么需要配置?让浏览器发出的请求知道到达那个servlet,也就是让tomcat将封装好的request找到对应的servlet让其使用。
配置四个东西:
配置之后,浏览器是如何通过我们配置的信息来找到对应的servlet的。
按照步骤,首先浏览器通过http://localhost:8080/test01/MyServlet来找到web.xml中的url-parttern,这就是第一步,匹配到了url-parttern后,就会找到第二步servlet的名字MyServlet,知道了名字,就可以通过Servlet-name找到第三步,到了第三步,也就能够知道Servlet的位置了。然后到其中找到对应的处理方式进行处理。
3.实验,验证上面配置成功。
补充:
利用Eclipse创建MyServlet
1.右击项目,在new选项中有直接新建servlet的选项。
2.配置MyServlet类中的信息
3.配置web.xml中的Servlet信息
4.查看MyServlet01类中的代码和Web.xml,其中的配置跟手动的配置是一样的,只是用图形化界面,让我们更方便的创建servlet而产生的。
四.Servlet的生命周期:
Servlet的生命周期可以概括为以下几个阶段:
1)当客户端第一次请求Servlet时,Servlet被加载到内存中,容器会创建Servlet实例,并调用其init()方法进行初始化工作。
2)容器创建请求对象和响应对象,然后调用Servlet的service()方法为客户端提供服务。
3)当Servlet不再被需要时,容器调用Servlet的destory()方法将Servlet实例销毁。
当客户端请求的Servlet已经存在于服务器内存时,容器会创建信的线程调用service()方法响应客户端请求。在Servlet的整个生命周期中,init()方法和destory()方法只会被调用一次。
五.四个重点对象。ServletConfig;ServletContext;request;response
讲解四大类:Servlet对象,ServletContext对象,request对象,response对象
ServletConfig对象
获取途径:getServletConfig();
功能:上面大概提及了下,能用到四个东西:
getServletName();//获取servlet的名称,也就是我们在web.xml中配置的servlet-name
getServletContext();//获取ServletContext对象,该对象的作用看下面讲解;
getInitParameter(String);//获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的知识在该servlet下的初始化参数。
getInitParameterNames();//获取在Servlet中所有初始化参数的名字,也就是key值,可以通过key值,来找到各个初始化参数的value值。注意发挥的是枚举类型。
<br /> <br /> <br /> 注意:在上面我们所分析的源码过程中,我们就知道,其实可以不用先获得ServletConfig,然后在获取各个参数,可以直接使用其它方法,比如上面我们用的ServletConfig().getServletName();可以直接写成getServletName();而不用在获取ServletConfig();了,原因就是在GenericServlet中,已经帮我们获取了这些数据,我哦们只需要直接拿就行了。<br /> <br /> ServletContext对象<br /> 获取途径:<br /> getServletContext();getServletConfig().getServletContext();//这两种获取方式的区别就跟上面的解释一样,第一种是直接拿,在GenericServlet中已经帮我们用getServletConfig.getServletContext();拿到了ServletContext。我们只需要直接获取就行了,第二种就相当于我们自己在获取一遍,两种读是一样的。<br /> 功能:tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web匹配公共信息等,通俗点讲,就是一个web项目,就存在一个ServletContext实例,每个Servlet读可以访问到它。<br /> 1.web项目中共享数据,getAttribute(String name),setAttribute(String name,Object obj),removeAttribute(String name)<br /> setAttribute(String name,Object obj)在web项目范围内存放内容,以便让在web项目中所有的servlet读能访问到。<br /> getAttribute(String name)通过制定名称获得内容<br /> removeAttribute(String name)通过制定名称移除内容<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> 2.整个web项目初始化参数//这个就是全局初始化参数,每个Servlet中都能获取到该初始化值。<br /> getInitParameter(String name) //通过指定名称获取初始化值<br /> getInitParameterNames() //获得枚举类型<br /> web.xml配置 整个web项目的初始化<br /> <br /> <br /> <br /> <br /> 3.获取web项目资源<br /> 1)获取web项目下指定资源的路径:<br /> getServletContext().getRealPath("/WEB-INF/web.xml");<br /> <br /> <br /> <br /> 2)获取web项目下指定资源的内容,返回的是字节输入流。InputStream.getResourceAsStream(java.lang.String path)<br /> 前提知识:需要了解流。<br /> <br /> Request对象<br /> request对象就是将请求文本封装而成的对象,所以通过request能获得请求文本中的宿友内容,请求头,请求体,请求行。<br /> <br /> <br /> <br /> 1.请求行内容的获取:<br /> <br />  <br /> <br /> <br /> <br /> 2.请求头的获取:<br /> 随便百度一个东西,然后查看的请求头,包括下面这些内容,稍作了解。<br /> <br /> <br /> String getHeader(java.lang.String name)获得指定头内容String<br /> System.out.println(req.getHeader("Accept-Language"));<br /> 3.请求体的获取--请求参数的获取<br /> 分为两种,一种get请求,一种post请求<br /> get请求参数:http://localhost:8080/test01/MyServlet?username = jack & password = 1234<br /> post请求参数:<form method = "post"><input type="text" name="username"><br /> String request.getParameter(String)获得指定名称,一个请求参数值。<br /> String[] request.getParameterValues(String)获得指定名称,一个请求参数值。<br /> 4.请求转发<br /> request.getRequestDispatcher(String path).forward(request,response);<br /> //path:转发后跳转的页面,这里不管用不用“/”开头,都是以web项目根开始,因为这是请求转发,请求 //转发只局限与在同一个web项目下使用,所以这里一直都是从web项目根下开始的。<br /> web项目根就是从该web项目名开始,所以我们请求转发时,只需接着项目名后面需要访问的路径写就行了。<br /> 特点:浏览器中的URL不会改变,也就是浏览器不知道服务器做了什么,是服务器帮我们跳转页面的,并且 在转发后的页面,能够继续使用原先的request,因为是原先的request,所以request域中的属性都可 以继续获取到。<br /> <br /> response对象<br /> <br /> <br /> <br /> 常用的一个方法:response.setHeader(java.lang.String name,java.lang.String value)<br /> 设置指定的头,一般常用。<br /> 例如:设置每隔3秒就自动刷新一次,<br /> response.setHeader("Refresh",3);<br /> <br /> <br /> <br /> <br /> 这样可以看到现在时间的秒数,会发现每隔三秒就会自动刷新一次页面。<br /> 这个最重要的一个就是重定向,其它的一些操作都被装到response对象中了<br /> 重定向(页面跳转)<br /> 方式一:手动方案<br /> response.setStatus(302); //状态码302就代表重定向<br /> response.setHeader("location","http://www.baidu.com");<br /> 方式二:使用封装好的,通过response.sendRedirect("http://www.baidu.com");<br /> 特点:<br /> 服务器告诉浏览器要跳转的页面,是浏览器主动跳转的页面,浏览器知道,浏览器中的地址栏url也会改变,是浏览 器重新发起一个请求到另外一个页面,所以request是重新发起的,跟请求转发不一样。<br /> 注意:response.sendRendirect(path);<br /> 第一种:response.sendRedirect("/test01/MyServlet01"); //使用了“/”开头,说明是从web站点根开始,所以需 要写test01/MyServlet01 <br /> 第二种:response.sendRedirect("MyServlet01"); //没有使用"/"开头,说明从web项目开始,那么就无需写 test01了。<br /> 重定向没有任何局限,可以重定向web项目内的任何路径,也可以访问别的web项目中的路径,并且这里就用"/"区分开来,如果使用了"/"开头,就说明我要重新开始定位了,不访问刚才的web项目,自己写项目名,如果没有使用"/ "开始,那么就知道是访问刚才那个web项目 下的servlet,就可以省略项目名了。就是这样来区别的。<br />
Servlet处理请求的流程:
1) 客户端在浏览器的地址栏中输入一个请求的URL,按回车后就向服务器端发起一个http request(由浏览器生成)。<br /> 2) 服务器端的Web Server首先接受到请求,并将请求转交给容器,容器会根据请求的URL去调用客户端要访问的Servlet。<br /> 3) 容器会根据web.xml中对Servlet的描述去查找要访问的Servlet,若找到,将此Servlet<br />装载进虚拟机并实例化(第一次访问),然后调用Servlet实例中的service方法处理请求,并分配一个线程去执行。<br />注: 当第二次去访问同一个Servlet时,若容器判断到该Servlet已经被装载并实例化,<br />那么容器就不会再去创建一个新的Servlet实例,直接调用原来那个Servlet实例中的service方法<br />来处理请求。<br /> 4) 若没有查找到,直接返回一个404的错误代码到客户端,表示访问的资源不存在。<br /> <br /> <br />
Servlet处理响应:
设置HTTP状态码
设置HTTP响应头
HttpServletResponse对象用于操纵响应的HTTP头
目的用于告诉客户端
–发送回来的内容的类型
–有多少内容正被发送
常用的方法:
setContentType(String mimetype);
addCookie(Cookie c);
发送内容的服务器的类型
设置HTTP消息体
HttpServletResponse对象负责将信息返回给客户端
HttpServletResponse对象只产生一个空的HTTP响应
传回自定义的内容需要使用getWriter()或者getOutputStream()方法
–传送普通文本
–传送二进制内容
请求重定向和自动刷新页面
重定向的原理:
<br />  <br /> <br />使用sendRedirect(String URL)方法实现重定向,<br /> <br />在指定时间内自动刷新当前页或到一个新的页面<br />根据时间来控制响应<br />想在响应中有一个短时间的暂停 <br />response.setHeader("Refresh", "time; URL=url" );<br /> 总结:<br />请求URL时HTTP发出了多个请求<br />状态码告诉浏览器发送的内容及格式状态<br />Servlet API与容器进行通讯<br />HttpServletResponse定义的常量来避免直接使用整数<br />在通过PrintWriter对象发送任何内容之前先调用 HttpServletResponse的setStatus()方法<br />为了让Servlet发挥最大的效能,HttpServletResponse对象用于操纵响应的HTTP头<br />getWrite()或者getOutputStream()方法传送文本或者二进制内容给客户端<br />sendRedirect方法实现重定向<br />HTTP响应头“Refresh”会根据时间来控制响应