- 浏览: 89527 次
文章分类
最新评论
第九章 会话跟踪
核心方法:
1.只能在发送任何文档内容到客户程序之前调用request.getSession,在之后调用,则会影响到后面的响应。
警告:
1.如果我们使用URL重写进行会话跟踪,我们的页面最好不要使用静态页面,或者静态页面至少不包含指向自身站点的动态链接。
学习笔记
一、会话跟踪的需求
1.首先什么是会话:会话首先是一个过程,引用百度百科的说法:
而我的理解是会话还有一层概念:就是会话就是一个类似Map的对象(session)。
那么什么是会话跟踪,我的理解就是利用会话去跟踪用户访问这个网站的一系列操作。联想购物车来理解这个会话跟踪的概念。
2.HTTP是“无状态”的协议,也就是没有像FTP的那种连接,断开的状态之分,客户每次读取web页面,都是打开web服务器的单独的连接,而且,服务器也不自动维护客户的上下文信息(可以理解为:服务器也没有这么多的精力去维护)。
3.这里要理解一下上下文,上下文我们可以把它理解为一个共享对象。上下文中的名字都由一个相关联的对象组成,同一个应用程序中任何程序都可以从一个上下文中通过名字获得相关联的对象,一个应用程序中的SERVLET还经常需要在一个HTTP请求外来共享某些信息,因此为了管理这些对象的共享周期,容器提供了3个标准的上下文:应用程序上下文,HTTP请求上下文,会话上下文。一个页面范围内的上下文仅仅对一个页面有效。在页面范围内的对象不可能和其他JSP和SERVLET共享。具体可以参见
http://fanlifeng.iteye.com/blog/690827
4.如何把一个用户之前创建购物车和用户进行关联,类似的,如何知道购物车已经放了哪些东西。可以使用四种解决方式,
a.cookie,每一个用户有一个特殊的ID,通过这个ID我们可以找到存放在服务器上的用户信息。但是,它所需的工作量比较大,需要我们提取cookie,并且确定空闲会话什么时候过期,还要把散列表和请求关联起来(就是根据cookie中的会话ID与sessionInfo散列表中的用户具体数据关联起来,这里实际上使用的是两个表,一个是会话ID和用户关联起来的表,一个是存放具体用户数据的表,也就是说我们根据关键码获得这个用户数据的存放位置,然后我们去具体的这个位置查找相应的表得出用户数据),并生成唯一的会话标识符。
b.使用URL链接,这种方式就是在URL后加上一个用户的ID,通过该ID,我们可以得到服务器上的用户信息。比如http://host/path/file.html;jsessionid=a1234 这样可以解决浏览器不支持cookie或在用户禁用cookie的情况下。但是,我们同样遇到了工作量大的问题。其次,我们就必须在所以涉及用户信息的URL中加上用户的标识符,这样我们就不能使用静态页面(至少不能有任何链接到站点动态页面的链接,因为我们无法通过静态页面把用户信息加到动态页面中去),因为静态页面不需要通过服务器加载,所以我们就不能通过服务器把用户名加到URL上去。静态页面是后缀为html或htm的页面。c.隐藏的表单域,使用
,这个高层建筑在cookie和重写URL之上,这个方法十分的方便。
二、会话跟踪基础
如何使用会话?见如下四步
(一)访问与当前请求相关联的会话对象。request.getSession获取HttpSession 对象,该对象是一个简单的散列表。用来存储用户的相关数据。在后台,系统从cookie或附加的URL数据中提取出用户ID,之后以该ID为键,访问之前创建的HttpSession对象组成的表,但是,这些动作对程序员都是透明的,我们只需调用getSession,如果我们在输入cookie或附件URL信息中找不到会话ID,系统则会创建一个新的空会话,同时如果,我们使用cookie(默认),系统还会创建一个名为JSESSIONID的输出cookie,在其中存入唯一的值表示会话ID。因此只能在发送任何文档内容到客户程序之前调用request.getSession,在之后调用,则会影响到后面的响应。这里要注意request.getSession()等同于request.getSession(true);意思就是如果不存在会话,则创建一个新的会话,如果为request.getSession(false)代表我们只想打印出那些在会话中已经存在的信息。
(二)访问与会话相关联的信息
会话对象拥有内建的数据结构(散列表),其中存储任意数量的键和与键相关联的值。查找前些时候存储的值使用
(三)将信息与会话关联起来。
1.如果要指定信息,则需使用setAttribute。如果希望在这些值存储在会话之前执行边界效应,只需让希望与会话关联的对象实现HttpSessionBindingListener接口(也就是说如果提供给setAttribute的对象实现了HttpSessionBindingListener接口)。这样每次调用setAttribute方法设置它们中间的任何一个对象时,它的valueBound方法都会紧随其后调用。
2.通常,会话属性的类型只要是Object的就可以,但是如果我们使用的应用程序为物理服务器的集群所共享,系统需要能够将会话对象在机器间转移,如果我们的程序运行在这种环境中,并将web应用标记为可分布式执行,则必须满足额外的条件,会话的属性要实现Serializable接口,而这个序列化又是什么意思呢?序列化就是把一个对象的形态改变一下,使他能够存放到文件中,或者在网络上传输。比如读写文件需要序列化,RMI也需要。
(四)废弃会话数据
1.只移出自己编写的servlet创建的数据,removeAttribute("key")废弃与指定键关联的值。
2.删除整个会话:我们可以调用invalidate,将整个会话删除,但是这样会丢失用户的所有会话数据。而且要注意如果作废一个会话,有可能会破坏其他servlet或jsp页面正在使用的数据。
3.将用户从系统中注销,并删除他的所有会话:我们可以调用logout方法,将客户从web服务器中注销。同时废弃所有相关联的会话
四、浏览器会话与服务器会话
也就是存放在浏览器中的会话和存放在服务器中的会话
如果我们使用的会话cookie,当浏览器退出时就会造成会话中断,客户程序就不能再访问会话,但是服务器并不知道浏览器已经关闭,所以它还会把维护会话一定时间,就好像是超市的员工看到一个购物车旁边没有人就一定代表员工可以把购物车中的东西放在货架上一样。当客户访问的时间间隔超过getMaxInactiveInterval指定的时间之后,会话自动变为不活动状态,我们就可以删除该会话。同时如果我们明确告诉服务器删除会话或是将用户从系统中注销时,服务器就可以删除该会话。
五、对发往客户的URL进行编码
因为servlet容器(引擎)使用cookie作为会话跟踪的底层机制。但假定我们改使用URL重写,代码该如何更改。
我们有两种情况会使用自身站点的URL,这时我们就要检查是否使用了URL重写技术。从而把会话标识放在URL中
1.在servlet生成的web页面中含有嵌入的URL,我们应该将URL传递给HttpServletResponse的encodeURL方法,这个方法确定当前是否使用URL重写,仅在必要时附加会话信息。
2.第二种情况是在sendRedirect调用中。这时使用encodeRedirectURL
encodeURL的用法:
六显示客户访问计数的servlet
七简单购物车的实现
关键代码
核心方法:
1.只能在发送任何文档内容到客户程序之前调用request.getSession,在之后调用,则会影响到后面的响应。
警告:
1.如果我们使用URL重写进行会话跟踪,我们的页面最好不要使用静态页面,或者静态页面至少不包含指向自身站点的动态链接。
学习笔记
一、会话跟踪的需求
1.首先什么是会话:会话首先是一个过程,引用百度百科的说法:
引用
web会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。当然用户开不同的浏览器,其会话也不同
。这也就可以解释什么是会话级别的cookie了。
而我的理解是会话还有一层概念:就是会话就是一个类似Map的对象(session)。
那么什么是会话跟踪,我的理解就是利用会话去跟踪用户访问这个网站的一系列操作。联想购物车来理解这个会话跟踪的概念。
2.HTTP是“无状态”的协议,也就是没有像FTP的那种连接,断开的状态之分,客户每次读取web页面,都是打开web服务器的单独的连接,而且,服务器也不自动维护客户的上下文信息(可以理解为:服务器也没有这么多的精力去维护)。
3.这里要理解一下上下文,上下文我们可以把它理解为一个共享对象。上下文中的名字都由一个相关联的对象组成,同一个应用程序中任何程序都可以从一个上下文中通过名字获得相关联的对象,一个应用程序中的SERVLET还经常需要在一个HTTP请求外来共享某些信息,因此为了管理这些对象的共享周期,容器提供了3个标准的上下文:应用程序上下文,HTTP请求上下文,会话上下文。一个页面范围内的上下文仅仅对一个页面有效。在页面范围内的对象不可能和其他JSP和SERVLET共享。具体可以参见
http://fanlifeng.iteye.com/blog/690827
4.如何把一个用户之前创建购物车和用户进行关联,类似的,如何知道购物车已经放了哪些东西。可以使用四种解决方式,
a.cookie,每一个用户有一个特殊的ID,通过这个ID我们可以找到存放在服务器上的用户信息。但是,它所需的工作量比较大,需要我们提取cookie,并且确定空闲会话什么时候过期,还要把散列表和请求关联起来(就是根据cookie中的会话ID与sessionInfo散列表中的用户具体数据关联起来,这里实际上使用的是两个表,一个是会话ID和用户关联起来的表,一个是存放具体用户数据的表,也就是说我们根据关键码获得这个用户数据的存放位置,然后我们去具体的这个位置查找相应的表得出用户数据),并生成唯一的会话标识符。
b.使用URL链接,这种方式就是在URL后加上一个用户的ID,通过该ID,我们可以得到服务器上的用户信息。比如http://host/path/file.html;jsessionid=a1234 这样可以解决浏览器不支持cookie或在用户禁用cookie的情况下。但是,我们同样遇到了工作量大的问题。其次,我们就必须在所以涉及用户信息的URL中加上用户的标识符,这样我们就不能使用静态页面(至少不能有任何链接到站点动态页面的链接,因为我们无法通过静态页面把用户信息加到动态页面中去),因为静态页面不需要通过服务器加载,所以我们就不能通过服务器把用户名加到URL上去。静态页面是后缀为html或htm的页面。c.隐藏的表单域,使用
<input type = "HIDDEN" name = "session" value = "a1234">但是我们只有在提交表单时才使用这种方法,而且<a href>不能产生表单提交的效果。d.我们可以使用会话跟踪解决方案,HttpSession API
,这个高层建筑在cookie和重写URL之上,这个方法十分的方便。
二、会话跟踪基础
如何使用会话?见如下四步
(一)访问与当前请求相关联的会话对象。request.getSession获取HttpSession 对象,该对象是一个简单的散列表。用来存储用户的相关数据。在后台,系统从cookie或附加的URL数据中提取出用户ID,之后以该ID为键,访问之前创建的HttpSession对象组成的表,但是,这些动作对程序员都是透明的,我们只需调用getSession,如果我们在输入cookie或附件URL信息中找不到会话ID,系统则会创建一个新的空会话,同时如果,我们使用cookie(默认),系统还会创建一个名为JSESSIONID的输出cookie,在其中存入唯一的值表示会话ID。因此只能在发送任何文档内容到客户程序之前调用request.getSession,在之后调用,则会影响到后面的响应。这里要注意request.getSession()等同于request.getSession(true);意思就是如果不存在会话,则创建一个新的会话,如果为request.getSession(false)代表我们只想打印出那些在会话中已经存在的信息。
(二)访问与会话相关联的信息
会话对象拥有内建的数据结构(散列表),其中存储任意数量的键和与键相关联的值。查找前些时候存储的值使用
session.getAttribute("key")。 HttpSession session = request.getSession(); SomeClass value = (SomeClass)session.getAttribute("someIdentifier"); if(value ==null){ value = new SomeClass(...); session.setAttribute("someIdentifier",value); } doSomethingWith(value);
(三)将信息与会话关联起来。
1.如果要指定信息,则需使用setAttribute。如果希望在这些值存储在会话之前执行边界效应,只需让希望与会话关联的对象实现HttpSessionBindingListener接口(也就是说如果提供给setAttribute的对象实现了HttpSessionBindingListener接口)。这样每次调用setAttribute方法设置它们中间的任何一个对象时,它的valueBound方法都会紧随其后调用。
2.通常,会话属性的类型只要是Object的就可以,但是如果我们使用的应用程序为物理服务器的集群所共享,系统需要能够将会话对象在机器间转移,如果我们的程序运行在这种环境中,并将web应用标记为可分布式执行,则必须满足额外的条件,会话的属性要实现Serializable接口,而这个序列化又是什么意思呢?序列化就是把一个对象的形态改变一下,使他能够存放到文件中,或者在网络上传输。比如读写文件需要序列化,RMI也需要。
(四)废弃会话数据
1.只移出自己编写的servlet创建的数据,removeAttribute("key")废弃与指定键关联的值。
2.删除整个会话:我们可以调用invalidate,将整个会话删除,但是这样会丢失用户的所有会话数据。而且要注意如果作废一个会话,有可能会破坏其他servlet或jsp页面正在使用的数据。
3.将用户从系统中注销,并删除他的所有会话:我们可以调用logout方法,将客户从web服务器中注销。同时废弃所有相关联的会话
四、浏览器会话与服务器会话
也就是存放在浏览器中的会话和存放在服务器中的会话
如果我们使用的会话cookie,当浏览器退出时就会造成会话中断,客户程序就不能再访问会话,但是服务器并不知道浏览器已经关闭,所以它还会把维护会话一定时间,就好像是超市的员工看到一个购物车旁边没有人就一定代表员工可以把购物车中的东西放在货架上一样。当客户访问的时间间隔超过getMaxInactiveInterval指定的时间之后,会话自动变为不活动状态,我们就可以删除该会话。同时如果我们明确告诉服务器删除会话或是将用户从系统中注销时,服务器就可以删除该会话。
五、对发往客户的URL进行编码
因为servlet容器(引擎)使用cookie作为会话跟踪的底层机制。但假定我们改使用URL重写,代码该如何更改。
我们有两种情况会使用自身站点的URL,这时我们就要检查是否使用了URL重写技术。从而把会话标识放在URL中
1.在servlet生成的web页面中含有嵌入的URL,我们应该将URL传递给HttpServletResponse的encodeURL方法,这个方法确定当前是否使用URL重写,仅在必要时附加会话信息。
String originalURL = someRelativeOrAbsoluteURL; String encodedURL = response.encodeURL(originalURL); out.println("<a href =\""+encodedURL+"\">"...</a>");
2.第二种情况是在sendRedirect调用中。这时使用encodeRedirectURL
String originalURL = someURL; String encodedURL = response.encodeRedirectURL(originalURL); response.sendRedirect(encodedURL);
encodeURL的用法:
引用
Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.
六显示客户访问计数的servlet
HttpSession session = request.getSession(); Integer accessCount = (Integer)session.getAttribute("accessCount"); String heading = ""; if(accessCount==null){ heading = "Welcome new User"; accessCount = new Integer(0); }else{ heading = "Welcome Back"; accessCount = new Integer(accessCount.intValue()+1); } session.setAttribute("accessCount", accessCount); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.println("<H1>"+heading+"</H1>"); out.println("<H1>"+cookieID+"</H1>"); out.println("<table>"); out.println("<tr><td>SessionID:"+session.getId()+"</td><tr>"); out.println("<tr><td>CreationTime:"+new Date(session.getCreationTime())+"</td></tr>"); out.println("<tr><td>Time Of Last Access:"+new Date(session.getLastAccessedTime ())+"</td></tr>"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close();
七简单购物车的实现
关键代码
<H4>Order Form</H4> <form action = "coreservlets.showItems" > <table> <tr> <td>New Item to Order:</td> <td><input type = "textfield" name = "itemName" ></td> </tr> <tr> <td><input type = "submit" value = "submit"></td> <td><input type = "reset" value = "reset"></td> </tr> </table> </form> String itemName = request.getParameter("itemName"); String title =null; ArrayList<String>itemNames=null; HttpSession session = request.getSession(); itemNames = (ArrayList<String>)session.getAttribute("itemNames"); if(itemNames==null||itemNames.size()==0){ title = "Please select your goods"; itemNames = new ArrayList<String>(); }else{ if(itemName==null||itemName.equals("")){ title = "Please select your goods,and this is your selected goods"; }else{ title = "This is your selected goods"; } } itemNames.add(itemName); session.setAttribute("itemNames", itemNames); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.println("<h1>"+title+"</h1>"); out.println("<table>"); for(int i = 0 ; i < itemNames.size() ;i++){ out.println("<tr><td>"+itemNames.get(i)+"</td></tr>"); } out.println("</table>"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close();
发表评论
-
servlet和jsp核心编程(第2版)第十六章 简化对Java代码的访问:jsp2.0表达式语言学习笔记
2012-08-23 21:49 772第十六章:简化对Java代 ... -
servlet和jsp核心编程(第2版)第十五章servlet和JSP的集成,模型-视图-控制器构架
2012-08-23 14:59 780第十五章:servlet和JSP的集成,模型-视图-控制器构架 ... -
servlet和jsp核心编程(第2版)第十四章 JavaBean组件在JSP文档中的应用 学习笔记
2012-08-21 11:55 737第十四章 JavaBean组件在JSP文档中的应用 一、bea ... -
servlet和jsp核心编程(第2版)第十三章 在JSP页面中包含文件和applet学习笔记
2012-08-20 15:53 891第十三章 在JSP页面中包 ... -
servlet和jsp核心编程(第2版)第十二章page指令学习笔记
2012-08-19 17:00 801第十二章 控制所生成的servlet的结构:JSP page指 ... -
servlet和jsp核心编程(第2版)第十一章jsp脚本元素的调用学习笔记
2012-08-18 21:09 851第十一章 用JSP脚本元素 ... -
servlet和jsp核心编程(第2版)第十章jsp技术概述学习笔记
2012-08-18 10:37 723第十章jsp技术概述 学习笔记: 一servlet和jsp的区 ... -
servlet和jsp核心编程(第2版)第八章cookie管理学习笔记
2012-08-08 12:27 883第八章 cookie管理 核心方法: 1.在创建cookie对 ... -
servlet和jsp核心编程(第2版)第七章服务器响应的生成:HTTP响应报头学习笔记
2012-08-06 17:45 783第七章:服务器响应的 ... -
servlet和jsp核心编程(第2版)第六章服务器响应的生成:HTTP状态代码学习笔记
2012-08-05 10:52 777第六章:服务器响应的生成:HTTP状态代码 核心方法: 1.在 ... -
servlet和jsp核心编程(第2版)第五章客户请求的处理:HTTP请求报头学习笔记
2012-08-02 21:36 734第五章客户请求的处理:HTTP请求报头 核心方法: 1.在使用 ... -
servlet和jsp核心编程(第2版)第四章客户请求的处理,表单数据学习笔记
2012-07-31 16:05 1264第四章学习笔记 客户请 ... -
servlet和jsp核心编程(第2版)第三章servlet基础学习笔记
2012-07-29 10:43 744第三章:servlet基础 核心方法: 1.使用HTML验证器 ...
相关推荐
第二篇为“Servlet核心技术”,主要讲述Servlet的技术特点、请求和响应、数据共享、会话跟踪等技术;第三篇为“JSP技术基础”,主要讲述JSP的基本语法和内建对象及JSP和Servlet的集成,JavaBean和表达式语言;第四篇...
**JSP(Java Server Pages)与Servlet是Java Web开发中的两个核心技术,它们在构建动态网页和处理客户端请求方面起着至关重要的作用。** **JSP技术:** JSP是一种服务器端脚本语言,用于创建动态网页。它允许开发者...
本书以其独特的学习风格,深入浅出地介绍了Servlet和JSP(JavaServer Pages)这两项核心的Java Web开发技术。 Servlet是Java平台上的一个标准API,用于构建动态Web应用程序。它允许开发者通过Java代码来处理HTTP...
**JSP(JavaServer Pages)/Servlet 知识详解** JSP 和 Servlet 是 ...以上就是关于 JSP 和 Servlet 的核心知识点,希望对你学习和理解这些技术有所帮助。通过深入学习和实践,你可以创建出高效、稳定的 Web 应用。
【标题】:“韩顺平servlet和jsp课堂笔记”涵盖了Web开发中的两个核心技术——Servlet和JSP(JavaServer Pages)的学习资料。韩顺平是一位知名的IT教育专家,他的课程通常深入浅出,适合初学者入门及进阶者提升。 ...
由于这部分内容是电子书中的学习笔记,电子书的内容并未直接给出,因此只能根据电子书的标题“JSP&Servlet学习笔记”和描述来推测可能涉及的知识点,而没有具体的电子书内容可以分析。如需进一步学习,建议查阅相关...
10. JSP和Servlet的高级特性:比如会话跟踪、cookie处理、过滤器、监听器、MVC模式等。 11. 实际开发中遇到的问题及其解决方案:例如,处理请求中文乱码问题、在开发中如何分层以及代码的组织和管理。 以上就是...
在"Servlet&JSP学习笔记源代码"中,林信良教授通过实例讲解了这两项技术的基础和进阶知识。这些源代码是在Eclipse集成开发环境中创建的,Eclipse是Java开发的主流工具,支持丰富的插件,使得开发、调试和部署Servlet...
这份"Servlet&JSP学习笔记源代码"是由林信良编著,提供了丰富的实例代码,旨在帮助学习者深入理解这两种技术。 Servlet是Java编程语言的一个接口,允许Java代码与HTTP服务器进行交互。它扩展了服务器的功能,使得...
本学习笔记源码提供了全面的学习资源,涵盖了这两个技术的基础到高级应用,旨在帮助开发者深入理解并熟练掌握JSP和Servlet。 1. **JSP基础**: JSP是一种服务器端的脚本语言,它将HTML、CSS、JavaScript与Java代码...
【Servlet&JSP基础知识】 ...以上是`head_first_servlet&jsp`学习笔记的主要知识点,涵盖了Servlet和JSP的基础、Web应用架构、MVC模式、会话管理和JSP编程等多个方面,为深入理解和实践Servlet与JSP开发奠定了基础。
《Jsp&Servlet学习笔记 第二版》源码是一份宝贵的学习资源,它涵盖了Java Web开发中的核心组件——JSP(JavaServer Pages)和Servlet。这份源码集合旨在帮助开发者深入理解这两个技术,并通过实际的代码示例进行实践...
在"Jsp&Servlet完整范例Gossip"中,可能包含了各种应用场景,如用户登录、注册、数据查询、提交表单等,通过实际操作可以帮助初学者深入理解JSP和Servlet如何协同工作,以及Model2架构的实现方式。文件列表中的...
**JSP(JavaServer Pages)和Servlet是Java Web开发中的两个核心技术,它们在构建动态Web应用程序方面发挥着关键作用。** **JSP技术**是一种服务器端脚本语言,用于生成HTML或XML等Web内容。JSP的核心概念包括: 1...
2. **PPT** 文件可能包含教学演示,详细讲解了JSP和Servlet的原理及其实现细节,比如JSP指令、动作、EL表达式和JSTL标签库的使用,以及Servlet生命周期、初始化参数和会话管理等。 3. **DOC** 文件可能包含文档资料...
《JSP动态网站开发实践教程(第2版)源代码》是学习JSP技术的宝贵资源,它提供了丰富的实例和实战经验,旨在帮助开发者深入理解JSP在构建动态网站中的应用。通过分析和实践这些源代码,我们可以掌握JSP的核心概念、...
### Servlet学习笔记精炼知识点 #### 一、Servlet初始化与加载机制 1. **Servlet注册与实例化**:在Web应用中,一个Servlet的生命周期始于它的注册与实例化过程。通常,这一过程是在Web服务器启动时,根据`web.xml...
### 良葛格JspServlet学习笔记 #### 一、引言 在现代Web开发领域,特别是Java EE平台中,JSP (JavaServer Pages) 和 Servlet 技术扮演着非常重要的角色。这两种技术共同构成了Java Web应用的基础,分别侧重于用户...
《Head First Servlet JSP(中文版)》是一本专为初学者设计的Java Web开发教程,旨在通过生动有趣的方式引导读者快速掌握Servlet和JSP的核心概念和技术。这本书以易理解的图文并茂的形式,深入浅出地讲解了这两个重要...