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