Java Server Pages
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
JSP这门技术的最大的特点在于,写jsp就像在写html,但:
它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。
相比servlet而言,servlet很难对数据进行排版,而jsp除了可以用java代码产生动态数据的同时,也很容易对数据进行排版。
Jsp快速入门:在jsp页面中输出当前时间。
把英文版myeclipse 8.6中jsp默认编码格式改为pageEncoding="utf-8" |
windows -- > Preferences -- > MyEclipse -- > Files and Editors -- > JSP 然后右边选择Encoding为 ISO 10646/Unicode(UTF-8) |
JSP最佳实践
不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。
其原因为,程序的数据通常要美化后再输出:
让jsp既用java代码产生动态数据,又做美化会导致页面难以维护。
让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。
因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。
JSP原理
目标:
Web服务器是如何调用并执行一个jsp页面的?
Jsp页面中的html排版标签是如何被发送到客户端的?
Jsp页面中的java代码服务器是如何执行的?
Web服务器在调用jsp时,会给jsp提供一些什么java对象?
思考:JSP为什么可以像servlet一样,也可以叫做动态web资源的开发技术?
JSP语法
JSP模版元素
JSP表达式
JSP脚本片断
JSP注释
JSP指令
JSP标签
JSP内置对象
如何查找JSP页面中的错误
JSP模版元素
JSP页面中的HTML内容称之为JSP模版元素。
JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。
JSP脚本表达式
JSP脚本表达式(expression)用于将程序数据输出到客户端
语法:<%= 变量或表达式 %>
举例:当前时间:<%= new java.util.Date() %>
JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端。
JSP脚本表达式中的变量或表达式后面不能有分号(;)。
JSP脚本片断(1)
JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码。语法:
<%
多行java代码
%>
注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。
JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。
在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。
举例:
<%
intx = 10;
out.println(x);
%>
<p>这是JSP页面文本</p>
<%
inty = 20;
out.println(y);
%>
多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);
单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例如:
<%
for(int i=1; i<5; i++)
{
%>
<H1>www.it315.org</H1>
<%
}
%>
JSP声明
JSP页面中编写的所有代码,默认会翻译到servlet的service方法中,而Jsp声明中的java代码被翻译到_jspService方法的外面。语法:
<%!
java代码
%>
所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法。
多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。
JSP声明案例
<%!
static
{
System.out.println("loadingServlet!");
}
private int globalVar = 0;
public void jspInit()
{
System.out.println("initializingjsp!");
}
%>
<%!
public void jspDestroy()
{
System.out.println("destroyingjsp!");
}
%>
JSP注释
JSP注释的格式:
<%--注释信息 --%>
JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。
JSP指令
JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP 2.0规范中共定义了三个指令:
page指令
Include指令
taglib指令
JSP指令简介
JSP指令的基本语法格式:
<%@指令 属性名="值" %>
举例:<%@ page contentType="text/html;charset=gb2312"%>
如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。
例如:
<%@page contentType="text/html;charset=gb2312"%>
<%@page import="java.util.Date"%>
也可以写作:
<%@page contentType="text/html;charset=gb2312"import="java.util.Date"%>
Page指令
page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置。
JSP 2.0规范中定义的page指令的完整语法:
<%@ page
[language="java" ]
[extends="package.class" ]
[import="{package.class | package.*}, ..." ]
[session="true | false" ]
[buffer="none | 8kb | sizekb" ]
[autoFlush="true | false" ]
[isThreadSafe="true | false" ]
[info="text" ]
[errorPage="relative_url" ]
[isErrorPage="true | false" ]
[contentType="mimeType [ ;charset=characterSet ]" | "text/html ;charset=ISO-8859-1" ]
[pageEncoding="characterSet | ISO-8859-1" ]
[isELIgnored="true | false" ]
%>
JSP 引擎自动导入下面的包:
java.lang.*
javax.servlet.*
javax.servlet.jsp.*
javax.servlet.http.*
errorPage属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前页面。
可以在web.xml文件中使用<error-page>元素为整个WEB应用程序设置错误处理页面,其中的<exception-type>子元素指定异常类的完全限定名,<location>元素指定以“/”开头的错误处理页面的路径。
如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。
JSP引擎会根据page指令的contentType属性生成相应的调用ServletResponse.setContentType方法的语句。
page指令的contentType属性还具有说明JSP源文件的字符编码的作用。
使用page指令解决JSP中文乱码
JSP程序存在有与Servlet程序完全相同的中文乱码问题
输出响应正文时出现的中文乱码问题
读取浏览器传递的参数信息时出现的中文乱码问题
JSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题
JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换。
如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的ISO8859-1字符集编码处理。
如何解决JSP引擎翻译JSP页面时的中文乱码问题
通过page指令的contentType属性说明JSP源文件的字符集编码
page指令的pageEncoding属性说明JSP源文件的字符集编码
include指令
include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。在编译时包含
语法:
<%@include file="relativeURL"%>
其中的file属性用于指定被引入文件的相对路径。 file属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件。
细节:
被引入的文件必须遵循JSP语法。
被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。
由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。
request.getRequestDispatcher("/a.jsp").forward(request,response);//动态包含,翻译成多个servlet,运行时包含
taglib指令
Taglib指令用于在JSP页面中导入标签库,讲自定义标签技术时讲。
JSP运行原理和九大隐式对象
每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。
由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。
这9个对象分别是哪些,以及作用也是笔试经常考察的知识点。
request
response
config
application
exception
Session
page
out
pageContext
JSP九大隐式对象对应关系
1、定义:就是JSP对应的Servlet中的service方法中定义的那些变量
JSP内置对象名称 | 对应的类型 | 备注 |
request | javax.servlet.http.HttpServletRequest |
|
response | javax.servlet.http.HttpServletResponse |
|
session | javax.servlet.http.HttpSession | JSP指令page中有一个开关session=”true” |
application | javax.servlet.ServletContext |
|
config | javax.servlet.ServletConfig |
|
page | java.lang.Object | 代表当前Servlet对象本身 |
exception | java.lang.Throwable | JSP指令page中有一个开关isErrorPage="true" |
out | javax.servlet.jsp.JspWriter | 和response.getWriter()返回的PrintWriter作用一样 |
pageContext | javax.servlet.jsp.PageContext |
|
2、pageContext内置对象(相当重要)
作用:
a、本身是一个域对象,存的数据只能当前页面来访问。还能操作其他的三个域对象(ServletRequest HttpSession ServletContext)中的数据
l 本身是一个域对象(页面范围):PageContext内部有一个Map<String,Object>
voidsetAttribute(String key,Object value)
voidremoveAttribute(String key)
ObjectgetAttribute(String key)
特点:放的数据,只能当前页面中来用
l 操作其他的三个域对象(ServletRequest HttpSession ServletContext)中的数据
voidsetAttribute(String key,Object value,int scope)
voidremoveAttribute(String key,int scope)
ObjectgetAttribute(String key,int scope)
scope:
PageContext.PAGE_SCOPE 页面范围
PageContext.REQUEST_SCOPE 请求范围
PageContext.SESSION_SCOPE 会话范围
PageContext.APPLICATION_SCOPE 应用范围
存:
取:
l 从四大域范围中查找数据
Object obj = pageContext.findAttribute(String key)
依次从页面、请求、会话、应用范围查找指定的key值,找到为止。
b、获得其他8个隐式对象
ServletRequest request = pageContext.getRequest()
c、提供了转发和包含的简易方法
四大域对象(相当重要)
l PageContext:页面范围的数据。用的很少
l ServletRequest:请求范围的数据。用的很多。显示一次数据后就没有用了,这样的数据应该放到该范围中
l HttpSession:会话范围的数据。用的很多。每次请求和响应都需要共享的数据。比如登录信息,购物信息。
l ServletContext:应用范围的数据。用的不多。所有客户端都共享的信息。注意同步。
数据能不能取到,关键是不是从一个地方取的数据
out隐式对象
out隐式对象用于向客户端发送文本数据。
out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
设置page指令的buffer属性关闭了out对象的缓存功能
out对象的缓冲区已满
整个JSP页面结束
out隐式对象的工作原理图
out隐式对象的注意事项
同时使用out和response.getwriter()输出数据。
用JSP实现文件下载。
pageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
通过pageContext获得其他对象
getException方法返回exception隐式对象
getPage方法返回page隐式对象
getRequest方法返回request隐式对象
getResponse方法返回response隐式对象
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象
getOut方法返回out隐式对象
pageContext封装其它8大内置对象的意义,思考:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将具有什么功能? //用在自定义标签上
pageContext作为域对象
pageContext对象的方法
public voidsetAttribute(java.lang.String name,java.lang.Object value)
publicjava.lang.Object getAttribute(java.lang.String name)
publicvoid removeAttribute(java.lang.String name)
pageContext对象中还封装了访问其它域的方法
publicjava.lang.Object getAttribute(java.lang.String name,int scope)
public voidsetAttribute(java.lang.String name,java.lang.Object value,int scope)
public void removeAttribute(java.lang.String name,int scope)
代表各个域的常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
findAttribute方法 (*重点,查找各个域中的属性)
重点
到此为止,web开发接触到了4个域对象:
pageContext(称之为page域)
request(称之为request域)
session(称之为session域)
servletContext(称之为application域)
这4个域对象是学习web的重点,也是笔试经常考察的知识点。
明确如下问题:
这4个对象的生命周期?
什么是域?为什么把这4个对象叫做域对象呢?
哪种情况下用哪种域对象。
引入和跳转到其他资源
PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法
传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相对于当前WEB应用程序的根目录,否则,表示相对于当前JSP所映射到的访问路径。
JSP标签
虽然我们希望JSP页面仅用作数据显示模块,不要嵌套任何java代码引入任何业务逻辑,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面出现难看java代码,怎么办?
Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码。当然sun公司在jsp页面中也内置了一些标签(这些标签叫做jsp标签),开发人员使用这些标签可以完成页面的一些常用业务逻辑。
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能。
JSP常用标签
<jsp:include>标签
<jsp:forward>标签
<jsp:param>标签
<jsp:include>标签
<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:
<jsp:includepage="relativeURL | <%=expression%>"flush="true|false" />
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
<jsp:include>与include指令的比较
<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。
不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
<jsp:include>标签:使用page属性指定被引入资源。
include指令:使用file属性指定被引入资源。
假设myweb应用的根目录下有一个a.jsp文件 如果将a.jsp页面映射成了如下地址:
http://localhost:8080/myweb/dir1/a.html
在a.jsp页面中使用了如下语句引入b.jsp文件:
<jsp:includepage="b.jsp" />
请问:b.jsp要位于什么位置,上面的include才不会出错?
http://localhost:8080/myweb/b.jspf bad
http://localhost:8080/myweb/dir1/b.jspf ok
假设myweb应用程序的根目录下有一个a.jsp文件,如果将a.jsp页面映射为如下地址:
http://localhost:8080/myweb/dir1/a.html
在a.jsp页面中使用了如下语句引入b.jspf文件:
<%@include file=“b.jspf”%>
请问: b.jspf要位于什么位置,上面的include才不会出错?
http://localhost:8080/myweb/b.jspf ok
http://localhost:8080/myweb/dir1/b.jspf bad
<jsp:forward>标签
<jsp:forward>标签用于把请求转发给另外一个资源。
语法:
<jsp:forwardpage="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
<jsp:param>标签
当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法1:
<jsp:includepage="relativeURL | <%=expression%>">
<jsp:paramname="parameterName" value="parameterValue|<%= expression%>" />
</jsp:include>
语法2:
<jsp:forwardpage="relativeURL | <%=expression%>">
<jsp:paramname="parameterName" value="parameterValue|<%= expression%>" />
</jsp:include>
<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
映射JSP
<servlet>
<servlet-name>SimpleJspServlet</servlet-name>
<jsp-file>/jsp/simple.jsp</jsp-file>
<load-on-startup>1</load-on-startup>
</servlet>
……
<servlet-mapping>
<servlet-name>SimpleJspServlet</servlet-name>
<url-pattern>/xxx/yyy.html</url-pattern>
</servlet-mapping>
如何查找JSP页面中的错误
JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。
JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。
JSP页面翻译成的Servlet程序在运行时出现异常,这与普通Java程序的运行时错误完全一样,Java虚拟机将提示错误发生在Servlet源文件中的位置(行和列)以及相关信息。
Div与css
相对定位 div没有脱离文档流 还占着原来的位置
绝对定位 position:absolute;right:0px; 相对浏览器边框定位 原来的位置让出来了
绝对定位 position:absolute;right:0px; 相对父定位 原来的位置让出来了,则父要设置为position:relative;
JavaBean与Jsp
JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
这个Java类必须具有一个无参的构造函数
属性必须私有化。
私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
虽然Sun公司在定义JavaBean规范时,允许Java开发人员把JavaBean设计得可以像Swing组件一样功能强大,但在实际的J2EE开发中,通常只使用到以上JavaBean最基本的特性。
JavaBean在J2EE开发中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其它程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用其属性保存数据。
JavaBean的属性
JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有相应的setter、 getter方法,setter方法称为属性修改器,getter方法称为属性访问器。
属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name属性的修改器名称为setName,password属性的修改器名称为setPassword。
属性访问器通常以小写的get前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name属性的访问器名称为getName,password属性的访问器名称为getPassword。
一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。
在JSP中使用JavaBean
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:
<jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
<jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
<jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
<jsp:useBean>标签
<jsp:useBean>标签用于在指定的域范围内查找指定名称的JavaBean对象:
如果存在则直接返回该JavaBean对象的引用。
如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
常用语法:
<jsp:useBeanid="beanName" class="package.class"
scope="page|request|session|application"/>
id属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
class属性用于指定JavaBean的完整类名(即必须带有包名)。
scope属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page。
<jsp:useBean>执行原理
<jsp:useBean id="currentDate"class="java.util.Date"/>
翻译成的Servlet源码:
java.util.Date currentDate = null;
synchronized (_jspx_page_context) {
currentDate= (java.util.Date) _jspx_page_context.getAttribute(
"currentDate",PageContext.PAGE_SCOPE);
if(currentDate == null){
currentDate= new java.util.Date();
_jspx_page_context.setAttribute("currentDate",
currentDate,PageContext.PAGE_SCOPE);
}
}
带标签体的<jsp:useBean>标签
语法:
<jsp:useBean...>
Body
</jsp:useBean>
功能:
Body部分的内容只在<jsp:useBean>标签创建JavaBean的实例对象时才执行。
<jsp:setProperty>标签
<jsp:setProperty>标签用于设置和访问JavaBean对象的属性。
语法格式:
<jsp:setPropertyname="beanName"
{
property="propertyName"value="{string | <%= expression %>}" |
property="propertyName"[ param="parameterName" ] |
property="*"
}/>
name属性用于指定JavaBean对象的名称。
property属性用于指定JavaBean实例对象的属性名。
value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。
param属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的JavaBean属性的类型。
支持8种基本数据类型
<jsp:useBean id="person" class="cn.itcast.domain.Person" scope="page"></jsp:useBean> <jsp:setProperty property="birthday" name="person" value="<%=new Date() %>"/> <%=person.getBirthday() %> |
<jsp:getProperty>标签
<jsp:getProperty>标签用于读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。
语法:
<jsp:getPropertyname="beanInstanceName" property="PropertyName" />
name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean>标签的id属性值相同。
property属性用于指定JavaBean实例对象的属性名。
如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容为“null”的字符串。
JSP开发模式
SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式。
JSP+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据。
Servlet+JSP+JavaBean(MVC)模式适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP、JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。
package cn.itcast.domain; import java.util.Date; //1 public class User {
private String id; private String username; private String password; private String email; private Date birthday; private String nickname; public String getId() { return id; } public void setId(String id) { this.id = id; }
public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } } |
/day09_user/src/users.xml <?xml version="1.0" encoding="UTF-8"?> <users> <user id="234343434" username="aaa" password="123" email="aa@sina.com" birthday="1900-09-18" nickname="强子" /> </users> |
package cn.itcast.dao;
import cn.itcast.domain.User; //5 public interface UserDao { void add(User user); User find(String username, String password); //查找注册的用户是否在数据库中存在 boolean find(String username); } |
package cn.itcast.dao.impl;
import java.text.SimpleDateFormat;
import org.dom4j.Document; import org.dom4j.Element;
import cn.itcast.dao.UserDao; import cn.itcast.domain.User; import cn.itcast.utils.XmlUtils; //2 public class UserDaoImpl implements UserDao { public void add(User user){ try { Document document=XmlUtils.getDocument(); Element root=document.getRootElement(); Element user_tag=root.addElement("user"); user_tag.setAttributeValue("id", user.getId()); user_tag.setAttributeValue("username", user.getUsername()); user_tag.setAttributeValue("password", user.getPassword()); user_tag.setAttributeValue("email", user.getEmail()); user_tag.setAttributeValue("nickname", user.getNickname()); user_tag.setAttributeValue("birthday", user.getBirthday()==null ? "" : user.getBirthday().toLocaleString()); XmlUtils.write2Xml(document); } catch (Exception e) { throw new RuntimeException(e); } } public User find(String username,String password){
try { Document document=XmlUtils.getDocument(); Element e=(Element) document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']"); if(e==null) return null; User user=new User(); user.setUsername(e.attributeValue("username")); user.setNickname(e.attributeValue("nickname")); user.setPassword(e.attributeValue("password")); user.setEmail(e.attributeValue("email")); user.setId(e.attributeValue("id")); String date=e.attributeValue("birthday"); if(date==null || date.equals("")){ user.setBirthday(null); }else{ SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); user.setBirthday(df.parse(date)); } return user; } catch (Exception e) { throw new RuntimeException(e); } } //查找注册的用户是否在数据库中存在 public boolean find(String username){ try { Document document=XmlUtils.getDocument(); Element e=(Element) document.selectSingleNode("//user[@username='"+username+"']"); if(e==null) return false; return true; } catch (Exception e) { throw new RuntimeException(e); } } } |
package cn.itcast.exception; //7 public class UserExistException extends Exception {
public UserExistException() { // TODO Auto-generated constructor stub }
public UserExistException(String message) { super(message); // TODO Auto-generated constructor stub }
public UserExistException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub }
public UserExistException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub }
/* public UserExistException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub }*/
} |
package cn.itcast.service.impl;
import cn.itcast.dao.UserDao; import cn.itcast.dao.impl.UserDaoImpl; import cn.itcast.domain.User; import cn.itcast.exception.UserExistException; import cn.itcast.utils.ServiceUtils;
//6 对web层提供所有的业务服务 public class BusinessServiceImpl {
private UserDao dao=new UserDaoImpl();//工厂模式 spring //对web层提供注册服务 public void register(User user) throws UserExistException{ boolean b=dao.find(user.getUsername()); if(b){ throw new UserExistException("用户已经存在!"); //用户存在,给web层抛出编译时异常 }else{ user.setPassword(ServiceUtils.md5(user.getPassword())); dao.add(user); } } //对web层提供登录服务 public User login(String username,String password){ password=ServiceUtils.md5(password); return dao.find(username, password); }
} |
package cn.itcast.utils;
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.UnsupportedEncodingException;
import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter;
//3 public class XmlUtils { private static String filepath; static{ filepath=XmlUtils.class.getClassLoader().getResource("users.xml").getPath(); filepath=filepath.replace("%20", " "); } public static Document getDocument() throws Exception{ SAXReader reader = new SAXReader(); Document document = reader.read(new File(filepath)); return document; } public static void write2Xml(Document document) throws Exception{ OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream(filepath), format ); writer.write( document ); writer.close(); }
} |
package cn.itcast.utils;
import java.lang.reflect.InvocationTargetException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.Converter;
public class WebUtils { public static <T> T request2Bean(HttpServletRequest request,Class <T> beanClass){ try { T bean = beanClass.newInstance(); Enumeration e=request.getParameterNames(); while(e.hasMoreElements()){ String name=(String)e.nextElement(); String value=request.getParameter(name); BeanUtils.setProperty(bean, name, value); } return bean; } catch (Exception e) { throw new RuntimeException(e); } } public static void copyBean(Object src,Object dest){ /* private String username; private String password; private String password2; private String email; private String birthday; private String nickname;
private String id; private String username; private String password; private String email; private Date birthday; private String nickname; * */ ConvertUtils.register(new Converter() { @Override public Object convert(Class type, Object value) { if (value == null) return null; String str = (String) value; if (str.trim().equals("")) return null; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { return df.parse(str.trim()); } catch (ParseException e) { throw new RuntimeException(); } } }, Date.class); try { BeanUtils.copyProperties(dest, src); } catch (Exception e) { throw new RuntimeException(); } }//产生全世界唯一的id public static String generateID(){ return UUID.randomUUID().toString(); }
} |
package cn.itcast.utils;
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
//8 public class ServiceUtils {
public static String md5(String message){ try { MessageDigest md=MessageDigest.getInstance("md5"); byte md5[]=md.digest(message.getBytes()); BASE64Encoder encoder=new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } } |
package cn.itcast.web.formbean;
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class RegisterForm { private String username; private String password; private String password2; private String email; private String birthday; private String nickname; private Map errors=new HashMap();
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getPassword2() { return password2; }
public void setPassword2(String password2) { this.password2 = password2; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public Map getErrors() { return errors; } public void setErrors(Map errors) { this.errors = errors; } public boolean validate(){ boolean isOk=true; //用户名不能为空,且3-8位字母 //密码不空,3-8位数字 //邮箱不空,且一个合法邮箱 //生日可以为空,如果不为空,则要合法 //昵称要汉字,不能为空
if(username==null || username.trim().equals("")){ isOk=false; errors.put("username","用户名不能为空"); }else{ if(!username.matches("[A-Za-z]{3,8}")){ isOk=false; errors.put("username","用户名3-8位字母"); } } if(password==null || password.trim().equals("")){ isOk=false; errors.put("password","密码不能为空"); }else{ if(!password.matches("\\d{3,8}")){ isOk=false; errors.put("password","密码3-8位数字"); } } if(password2==null || password2.trim().equals("")){ isOk=false; errors.put("password2","确认密码不能为空"); }else{ if(!password.equals(password2)){ isOk=false; errors.put("password2","两次输入密码不一样"); } } if(email==null || email.trim().equals("")){ isOk=false; errors.put("email","邮箱不能为空"); }else{//aa@sina.com aa@sina.com.cn if(!email.matches("\\w+@\\w+(\\.\\w+)+")){ isOk=false; errors.put("email","邮箱格式不合法"); } } if(birthday!=null && !birthday.trim().equals("")){ DateLocaleConverter dlc=new DateLocaleConverter(); try{ dlc.convert(birthday,"yyyy-MM-dd"); }catch(Exception e){ isOk=false; errors.put("birthday","日期格式不对"); } //SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); } if(nickname==null || nickname.trim().equals("")){ isOk=false; errors.put("nickname","昵称不能为空"); }else{//汉字区间 \u4e00-\u9fa5 if(!nickname.matches("^([\u4e00-\u9fa5]+)$")){ isOk=false; errors.put("nickname","昵称必须为汉字"); } } return isOk; } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.User; import cn.itcast.exception.UserExistException; import cn.itcast.service.impl.BusinessServiceImpl; import cn.itcast.utils.WebUtils; import cn.itcast.web.formbean.RegisterForm; //处理注册请求 public class RegisterServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); //1.合法性校验 formBean把表单数据封装到formbean RegisterForm form=WebUtils.request2Bean(request,RegisterForm.class); boolean b=form.validate(); //2.如果校验失败,跳回到表单页面,回显失败消息 if(!b){ request.setAttribute("form", form); request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response); return ; } //3.校验成功,则调用service处理注册请求 BusinessServiceImpl service =new BusinessServiceImpl();
User user=new User(); WebUtils.copyBean(form, user); user.setId(WebUtils.generateID()); try { service.register(user); //6.service处理成功,跳转到网站的全局消息显示页面,为用户显示注册成功消息 request.setAttribute("message","注册成功"); request.getRequestDispatcher("/message.jsp").forward(request, response); return; } catch (UserExistException e) { //4.service处理不成功,原因是用户存在跳回注册页面显示注册用户已存在 form.getErrors().put("username", "注册的用户已存在"); request.setAttribute("form", form); request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response); return; }catch (Exception e) { //5.service处理不成功,原因是其他问题 ,跳转到全局消息处理界面,显示友好错误页面 e.printStackTrace(); request.setAttribute("message", "服务器出现未知错误"); request.getRequestDispatcher("/message.jsp").forward(request, response); return; } }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.User; import cn.itcast.service.impl.BusinessServiceImpl;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getParameter("username"); String password=request.getParameter("password"); BusinessServiceImpl service =new BusinessServiceImpl(); User user=service.login(username, password); if(user!=null){ request.getSession().setAttribute("user", user); response.sendRedirect(request.getContextPath()+"/index.jsp"); return ; } request.setAttribute("message", "用户名或密码错误"); request.getRequestDispatcher("/message.jsp").forward(request, response); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
public class LoginOutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session=request.getSession(false); if(session!=null) session.removeAttribute("username"); request.getSession().setAttribute("message", "注销成功!3秒后跳转<br/><meta http-equiv='refresh' content='3;"+request.getContextPath()+"/'>"); response.sendRedirect(request.getContextPath()+"/message.jsp"); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
} |
package cn.itcast.web.UI;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //提供登陆界面 public class LoginUIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } } |
package cn.itcast.web.UI;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class RegisterUIServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response); } public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } } |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>全局消息显示页面 message.jsp</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> ${message }<br> </body> </html> |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>index.jsp</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <c:if test="${user!=null }"> 欢迎:${user.username } <a href="${pageContext.request.contextPath }/servlet/loginOutServlet">注销</a><br/> </c:if> <a href="${pageContext.request.contextPath }/servlet/registerUIServlet">注册</a> <br> <a href="${pageContext.request.contextPath }/servlet/loginUIServlet">登录</a> <br> </body> </html> |
1.搭建开发环境 1.1导开发包 dom4j http://dom4j.sourceforge.net/ dom4j\lib\jaxen-1.1-beta--.jar jstl beanUtils log4j
1.2创建组织程序的包 cn.itcast.domain cn.itcast.dao cn.itcast.dao.impl cn.itcast.service cn.itcast.service.impl cn.itcast.web.controller 处理请求的servlet cn.itcast.web.UI 给用户提供界面 cn.itcast.utils junit.test
/WEB-INF/jsp 保存网站所以jsp 1.3创建代表数据库的xml文件 在类目录下创建一个代表数据库的user.xml
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>登陆界面 WEB-INF/jsp/login.jsp</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head>
<body> <form action="${pageContext.request.contextPath }/servlet/loginServlet" method="post"> 用户名<input type="text" name="username"/><br/> 密码<input type="text" name="password"/><br/> <input type="submit" value="登陆"/><br/> </form>
</body> </html> |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>注册页面 WEB-INF/jsp/register.jsp</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <form method="post" action="${pageContext.request.contextPath }/servlet/registerServlet" name="reg"> <table width="320" border="1" height="172"> <tbody><tr> <td> 姓名</td> <td> <input type="text" name="username" value="${form.username }"><span>${form.errors.username }</span></td></tr> <tr> <td> 密码</td> <td> <input type="password" name="password"><span>${form.errors.password }</span></td></tr> <tr> <td> 确认密码</td> <td> <input type="password" name="password2"><span>${form.errors.password2}</span></td></tr> <tr> <td> email</td> <td> <input type="text" name="email" value="${form.email }"><span>${form.errors.email }</span></td></tr> <tr> <td> 生日</td> <td> <input type="text" name="birthday" value="${form.birthday }"><span>${form.errors.birthday }</span></td></tr> <tr> <td> 别名</td> <td> <input type="text" name="nickname" value="${form.nickname}"><span>${form.errors.nickname }</span></td></tr> <tr> <td> <input type="reset" value="重置" name="reset"></td> <td> <input type="submit" value="提交" name="submit"></td></tr> </tbody></table> </form> </body> </html> |
1.搭建开发环境 1.1导入开发包 jstl
1.2创建组织程序的包 cn.itcast.domain cn.itcast.dao cn.itcast.service cn.itcast.web.controller cn.itcast.web.UI cn.itcast.utils WEB-INF/jsp
1.3创建代表数据库的DB 2.开发Dao
3.开发service
4.开发web |
Index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> </head> <body> <a href="${pageContext.request.contextPath }/servlet/ListBookServlet">浏览书籍</a><br> </body> </html> |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>书籍列表页面 WEB-INF/jsp/listbook.jsp</title> </head>
<body style="text-align:center"> <h1>书籍列表</h1> <table width="70%" border="1"> <tr> <td>书名</td> <td>作者</td> <td>售价</td> <td>描述</td> <td>操作</td> </tr> <c:forEach var="entry" items="${map}"> <tr> <td>${entry.value.name }</td> <td>${entry.value.author }</td> <td>${entry.value.price }</td> <td>${entry.value.description }</td> <td><a href="${pageContext.request.contextPath }/servlet/BuyServlet?id=${entry.key}" target="_blank">购买</a></td>
</tr> </c:forEach> </table> </body> </html> |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>购物车列表 WEB-INF/jsp/listcart.jsp</title> <script type="text/javascript"> function deleteitem(id){ var b=window.confirm("真的删除吗?"); if(b){ window.location="${pageContext.request.contextPath }/servlet/DeleteItemServlet?id="+id; } } function clearcart(){ var b=window.confirm("真的清空吗?"); if(b){ window.location="${pageContext.request.contextPath }/servlet/ClearCartServlet"; } } function changeQuantity(input,id,oldvalue){ //alert(input.value); //检查数量是不是一个数字,且是正整数 var quantity=input.value; if(isNaN(quantity)){ alert("请输入数字"); input.value=oldvalue; return; } if(quantity<0 || quantity!=parseInt(quantity)){ alert("请输入正整数"); input.value=oldvalue; return; } var b=window.confirm("确定修改吗?"); if(b){ window.location="${pageContext.request.contextPath }/servlet/ChangeQuantityServlet?id="+id+"&quantity="+quantity; } } </script> </head>
<body style="text-align:center">
<h1>购物车列表</h1> <c:if test="${empty(cart.map)}"> 你没有购买任何商品 </c:if> <c:if test="${!empty(cart.map)}"> <table width="70%" border="1"> <tr> <td>书名</td> <td>作者</td> <td>单价</td> <td>数量</td> <td>小计</td> <td>操作</td> </tr> <c:forEach var="entry" items="${cart.map}"> <tr> <td>${entry.value.book.name }</td> <td>${entry.value.book.author }</td> <td>${entry.value.book.price }</td> <td> <input type="text" name="quantity" value="${entry.value.quantity }" οnchange="changeQuantity(this,${entry.key},${entry.value.quantity })"/> </td> <td>${entry.value.price }</td> <td><a href="javascript:void(0);" target="_blank" οnclick="deleteitem(${entry.key});return false;">删除</a></td>
</tr> </c:forEach> <tr> <td colspan="3">总价计</td> <td colspan="2">${cart.price }元</td> <td colspan="1"><a href="javascript:void(0);" target="_blank" οnclick="clearcart();return false;">清空购物车</a></td> </tr>
</table> </c:if> </body> </html> |
package cn.itcast.DB;
import java.util.LinkedHashMap; import java.util.Map;
import cn.itcast.domain.Book;
public class DB { private static Map map=new LinkedHashMap(); static{ map.put("1", new Book("1","javaweb开发","老张",38,"一本好书")); map.put("2", new Book("2","jdbc开发","老黎",18,"一本好书")); map.put("3", new Book("3","ajax开发","老佟",328,"一本好书")); map.put("4", new Book("4","jbpm开发","老毕",58,"一本好书")); map.put("5", new Book("5","struts开发","老方",28,"一本好书")); map.put("6", new Book("6","spring开发","老方",98,"一本好书")); } public static Map getAll(){ return map; } } |
package cn.itcast.domain;
public class Book { private String id; private String name; private String author; private double price; public Book() { super(); } public Book(String id, String name, String author, double price, String description) { super(); this.id = id; this.name = name; this.author = author; this.price = price; this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } private String description; } |
package cn.itcast.domain;
import java.util.Map;
import cn.itcast.DB.DB;
public class BookDao { public Map getAll(){ return DB.getAll(); } public Book find(String id){ return (Book) DB.getAll().get(id); } } |
package cn.itcast.domain;
import java.util.LinkedHashMap; import java.util.Map;
//代表用户的购物车 public class Cart { private Map<String,CartItem> map=new LinkedHashMap(); private double price;//所有商品多少前 public void add(Book book){ CartItem item=map.get(book.getId()); if(item==null){ item=new CartItem(); item.setBook(book); item.setQuantity(1); map.put(book.getId(), item); }else{ item.setQuantity(item.getQuantity()+1); } } public Map<String, CartItem> getMap() { return map; } public void setMap(Map<String, CartItem> map) { this.map = map; } public double getPrice() { double totalprice=0; for(Map.Entry<String, CartItem> entry:map.entrySet()){ CartItem item=entry.getValue(); totalprice+=item.getPrice(); } this.price=totalprice; return price; } public void setPrice(double price) { this.price = price; } } |
package cn.itcast.domain; //代表某个商品,以及商品出现的次数(购物项) public class CartItem { private Book book; private int quantity; private double price; public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public int getQuantity() { price=book.getPrice()*quantity; return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } } |
package cn.itcast.service;
import java.util.Map;
import cn.itcast.domain.Book; import cn.itcast.domain.BookDao; import cn.itcast.domain.Cart; import cn.itcast.domain.CartItem; //业务层,统一对web层提供所有服务 public class BusinessService { private BookDao dao=new BookDao(); public Map getAll(){ return dao.getAll(); } public Book findBook(String id){ return (Book) dao.getAll().get(id); } //删除购物车中的购物项 public void deleteCartItem(String id, Cart cart) { cart.getMap().remove(id); } public void clearCart(Cart cart) { cart.getMap().clear(); } public void changeItemQuantity(String id, String quantity, Cart cart) { CartItem item=cart.getMap().get(id); item.setQuantity(Integer.parseInt(quantity)); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Book; import cn.itcast.domain.Cart; import cn.itcast.service.BusinessService;
public class BuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id=request.getParameter("id"); BusinessService service = new BusinessService(); Book book=service.findBook(id); //得到用户的购物车 Cart cart=(Cart) request.getSession().getAttribute("cart"); if(cart==null){ cart=new Cart(); request.getSession().setAttribute("cart", cart); } //把书加到用户的购物车中 cart.add(book); response.sendRedirect(request.getContextPath()+"/servlet/ListcartUIServlet"); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
} |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Cart; import cn.itcast.service.BusinessService; //把购物车中的书修改为指定数量 public class ChangeQuantityServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id=request.getParameter("id"); String quantity=request.getParameter("quantity"); Cart cart=(Cart)request.getSession().getAttribute("cart"); BusinessService service=new BusinessService(); service.changeItemQuantity(id,quantity,cart); request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Cart; import cn.itcast.service.BusinessService; //清空购物车 public class ClearCartServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cart cart=(Cart) request.getSession().getAttribute("cart"); BusinessService service = new BusinessService(); service.clearCart(cart); request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Cart; import cn.itcast.service.BusinessService;
public class DeleteItemServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id=request.getParameter("id"); BusinessService service=new BusinessService(); Cart cart=(Cart) request.getSession().getAttribute("cart"); service.deleteCartItem(id,cart); request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response); } } |
package cn.itcast.web.controller;
import java.io.IOException; import java.io.PrintWriter; import java.util.Map;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import cn.itcast.service.BusinessService;
public class ListBookServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BusinessService service =new BusinessService(); Map map=service.getAll(); request.setAttribute("map", map); request.getRequestDispatcher("/WEB-INF/jsp/listbook.jsp").forward(request, response); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } } |
package cn.itcast.web.UI;
import java.io.IOException; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class ListcartUIServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response); } } |