一、Servlet是什么?JSP是什么?它们的联系与区别是什么?
Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是指任何实现Servlet接口的类,我们一般理解的为后者。Servlet的作用是接收浏览器发给服务器的请求Request,经过处理后,将返回响应Response给浏览器。
JSP是一种后端脚本语言,是为了解决Html是静态的,而Servlet输出动态页面又太复杂的问题而出现的,通过JSP标签、动作、内置对象提供方便的生成动态网页功能,是一种后端渲染技术。
联系和区别:
1、JSP其实就是基于Servlet实现的,JSP生命周期:
(1)解析阶段:Servlet容器解析JSP代码,如果有错则报错;
(2)翻译阶段:Servlet容器翻译JSP代码为Servlet源文件;
(3)编译阶段:Servlet容器编译Servlet源代码,生成Servlet字节码类文件;
……剩下就是Servlet的生命周期,会在下面介绍。
2、JSP注重视图显示、Servlet注重控制,在传统的MVC架构中,JSP是View,Servlet是Controller。
3、JSP在修改静态内容时不需要重新编译。
二、Servlet API
核心包:javax.servlet与javax.servlet.http
核心类\接口:
1、javax.servlet.Servlet:Servlet核心接口,定义了init()、service()、destroy()有关Servlet 生命周期的方法。
2、javax.servlet.ServletConfig:Servlet配置接口,定义了getServletContext(),主要用于获取ServletContext实例。
3、javax.servlet.ServletContex:Servlet上下文接口,相当于Web应用的总管家。定义了getAtrribute(String name)、setAttribute(String name, Object object)、getInitParameter(String name)、getContextPath()、getRequestDispatcher(String path)等方法,主要用于应用间通信,获取web应用资源、访问服务器文件资源、输出日志等功能。
4、javax.servlet.GenericServlet:该包下唯一抽象类,实现了ServletConfig、Servlet接口,为两个接口方法提供默认的实现方式。
三、如何使用Servlet
1、继承GenericServlet类(通用)
(1)GenericServlet类有一个关键的设计,定义了一个私有的ServletConfig成员变量,在init()方法中,由Servlet容器传入ServletConfig对象与之匹配。
(2)GenericServlet类中唯一一个抽象方法是Service方法,子类必须实现Service方法,以为用户提供特定的服务。
2、继承HttpServlet类,是GenericServlet的子类,重写了Service方法,提供了HTTP的相关服务实现。用户需要做的事,根据实际情况,重写doPost()、doGet()等方法。
四、Servlet生命周期
1、初始化阶段
(1)将编译后的servlet字节码文件读入内存;
(2)Servlet容器创建ServletConfig,并与ServletContext对象建立关联关系,即调用ServletConfig的getServletContext()方法会获取到ServletContext对象。
(3)创建Servlet对象。
(4)调用GenericServlet的init(ServletConfig config)方法,建立Servlet对象与ServletConfig对象的关联。
初始化时机:
(1)未配置属性的Servlet被客户端首次访问时才会被初始化。
(2)配置属性的Servlet在web容器启动时就会按配置的数值按顺序被初始化。
2、运行时阶段,调用Servlet类的Service()方法。当Servlet将响应返回后,Servlet容器会销毁HttpServletRequest对象与HttpServletResponse对象。
3、销毁阶段,在web容器终止时,会先调用所有Servlet的destroy()方法。
五、ServletContextListener监视器
通过实现ServletContextListener接口,实现contextInitialized(ServletContextEvent sce)与contextDestroyed(ServletContextEvent sce)方法,其中可以通过参数的getServletCotext()方法获取ServletContext对象以完成监听工作。
注意:Servlet、Listener、Filter三者的加载顺序为:Listener>Filter>Servlet
六、请求转发与重定向特点以及它们的区别
1、请求转发:HttpServletRequest.getRequestDispatcher(String path).forward(request, response);
特点:
(1)服务器内部转发,浏览器URL不会改变,对用户透明。整体体现的是一个请求与一个响应。
(2)请求转发前,会清空响应缓冲区。
(3)如果转发的为Servlet或JSP(JSP也是Servlet),就会直接将当前HttpServletRequest对象与HttpServletResponse对象转交给目标Servlet或JSP的Service方法,处理后将响应结果返回给前端。
(4)如果转发的为Html静态文档,则就读取文档中数据发送到前端。
(5)请求转发不会执行转发方法之后的代码
2、重定向:HttpServletResponse.sendRedirect(String path);
特点:
(1)客户端外部转发,浏览器URL会发生改变。在Servlet调用重定向后,会返回302临时重定向状态码,响应内容为待重定向路径。然后,浏览器就会再次发出请求,请求路径为刚刚相应内容中的路径。整体体现的是两个请求与两个响应。
(2)重定向前,也会清空响应缓冲区。
(3)而重定向会执行重定向方法后的代码
区别汇总:
1、请求转发在服务端完成,重定向在客户端完成。
2、请求转发速度快,重定向速度慢。
3、请求转发是一次请求,一次响应;而重定向是两次请求,两次响应。
4、请求转发不会执行转发方法之后的代码;而重定向会执行重定向方法后的代码。
5、请求转发URL不会发生改变;而重定向URL会发生改变。
6、请求转发必须在同一台服务器下完成;而重定向可以在不同服务器下完成。
注意:请求转发与重定向的资源路径表示是有区别的
请求转发的path一般使用"/资源名",这里的 '/' 就代表了项目根路径 "http://localhost:8080/项目名/";
而重定向的path一般使用context.getContextPath() + "/资源名",不能直接使用"/资源名",因为在重定向中"/"代表了Web站点的根路径"http://localhost:8080"。
七、如何访问Servlet容器中的其他Web应用
在Service中编写如下代码:
ServletContext otherContext = context.getContext("/otherApp");
otherContext.getRequestDispatcher("/资源名").forward(request, response);
八、如何保证Servlet线程安全
1、保证变量作用域合理,线程私有的变量要定义在方法中。
2、共享变量要用保证线程安全,可以使用加锁、atomic类、volatile关键字实现。
九、JSP九大内置对象(详情可参看博客http://blog.csdn.net/zhangliangzi/article/details/49965209)
1、request对象——代表javax.servlet.http.HttpServletRequest对象
2、response对象——代表javax.servlet.http.HttpServletResponse对象
3、session对象——代表javax.servlet.http.HttpSession对象
4、application对象——代表javax.servlet.ServletContext对象
5、pageContext对象——代表javax.servlet.jsp.pageContext对象
6、page对象——代表this
7、config对象——代表javax.servlet.ServletConfig对象
8、out对象——代表javax.servlet.jsp.jspWriter对象
9、exception对象——代表java.lang.Exception对象
十、Session与Cookie
为什么要使用Session与Cookie:Web应用一般使用HTTP协议传输数据,HTTP是一种无状态协议,完成数据交换后客户端与服务端的连接就会关闭。所以服务端无法根据HTTP请求区分请求者。但区分请求者身份是是非常有意义的,比如一个购物车系统,添加一件商品到购物车,服务端必须区分是哪个用户添加的商品;而且如果一段时间内某个用户多次发出请求,那么就可以对用户的相关数据进行缓存,提高访问效率。这都可以通过Session与Cookie实现。
Cookie与Session的区别在于:Cookie存在于客户端,Session存在于服务端。Cookie的存储数量是有限制的,安全性也更差。Session是基于Cookie实现的,但服务端为了获得较高的存取速度,会把Session放到内存中,在高并发环境下会增大服务器压力。
Cookie机制:
Cookie基于浏览器的支持,具有“不可跨域名性”,浏览器只能访问当前域名网站的Cookie。
Cookie的常见属性有如下几个:
String name——Cookie的名称,一旦创建便不能更改;
Object value——Cookie的值;
int maxAge——Cookie失效时间,单位为秒;
boolean secure——Cookie是否使用HTTPS或SSL的安全数据,传输前要加密,默认为false
String domain——Cookie的作用域名,比如设置为".google.com",第一个字符必须为点,代表着以google.com为结尾的域名才可以访问该Cookie。
String path——Cookie的作用项目名,比如设置为"/webApp/",最后一个字符必须为斜线,代表着contextPath为"/webApp"的程序才可以访问该Cookie。
Cookie使用:
Cookie cookie = new Cookie("name","StringValue"); // 新建Cookie
Cookie[] cookies = request.getCookie(); //获取客户端提交的所有cookie
cookie.setDomain(".leeon.top"); //设置作用域名
cookie.setPath("/testApp/"); //设置作用项目路径
cookie.setSecure(true); //设置安全属性
cookie.setMaxAge(Integer.MAX_VALUE); // 设置生命周期为永久;
response.addCookie(cookie); // 输出到客户端
在网页URL栏输入:javascript:alert (document. cookie) 可输出当前页面cookie
注意:
Coookie不能修改与删除,修改可通过创建同名Cookie后覆盖原Coolkie;删除可通过设置setMaxAge方法中的参数为0。
setMaxAge方法中的参如果设置为负值,则为存放在内存中的临时Cookie,关闭浏览器即失效;如果设置为0,则代表使Cookie失效。
Session会话机制:
Session基于Cookie的工作流程:
(1)当用户通过浏览器进程第一次请求一个支持会话的资源时,Servlet容器会为这个会话创建一个HttpSession对象,并为其分配一个唯一的ID,当前会话就此开始。
(2)把这个唯一的ID以name为JSESSIONID的Cookie形式添加到响应中,返回给客户端保存。(当Cookie被禁用时,使用URL重写机制,在URL后添加;jsessionid=XXX以传输HttpSession对象标识)
(3)当浏览器进程再次请求这个支持会话的资源时,会在请求头中加上一直保持着的JSESSIONID,Servlet容器会在HTTP请求头中自动查找这个Cookie(也可以通过HttpSession.getId()方法主动获取),如果找到,就取出对应HttpSession对象(其实用户第一次访问,也会进行相同的查询,因为查询不到,才会执行创建操作)。
Session使用:
HttpSession session = request.getSession(); //获取Session对象
session.setAtrribute("name", "StringValue");//加入session
session.getAttribute("name");//获取session
session.removeAtrribute("name");//删除session
session.setMaxInactiveInterval(int second);//设置超时时间,单位为秒,默认20分钟
session.getLastAccessedTime();//返回Session的最后活跃时间
Session持久化:
1、StandarManager是默认的Session Manager(用来管理Session)。它的实现机制是:当Tomcat服务器关闭或重启,或Web应用被重新加载时,会将内存中所有的HttpSession对象保存到文件系统中,默认的文件路径是:%CATALINA_HOME%\work\Catalina\\SESSIONS.ser
重启Tomcat后,Tomcat服务器把SESSIONS.ser中的持久化HttpSession对象加载到内存中。
2、PersistentManager能够把HttpSession对象保存到Session Store中,它提供了比较StandarManager更灵活的管理功能,具有容错能力,控制内存中HttpSession对象的数目等。
Tomcat实现Session Store的接口为org.apache.catalina.session.Store,目前提供了两个实现这一接口的类:org.apache.catalina.session.FileStore和org.apache.catalina.session.JDBCStore。FileStore会将HttpSession对象保存到文件系统中;而JDBCStore则将HttpSession对象保存到数据库表中。