大妈 java web_java web学习笔记-jsp篇

转载自:http://www.cnblogs.com/happyfans/archive/2015/03/17/4343571.html

1.java web简介

1.1静态页面与动态页面

表现形式

所需技术

静态网页

网页内容固定,不会更新

html,css

动态网页

网页内容由程序动态显示,自动更新

html,css,DB,java/c#/php,javascript,xml,主流的动态网页脚本(jsp,asp.net,php)

1.2搭建java web开发环境

jdk1.7+tomcat7.0+MyEclipse10。关于MyEclipse的安装和配置请参见http://blog.sina.com.cn/s/blog_907043b301016jtp.html。Tomcat服务器是Apache Jakarta的开源项目,是Jsp/Servlet容器。安装Tomcat只需要解压zip包到指定目录即可。新建一个环境变量CATALINA_HOME,变量的值是Tomcat的根目录D:\Program Files (x86)\apache-tomcat-7.0.57。全部的环境变量如下:

变量名

变量值

JAVA_HOME

D:\Program Files (x86)\Java\jdk1.7.0_40

Path

C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;%JAVA_HOME%\bin;D:\Program Files\Sublime Text 3;D:\Program Files\MySQL\MySQL Utilities 1.3.6\

classpath

.;%JAVA_HOME%\lib\rt.jar;%JAVA_HOME%\lib\tools.jar;

CATALINA_HOME

D:\Program Files (x86)\apache-tomcat-7.0.57

之后我们测试一下Tomcat的首页:

进入Tomcat服务器根目录下面的bin目录,以管理员方式运行startup.bat,如果运行结果如下就表示Tomcat服务器启动成功。

e92117fc849458a79f6fcaaf13e17634.png

注意:不要关闭这个窗口(关闭窗口就意味着关闭了Tomcat服务器,将其最小化)。

在浏览器地址栏输入http://localhost:8080/回车得到如下页面:

8e9d22499ca4ef1b284f8af685f0da5b.png

1.3Tomcat目录结构

a56b626b999c2763becd9560cb59a3cb.png

1.4手工编写第一个web应用程序

21d73f1fdd9714551bda45bc06301fd5.png

在项目文件夹中创建一个index.jsp:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

手工编写的第一个java web项目

6

7

8

这是手工编写的第一个java web项目——jsp

9


10

11

48304ba5e6f9fe08f3fa1abda7d326ab.png

在项目目录中创建一个WEB-INF目录拷贝/webapps/examples/WEB-INFO/web.xm到自己项目的/myJspProject/WEB-INFO中,在/myJspProject/WEB-INFO中创建两个文件夹:classes和lib。最后的项目目录应该是这样:

0f7492963d40799af7b9b77d7e9b48ce.png

测试:浏览器输入:http://localhost:8080/myJspProject/index.jsp回车,运行结果如下:

21f23b658b327dc96cf32cfa749cb268.png

解决方法:更改浏览器编码为指定编码:

51d4cbed10612a8f4f091d7fe2ced265.png

1.5WEB-INF目录详解

该目录是java web应用的安全目录。所谓安全目录就是客户端无法访问只有服务端可以访问的目录。其中web.xml是项目部署文件,classes目录:存放*.class文件,lib目录存放需要的jar包。例如:我们在WEB-INF中创建一个test.html,下面我们通过浏览器访问:

d534d2cede66795ac6263817116d272c.png

web.xml配置文件可以配置欢迎页面默认的欢迎页面是项目下面的index.jsp,加入我们需要将项目下的haha.jsp,在/WEB-INF/web.xml的web-app标记中添加以下代码:

1

2 /haha.jsp

3

运行结果:

b7a7755d97c1f9141d35d23dd8406ff4.png

1.6实用Eclipse编写第一个web应用程序

注意:如果要使用Eclipse编写java web应用应该使用Eclipse的J2EE版本。并在Eclipse中配置Tomcat服务器Window-Preference-Server-Runtime Environment-Add,然后在WebContent目录下新建jsp文件,按下Ctrl+F11(或者在项目中右键-Run On Server)就可以使用内置浏览器访问建立的网站。

1.7用MyEclipse编写第一个web应用程序

在新建项目之前首先在MyEclipse中配置jre和tomcat。步骤Window-Preference-Java-Install JREs-Add;Window-MyEclipse-Servers-Tomcat(注意设置tomcat的jre并将服务器设置为Enabled)。

接下来在MyEclipse中启动Tomcat服务器:

8affe143bbb0b625fc739579c84e1570.png

测试首页http://localhost:8080/证明Tomcat正常启动,我们就可以在MyEclipse中启动和发布Web应用程序了。

New一个WebProject会生成以下的目录结构(默认在WebRoot目录下有一个index.jsp)。

da9c21dbeafc42e56ca35d58092bda82.png

发布该WebApp。

593b84125f399ad83ce71d7b2f9689e2.png

a79204fe94b65dd58ca33a4d31a79b48.png

1.8理解项目的虚拟路径

87ce5dd4e661e90780ac01e6353780e8.png

该虚拟路径是可以修改的项目上右键属性-MyEclipse-Web。

f8cdb9b02d1059ea38d50dfe26d6178e.png

重新部署,浏览器需要使用使用http://localhost:8080/hello/index.jsp访问了。

1.7修改Tomcat默认端口

修改conf目录下的server.xml的以下标记:

2.jsp语法基础

2.1jsp简介

jsp的全名是Java Server Page,是一个简化的Servlet设计,它实现了在java当中使用html标记。jsp是一种动态网页技术,符合J2EE标准。jsp和Servlet一样也是在服务器端执行的。

2.2常见动态网站开发技术对比

平台

特点

jsp

跨平台,安全性高,适合开发大型的、企业级的Web应用、分布式应用(Hadoop)。例如:12306、10086.cn、网上银行

asp.net

简单易学,安全性和跨平台性差

php

简单、高效、成本低、开发周期短,适合中小型企业的Web应用开发(LAMP)

2.3jsp页面元素简介以及page指令

212d3307581bf7dd68210f88167eea24.png

db93f94dd355fc2d45b03494b7e85869.png

page指令语法:

属性

描述

默认值

language

jsp页面所使用的脚本语言

java

import

引用脚本语言中所要使用的类文件

contentType

指定jsp页面的编码

text/html,ISO-8859-1

新建一个java web工程默认的jsp页面开头有一个page指令:

默认的编码是ISO-8859-1,不支持中文,这里建议使用另一个属性contentType。将第一行改为如下:

这样就支持中文了。

page指令的全部属性如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 [language="Java"]

3 [extends="package.class"] // 指定JSP页面编译所产生的Java类所继承的父类,或所实现的接口。

4 [import="package.class│package.*,…"]

5 [session="true│false"]

6 [buffer="none│8kb│size kb"]

7 [autoFlush="true│false"]

8 [isThreadSafe="true│false"]

9 [info="text"]

10 [errorPage="relativeURL"] // 指定错误处理页面。因为JSP内建了异常机制支持,所以JSP可以不处理异常。

11 [contentType="mimeType[;charset=characterSet]"│"text/html;charSet=ISO8859-1"]

12 [isErrorPage="true│false"] // 设置本JSP页面是否为错误处理程序。

13 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

注意:除page指令中的import属性之外,其他属性均只能设置一次。

2.4jsp注释

分为3种:html注释,jsp注释,jsp脚本注释。语法:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4 /*这里是jsp脚本注释 有两种*/

5

6 //单行注释

7

8 /*多行注释*/

9 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

例如:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

12

My JSP 'index.jsp' starting page

13

14

15

16

17

18

21

22

23

24

欢迎你

25

26

27

28 /*这里是jsp脚本注释

29 有两种*/

30 //单行注释

31 /*多行注释*/

32 %>

33

34

48304ba5e6f9fe08f3fa1abda7d326ab.png

将项目部署到Tomcat,客户端用浏览器查看源代码:

95083f858377ef68f58790fdb9d628e5.png

2.5jsp脚本

在jsp页面中执行的java代码。语法:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

12

My JSP 'index.jsp' starting page

13

14

15

16

17

18

21

22

23

24

欢迎你

25


26

27 out.println("通过jsp内置对象out对象打印输出");

28 %>

29

30

48304ba5e6f9fe08f3fa1abda7d326ab.png

af86229c026e76a97d6ffee2cfaf2443.png

2.6jsp声明

jsp页面中定义变量或者方法。语法:

例如:

1

2 String s = "张三"; //声明一个String类型的变量

3 int add(int x,int y){ //声明一个返回值为int类型的方法

4 return x+y;

5 }

6 %>

2.7jsp表达式

jsp页面中执行的表达式。语法(注意=紧挨着百分号,表达式末尾没有分号):

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

12

My JSP 'index.jsp' starting page

13

14

15

16

17

18

21

22

23

24

欢迎你

25


26

27

28 String s = "张三"; //声明一个String类型的变量

29 int add(int x,int y){ //声明一个返回值为int类型的方法

30 return x+y;

31 }

32 %>

33 你好:

34 令x=10,y=5,则x+y =

35

36

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

ede3749e826cc4b38817f9b8a49e4e30.png

2.8jsp页面生命周期

3c44c49b8cd6b71cae659f0b6b8c04ce.png

jspService()方法被调用来处理客户端的请求。对每一个请求,JSP引擎创建一个新的线程来处理该请求。如果有多个客户端同时请求你该jsp文件,则jsp引擎会创建多个线程(每一个客户端请求对应一个线程)。以多线程的方式执行可以大大降低对系统的资源需求,提高系统的并发量以及缩短服务器的响应时间——但是同时要注意多线程的同步问题。由于该Servlet常驻内存,所以响应是非常快的。

当页面没有被访问的时候work目录下没有相关的Servlet。如果页面被访问之后就会在work目录的对应目录生成响应的Servlet。如图:

bf3f8cfb0ba2d981d40816939158ee94.png

打开index_jsp.java会看到以下的初始化方法:

a309fb3d78e92ccea11d6a0b09d576dc.png

然后该Servlet常驻内存,创建线程处理每一个客户端的请求。由每一个线程调用_jspService()方法来处理请求。

如果jsp页面内容发生了改变,jsp引擎就需要重新编译jsp页面。我们修改index.jsp,用浏览器重新访问,则:

12112cdb36f4519e45d15df622919f6c.png

f31ed86b0c5f611c1049db4c6ad6920f.png

2.9阶段项目(九九乘法表)

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 contentType="text/html; charset=utf-8"%>

4

5 String path = request.getContextPath();

6 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

7 %>

8

9

10

11

12

13

14

My JSP 'multiplicationTable.jsp' starting page

15

16

17

18

19

20

21

22

23

24

25

26

九九乘法表

27

表达式的方式打印乘法表

28

29 //声明表达式

30 String printMultiTable(){

31 StringBuilder s = new StringBuilder();

32 for(int i=1;i<=9;i++){

33 for(int j=1;j<=i;j++){

34 s.append(i+" * "+j+" = "+i*j+"\t");

35 }

36 s.append("
");//追加换行标记,注意不能使用\n

37 }

38 return s.toString();

39 }

40 %>

41

42 %>

43

44

使用脚本的方式打印九九乘法表

45

46 //jsp小脚本

47 void printMultiTable2(JspWriter out) throws IOException{

48 StringBuilder s = new StringBuilder();

49 for(int i=1;i<=9;i++){

50 for(int j =1;j<=i;j++){

51 s.append(i+" * "+j+" = "+i*j+"\t");

52 }

53 s.append("
");

54 }

55 out.println(s.toString());

56 }

57 %>

58

59

60 //调用脚本

61 printMultiTable2(out);

62 %>

63

64

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

cef55f5e6fbc2a22cee0e1d470dfaf32.png

3.jsp内置对象

9b02105bbf5d98ac7aeca917a8e4209e.png

3.1jsp内置对象简介

JSP内置对象是Web容器创建的一组对象,不需要使用new关键字,JSP规范将它们完成了默认初始化(由JSP页面对应Servlet的_jspService()方法来创建这些实例)。例如打印九九乘法表的jsp小脚本中使用的out对象就是jsp内置对象。

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 //jsp小脚本

3 void printMultiTable2(JspWriter out) throws IOException{

4 StringBuilder s = new StringBuilder();

5 for(int i=1;i<=9;i++){

6 for(int j =1;j<=i;j++){

7 s.append(i+" * "+j+" = "+i*j+"\t");

8 }

9 s.append("
");

10 }

11 out.println(s.toString());//这里的out就是jsp内置对象

12 }

13 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

JSP一共有9个内置对象,其中常用的内置对象有5个,如图所示:

aa6460d08848c0b46f5e311885dfcb71.png

3.3out对象

缓冲区(Buffer)就是内存中用来保存临时数据的一块区域。关于缓冲区有一个很形象的例子:比如我们煮好了饭放在锅里,如果我们一粒一粒地来吃米饭就不知道吃到猴年马月,拿来一个碗来一碗一碗吃,岂不快哉!这里的碗就充当了缓冲区的概念。其实IO的本质就是直接操作字节,但是效率太慢所以引入了缓冲区。

out对象是JspWriter类的一个实例——是向客户端输出内容的常用对象,该对象的常用方法:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 void println(String message); // 向客户端打印字符串

2 void clear(); // 清除缓冲区内容,如果在flush之后调用会抛出异常

3 void clearBuffer(); // 清除缓冲区内容,如果在flush之后调用不会抛出异常

4 void flush(); // 将缓冲区的内容输出到客户端

5 int getBufferSize(); // 返回缓冲区的大小(字节),默认是0

6 int getRemaining(); // 返回缓冲区可用容量

7 boolean isAutoFlush(); // 返回缓冲区满的时候是自动清空还是抛出异常

8 void close(); // 关闭输出流

48304ba5e6f9fe08f3fa1abda7d326ab.png

下面是一个简单的示例:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

JSP的out内置对象

2

3 //jsp脚本

4 out.println("

静夜思

");

5 out.println("李白
");

6 out.println("窗前明月光,
");

7 out.println("疑是地上霜。
");

8 out.println("举头望明月,
");

9 out.println("低头思故乡。


");

10 %>

11

12 缓冲区大小:字节。

13 剩余缓冲区(可用缓冲区):字节。

14 是否自动清空缓冲区:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

9679f51c45e35716977430601ac7381a.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

JSP的out内置对象

2

3 //jsp脚本

4 out.println("

静夜思

");

5 out.println("李白
");

6 out.println("窗前明月光,
");

7 out.flush();//将缓冲区中的内容输出到客户端

8 out.println("疑是地上霜。
");

9 out.println("举头望明月,
");

10 out.println("低头思故乡。


");

11 %>

12

13 缓冲区大小:字节。

14 剩余缓冲区(可用缓冲区):字节。

15 是否自动清空缓冲区:

48304ba5e6f9fe08f3fa1abda7d326ab.png

如果在第7行强制刷新缓冲区,则输出的页面不会有任何变化,仅仅是可用缓冲区的数量变多了而已【因为flush清空了缓冲区】

29ac9b981f7f2b0a9a9caf8ba16ff1de.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 //jsp脚本

3 out.println("

静夜思

");

4 out.println("李白
");

5 out.println("窗前明月光,
");

6

7 out.flush();//将缓冲区中的内容输出到客户端

8 out.clear();//在flush之后调用clear,将会抛出异常

9

10 out.println("疑是地上霜。
");

11 out.println("举头望明月,
");

12 out.println("低头思故乡。


");

13 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

595185d7edf9428d40bb40b19fabd693.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 //jsp脚本

3 out.println("

静夜思

");

4 out.println("李白
");

5 out.println("窗前明月光,
");

6

7 out.flush();//将缓冲区中的内容输出到客户端

8 out.clearBuffer();//在flush之后调用clearBuffer不会抛出异常

9

10 out.println("疑是地上霜。
");

11 out.println("举头望明月,
");

12 out.println("低头思故乡。


");

13 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

0e791fff53c3855ae5c1851bf46205a8.png

3.4post和get提交方式的区别

get:以明文的方式通过URL提交数据,提交的数据最大不超过2K。适合提交数据量小,安全性不高的数据【例如:搜索和查询】

post:将用户提交的数据封装在URL HEADER内。适合提交数据量大,安全性高的数据【例如:注册、修改、上传】

下面以用户登录的例子比较两者的区别:

login.jsp页面

1 请输入用户名和密码:

2

3 用户名:

4 密码:

5

6

处理登录的动作脚本dologin.jsp仅仅是显示一句话"登录成功"。

运行结果:

453d2735ba0f5e6def6496e6be6dcb26.png

将用户登录表单的get方式改为post。

588b20de3f9ad6f0600d3a692cd0554e.png

3.5request对象

客户端的请求被封装在request对象中,通过它才能了解到客户端的需求,然后做出响应。它是HttpServletRequest对象的实例。request对象具有请求域,即:完成客户端的请求之前,该对象一直有效。常用方法如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

/* 两个比较常用的方法 */

1 String getParameter(String name); // 返回name指定参数的参数值

2 String[] getParameterValues(String name); // 返回包含name的所有值的数组

3 void setAttribute(String,Object); // 存储此请求中的属性

4 String getContentType(); // 返回请求体的MIME类型

5 Stirng getProtocol(); // 返回请求所用的协议和版本号

6 String getServerName(); // 返回接受请求的服务器的主机名

7 int getServerPort(); // 返回服务器接受此请求所用的端口号

8 String getCharacterEncoding(); // 返回字符编码方式【只能解决post方式的乱码问题】

9 void setCharacterEncoding(); // 设置请求的字符编码方式

10 int getContentLength(); // 返回请求体的长度(字节)

11 String getRemoteAddr(); // 返回发送此请求的客户端IP

12 String getRealPath(String path); // 返回虚拟路径的真实路径

13 String request.getContextPath(); // 返回上下文路径

48304ba5e6f9fe08f3fa1abda7d326ab.png

以用户注册页面为例(用户在注册页reg.jsp完善信息后提交给request.jsp来处理):

用户注册页reg.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1   请输入相关信息完成注册

2

3 用户名:

4 密码:

5 爱好:

6 读书

7 音乐

8 电影

9 上网

10

11

48304ba5e6f9fe08f3fa1abda7d326ab.png

处理用户注册页的request.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

request内置对象

2

3 用户名:

4 密码:


5 爱好:

6

7 String[]favorites = request.getParameterValues("favorite");

8 for(String str:favorites){

9 out.print(str+"  ");

10 }

11 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

b30c4a96897db8644c9c7dfd5ee7f334.png

但是以上页面存在一个问题:假如我们在用户名中输入中文:

1549f1afcf0f1c9fa0269792448568cd.png

这时只要再request.jsp中设置字符集和reg.jsp一样即可:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

request内置对象

2

3

4 用户名:

5 密码:


6 爱好:

7

8 String[]favorites = request.getParameterValues("favorite");

9 for(String str:favorites){

10 out.print(str+"  ");

11 }

12 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

除了可以使用表单的方式传递数据给request对象,也可以使用URL传参的方式传递数据给request对象:

reg.jsp

测试URL传参

request.jsp(不变)

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

request内置对象

2

3

4 用户名:

5 密码:


6 爱好:

7

8 String[]favorites;

9 if((favorites=request.getParameterValues("favorite"))!=null){

10 for(String str:favorites){

11 out.print(str+"  ");

12 }

13 }

14 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

fdbf2684767a258d43fdabc4d57eb3a1.png

如果我们在URL传参中传入了中文数据,同样会出现乱码问题:

测试URL传参

此时通过request.setCharacterEncoding()方法就无法解决乱码问题了【一个良好的解决方案是修改tomcat的配置文件server.xml】

向request对象中添加键值对:

reg.jsp:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1   请输入相关信息完成注册

2

3 用户名:

4   密码:

5 爱好:

6 读书

7 音乐

8 电影

9 上网

10

11

48304ba5e6f9fe08f3fa1abda7d326ab.png

request.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

request内置对象

2

3

4

5 //在request对象中保存一个email属性

6 request.setAttribute("email","io@gmail.com");

7

8 %>

9 用户名:

10 密码:


11 爱好:

12

13 String[]favorites;

14 if((favorites=request.getParameterValues("favorite"))!=null){

15 for(String str:favorites){

16 out.print(str+"  ");

17 }

18 }

19 %>

20
邮箱:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

7f8cf1819604c847cba4978afe0504ca.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

request内置对象

2

3

4

5 //在request对象中保存一个email属性

6 request.setAttribute("email","io@gmail.com");

7

8 %>

9 用户名:

10 密码:


11 爱好:

12

13 String[]favorites;

14 if((favorites=request.getParameterValues("favorite"))!=null){

15 for(String str:favorites){

16 out.print(str+"  ");

17 }

18 }

19 %>

20
邮箱:


21 请求体的MIME类型:

22 请求体的协议及版本号:

23 服务器主机名:

24 服务器端口号:

25 请求的字符编码:

26 请求的文件长度:字节

27 请求的客户端的IP:

28 请求的真实路径:

29 请求的上下文路径:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

79b3601c3d44cc95bb13f5b4337ac4f4.png

3.6response对象

response对象包含了响应客户请求的相关信息,但是在JSP中很少直接使用到它。它是HttpServletResponse类的实例。response对象具有页面作用域——即:访问一个页面时,该页面的response只对本次访问有效,其他页面的response对象对当前页面无效。常用方法如下:

1 String getCharacterEncoding(); // 返回响应所用的编码

2 void setContentType(); // 设置响应的MIME类型

3 PrintWriter getPrintWriter(); // 返回一个可以向客户端输出字符的对象【注意区别于out内置对象】

4 sendRedirect(String location); // 重定向客户端的请求

response.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4 response.setContentType("text/html;charset=utf-8");//设置响应的MIME类型

5

6 out.println("

response内置对象


");

7

8 PrintWriter outer = response.getWriter();//获得输出流对象

9 outer.println("我是response对象生成的outter对象,在页面中总是在前面输出");

10 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

a7aaa111f6f5b4db4fc6fa6f31006827.png

运行结果很是奇怪:明明out对象的输出在代码中位于前面。但是结果却是PrintWriter的打印结果在前面,根本原因就是:PrintWriter的对象的输出总是在最前面。如果我们需要让标题先输出,可以使用内置对象out的flush()方法强制刷新缓冲,向页面输出——保证标题出现在最前面。

请求重定向——当用户请求response.jsp的时候马上跳转到login.jsp

response.sendRedirect("login.jsp"); // 请求重定向

%>

3.7请求重定向与请求转发的区别

请求重定向:客户端行为response.sendResponse(),从本质上讲相当于两次请求,前一次的请求对象不会保存,浏览器的URL栏会改变。

请求转发:服务器行为request.getRequestDipatcher().forword(req,resp);是一次请求,转发后请求对象会被保存,浏览器的URL不会改变。

例如还是用原来的例子:我们在reg.jsp中指定处理页面的脚本是response.jsp而在response.jsp中我们重定向到request.jsp。观察request.jsp的输出:

879b231b7e8ab50bdd4a8e67434c5f25.png

如果我们在response.jsp中使用请求转发:

1

2

3 //请求转发

4 request.getRequestDispatcher("request.jsp").forward(request, response);

5 %>

运行结果:

9a22166cabc8e828def33229dff5005a.png

3.8session对象

Session客户端与服务器的一次会话。Web中的Session表示用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间——也就是用户浏览这个网站所花费的时间。在服务器的内存中保存着不同用户的Session。

156ad47930e6f029fc07c865149bf501.png

44da9e88fccba86b771e14dce444909d.png

session对象的常用方法:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 long getCreationTime(); // 返回session的创建时间

2 String getId(); // 返回session创建时JSP引擎为它设定的唯一ID号

3 Object setAttribute(String name,Object value); // 使用指定名称将对象绑定到此会话

4 Object getAttribute(String name); // 返回此会话中的指定名称绑定在一起的对象,如果没有对象绑定在该名称下则返回null

5 String[] getValueNames(); // 返回一个包含此Session所有可用属性的数组

6 int getMaxInactiveInterval(); // 返回两次请求间隔多长时间此session被取消【单位:秒】

48304ba5e6f9fe08f3fa1abda7d326ab.png

sesseion_page1.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1   

session内置对象

2

session_page1.jsp

3

4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

5 String date = sdf.format(new Date(session.getCreationTime()));

6 out.print("session的创建时间:" + date);

7 session.setAttribute("username", "admin"); // 向session中设置属性

8 %>

9
Session的ID号:

10 从session中获取用户名:

11

12 以新窗口的方式打开session_page2.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

session_page2.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

session_page2.jsp

2

3 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

4 String date = sdf.format(new Date(session.getCreationTime()));

5 out.print("session的创建时间:" + date);

6 %>

7
Session的ID号:

8 从session中获取用户名:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

1817142df610694472ac5304ad20e370.png

可以获取session中保存的属性集合以及设置session的有效期:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 session.setMaxInactiveInterval(5);//设置session的有效期为5s

3

4 session.setAttribute("username", "admin"); // 向session中设置属性

5 session.setAttribute("password", "123456");

6 session.setAttribute("age", 16);

7 %>

8

9

10 //获取session中保存的属性

11 String[]names=session.getValueNames();

12 if(names!=null){

13 for(String str:names){

14 out.print(str+"\t");

15 }

16 }

17 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

Session的生命周期:

851b259457acf419c55b8b63d1abbf3e.png

创建:当客户端第一次访问某个jsp页面或者Servlet的时候,服务器会为当前会话创建一个SessionId。每次客户端向服务器发送请求的时候都会携带此SessionId,服务端会对此SessionId进行检验——判断是否属于同一次会话。

活动阶段:某次会话中通过超链接打开新的页面;只要当前页面没有全部关闭,打开新的浏览器窗口访问同一项目资源也属于同一会话。注意:原有的会话仍然存在,只不过再也没有客户端会携带此sessionId交给服务器检验。——创建一个新的会话并不意味着原有会话消失,除非超时。

销毁。

Tomcat如何进入后台管理系统?

修改/conf/tomcat-user.xml为以下:

1 <?xml version="1.0" encoding="UTF-8"?>

2

3

4

5

6

在浏览器中打开session_page1.jsp然后通过session_page1.jsp的超链接打开session_page2.jsp在后台管理系统中查看:

78e2daea244dd12d4042777ee18c99f1.png

如果我们在session创建之后调用session.invalidate()方法,例如:我们在session_page1.jsp中这样写:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

session内置对象

2

session_page1.jsp

3

4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

5 String date = sdf.format(new Date(session.getCreationTime()));

6 out.print("session的创建时间:" + date);

7

10 session.setAttribute("username", "admin"); // 向session中设置属性

11 session.setAttribute("password", "123456");

12 session.setAttribute("age", 16);

13 %>

14
Session的ID号:


15 session中保存的属性有:

16

17 //获取session中保存的属性

18 String[]names=session.getValueNames();

19 if(names!=null){

20 for(String str:names){

21 out.print(str+"\t");

22 }

23 }

24 session.invalidate();//销毁session

25 %>

26 点击在新标签页中打开session_page2.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果(不断刷新浏览器):

bc3f2c67b18bdf385a13ff74f73f1020.gif

Session默认session超时是30min设置session对象的超时有两种方式:

session.setMaxInactiveInterval(5);单位是秒

在web.xml中配置(单位是分钟):

30

3.9application对象

application对象实现了用户间数据的共享,可以存放全局变量。

application对象开始于服务器的启动,结束于服务器的关闭。

在用户的前后连接或者不同用户之间,可以对统一个application对象的属性进行操作。

在任何地方对application对象属性的操作将会影响到其他用户对此的访问。

application对象是ServletContext类的实例。

该对象的常用方法如下:

1 void setAttribute(String name,Object value); // 指定名称将对象绑定到此会话

2 Object getAttribute(String name); // 返回此会话中和指定名称绑定在一起的对象,如果没有对象绑定在该名称下则返回null

3 Enumeration getAttributeNames(); // 返回所有可用属性名的枚举

4 String getServerInfo(); // 返回JSP(Servlet)引擎名和版本号

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

application对象

2

3 //在application中保存3个键值对

4 application.setAttribute("city", "北京");

5 application.setAttribute("zipcode", "10000");

6 application.setAttribute("email", "io@gmail.com");

7 %>

8 所在城市:


9 application中存放的属性有:

10

11 Enumeration attrs = application.getAttributeNames();

12 while(attrs.hasMoreElements()){

13 out.print(attrs.nextElement()+"
");

14 }

15 %>

16


17 jsp(Servlet)引擎:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行效果:

0108788831e6a3f63dc4a52e6d5e986a.png

3.10page对象

page对象就是指向当前jsp页面本身(就好像类中的this),是java.lang.Object类的实例,常用方法和Object类的方法一致。例如它的toString()方法:

1

page内置对象

2 当前页面的page对象的字符串描述:

3

运行结果:

e5677b0000039101efbaf5c043a63e92.png

我们打开tomcat的work目录(编译生成的Servlet目录)看到它的包结构是org.apache.jsp,在该目录下有一系列的*_jsp.java和*_jsp.class文件。我们打开page_jsp.java发现类名就是page_jsp。

3.11pageContext对象

提供了对JSP页面内所有的对象及名字空间的访问。

可以访问到本页所在的session,也可以取本页面所在的application的某一属性值

相当于页面中所有功能的集大成者。

pageContext对象的本类名也叫pageContext。

常用方法:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 JspWriter getOut(); // 返回当前客户端响应被使用的JspWriter流(out)

2 HttpSession getSession(); // 返回当前页中的HttpSession对象(session)

3 Object getPage(); // 返回当前页面的Object对象(page)

4 ServletRequest getRequest(); // 返回当前页面的ServletRequest对象(request)

5 ServletResponse getResponse(); // 返回当前页面的ServletResponse对象(response)

6 void setAttribute(String name,Object value); // 设置属性键值对

7 Object getAttribute(String name,int scope); // 在指定范围内取属性值

8 void forward(String relativeUrlPath); // 将当前页面重定向到另一页面

9 void include(String relativeUrlPath); // 在当前页面包含另一文件

48304ba5e6f9fe08f3fa1abda7d326ab.png

我们在session_page1.jsp中向session中设置了用户名:

session.setAttribute("username", "admin");

%>

现在我们在pageContext.jsp中取出session中存储的用户名(注意要先打开session_page1.jsp):

pageContext内置对象

用户名:

运行结果:

3f5ccd938f28068e15975835c5fb811b.png

用pageContext实现页面跳转:

pageContext.forward("reg.jsp");

%>

运行结果:

756d18aed6966c7be6971a665a2eaae1.png

新建一个include.jsp(页面用于向页面输出当前的日期):

1

2

3

4 out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

5 %>

下面我们在pageContext.jsp页面中包含include.jsp:

1

pageContext内置对象

2 用户名:


3

4

5

3.12config对象

该对象是一个在servlet初始化时,jsp引擎向它传递信息时使用的,此信息包含Servlet初始化时所用到的参数(键-值对)以及服务器的相关信息(通过传递一个ServletContext对象),常用方法:

1 ServletContext getServletContext(); // 返回服务器相关信息的ServletContext对象

2 String getInitParameter(String name);// 返回初始化参数的值

3 Enumeration getInitParameterNames(); // 返回Servlet初始化时所有需要参数的枚举

3.13exception对象

该对象是一个异常对象,如果一个页面在运行过程中出现了异常就会产生这个对象。如果一个JSP页面需要应用此对象,就必须把isErrorPage设为true——否则无法编译。它实际上是java.lang.Throwable的对象,常用方法:

1 String getMessage(); // 返回异常的描述信息

2 String toString(); // 返回关于异常的简短描述信息

3 void printStackTrace(); // 显示异常及其栈轨迹

4 Throwable FillInStackTrace(); // 重写异常的执行栈轨迹

首先建立一个会出现异常的页面exception_text.jsp(并指定处理异常的页面):

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

6

这个页面肯定会出现异常

7

8

9

10

测试异常对象


11

12 out.println(100/0);//肯定会抛出运行时异常【算术异常】

13 %>

14

15

48304ba5e6f9fe08f3fa1abda7d326ab.png

然后建立处理异常的页面exception.jsp:

48304ba5e6f9fe08f3fa1abda7d326ab.png

My JSP 'exception.jsp' starting page

Exception内置对象

异常消息是:

异常的字符串描述:

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

e06d1b1293ee9779459ffe3a48307e24.png

3.14阶段案例——实现用户登录

这个案例比较简单:用户名和密码都是admin(没有使用数据库),如果用户名和密码相符,则页面跳转到login_success.jsp【服务器内部转发】,提示用户登录成功;如果用户登录失败,则页面跳转到login_failure.jsp【请求重定向】,提示用户登录失败。

整个项目的截图:

6684d9e3da15b1fedbb4205b4cdb97c4.png

834b865bff9842703c015a7a5da27f99.png

4.java beans

JavaBean是使用Java语言开发的一个可重用的组件,在JSP的开发中可以使用JavaBean减少重复的代码,使整个JSP代码的开发更加简洁。JSP配置JavaBean使用有以下优点:

1. 将html和java大妈分离,为日后的维护提供了方便。

2. 可以利用JavaBean的优点将常用到的程序写成JavaBean组件,节省开发时间。

简单JavaBean有以下几个名词:

VO:值对象,存放所有的传递数据的操作上

POJO:简单java对象

TO:传输对象,必须实现Serializable接口

WEB开发的标准目录结构

40c8d3e2e7f6b76e32457069a1b2a5a7.png

实际上在WEB-INF中的lib和classes目录就相当于一个默认的classpath(类执行时所需要的一个重要的环境属性)。当Tomcat启动之后,WEB-INF/lib和WEB-INF/classes都会自动配置到classpath中。

4.1java bean简介与设计原则

Javabeans就是符合某种特定规范的的Java类。它的好处有:

6ce72165e82a85595475b067ccf49448.png

一个Javabean要满足4个规范:

a7057855c2affa36ff3d5dbee5e68d37.png

例如以下的学生类就是一个Javabean:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 /**

2 * 这是一个典型的JavaBean

3 */

4

5 // 1.这是一个共有的类

6 public class Student {

7 // 2.属性私有

8 private String name;

9 private int age;

10

11 // 3.有共有的无参构造

12 public Student() {

13 }

14

15 // 4.getter和setter

16 public String getName() {

17 return name;

18 }

19

20 public void setName(String name) {

21 this.name = name;

22 }

23

24 public int getAge() {

25 return age;

26 }

27

28 public void setAge(int age) {

29 this.age = age;

30 }

31

32 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

JavaBean有2种应用方式:

de07a25dbbbdebb8dde7b55b5f448987.png

4.2jsp动作元素【运行时】

JSP动作元素(action elements),动作元素为请求处理阶段提供信息。动作元素遵循XML元素的语法——有一个元素名的开始标签,可以有属性、可选的内容、与开始标签匹配的结束标签。

6d249103de04f6df6a4175c1e484a2ae.png

4.3普通方式应用java bean

像使用普通java类一样,创建javabean实例。在MyEclipse项目的src目录下新建类Users:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package org.po;

2

3 /**

4 * 用户类-符合Javabean的实际原则

5 */

6 public class Users {

7 private String username;

8 private String password;

9

10 public Users() {

11

12 }

13

14 public String getUsername() {

15 return username;

16 }

17

18 public void setUsername(String username) {

19 this.username = username;

20 }

21

22 public String getPassword() {

23 return password;

24 }

25

26 public void setPassword(String password) {

27 this.password = password;

28 }

29

30 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

下面我们在javabean_page1.jsp中使用以上的Javabean:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

6

7

8

JavaBeans范例

9

10

11

12

使用普通方式创建Javabean的实例

13

14 //使用普通方式创建JavaBean

15 Users user = new Users();

16 user.setUsername("admin");

17 user.setPassword("admin");

18 %>

19 用户名:

20 密码:

21

22

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

0e2daef8f9d589a8c6d679c147e26702.png

4.4useBean动作元素

用于在jsp页面中实例化或者在指定范围内使用JavaBean。基本操作是首先使用id和作用域查找一个现有的对象,如果在指定的作用域中没有找到具有指定id的对象,那么它会试图使用其他属性创建一个新实例。语法如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

6

使用useBean动作指令来使用JavaBean

7

8

9

10

使用<jsp:useBean>动作指令来使用JavaBean

11

12

13 用户名:

14 密码:

15

16

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

b377c830918592d25261a56b96db9d7f.png

4.5setProperty

上一个jsp页面中取得的用户名和密码都为null,原因就是我们使用仅仅是实例化了Users对象,并没有为其成员变量执行属性。当然你也可以使用setXXX来给已经实例化的JavaBean设置属性,不过我更推荐使用setProperty指令。

的主要作用就是给已经实例化的JavaBean的属性赋值,一共有4种形式:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1                       

2                

3     

4

48304ba5e6f9fe08f3fa1abda7d326ab.png

方式一:【表单内容的自动全部匹配】

新建一个用户登录表单login.jsp:

1

2 用户名:

3 密码:

4   

5

处理用户登录的页面dologin.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

用户登录处理页面

12

13

14

15

16

17

18

19

setPerpority动作元素


20

21

22

23 用户名:

24 密码:

25

26

27

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

e54d7d673fe112ca9b72ec976772a759.png

这实际上以依靠表单中的name属性来匹配javabean中的成员变量。例如:在用户登录表单中input标记的属性有一个name="username",那么使用这种自动匹配的方式就会把这个username与javabean中的属性挨个查找,如果找到了就为这个字段设定相应的值——换言之:表单中的name属性要和要和javabean中的属性对应相同。

方式二:部分匹配表单的属性(dologin.jsp):

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

用户登录处理页面

12

13

14

15

16

17

18

19

setPerpority动作元素


20

21

22

23 用户名:

24 密码:

25

26

27

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

5b296be6d692e64a50b41539373b13e4.png

仅仅匹配了用户名属性,由于密码属性没有匹配,所以为null。这种方式也要注意表单的name属性要和javabean的属性相同。

方式三:手工给javabean的属性赋值——与表单无关(dologin.jsp):

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

用户登录处理页面

12

13

14

15

16

17

18

19

setPerpority动作元素


20

21

22

23

24 用户名:

25 密码:

26

27

28

48304ba5e6f9fe08f3fa1abda7d326ab.png

b391b822c409e64632220ab57eefee79.png

方式四(通过URL传参的方式给javabean赋值):

login.jsp:

通过url传参的方式给javabean的属性赋值

dologin.jsp:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

用户登录处理页面

12

13

14

15

16

17

18

19

setPerpority动作元素


20

21

22

23

24 用户名:

25 密码:

26

27

28

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

a4ad3f838eaf8b6faff51f603fd3779d.png

4.6getProperty

获取指定JavaBean对象的属性值【String类型】。语法:

前面的例子已经通过URL传递参数的方式指定了javabean的属性值,现在通过getProperty的方式获得javabean的属性值:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 String path = request.getContextPath();

4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

5 %>

6

7

8

9

10

11

用户登录处理页面

12

13

14

15

16

17

18

19

setPerpority动作元素


20

21

22

23

24

25

26

27 用户名:

28 密码:

29 --%>

30

31

32 用户名:

33 密码:

34

35

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

379f9d63cead0fc3c73e17824764c286.png

4.7java bean的4个作用域范围

使用useBean的scope属性可以指定javabean的作用域。

1 page // 当前页面有效,可以通过PageContext.getAttribute()获得JavaBean对象。

2 request // 同一个请求有效,可通过HttpRequest.getAttibute()方法获得JavaBean对象。

3 session // 同一个session有效,可通过HttpSession.getAttribute()方法获得JavaBean对象。

4 application // 同一个application有效,可通过application.getAttribute()方法获得JavaBean对象。

下面是一个简单的测试4个作用范围的示例:

dolog.jsp以URL传参的方式为javabean指定属性值:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

用户登录处理页面

6

7

8

9

10

11

12

13

setPerpority动作元素


14

15

16

17

18

19 测试javabean的4个作用域范围

20

21

22

48304ba5e6f9fe08f3fa1abda7d326ab.png

dologin.jsp中有一个跳转链接test_scope.jsp用于跳转页面,下面是test_scope.jsp。

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

6

7

检验useBean的4个作用域

8

9

10

11

检验useBean的4个作用域


12

13

14

15

用jsp动作元素获取javabean的属性值

16 用户名:

17 密码:


18

19

20

通过内置对象获取javabean的属性值

21 用户名:

22 密码:

23

24

48304ba5e6f9fe08f3fa1abda7d326ab.png

按照上面的例子分别将scope换成session、request和page得到如下如下结果:javabean的作用域范围从大到小依次是:application、session、request、page。

4.8JavaBean的删除

JavaBean虽然使用了标签进行创建,但是其操作仍然依靠的是4种属性范围。如果一个JavaBean不再使用的话,则可以使用对应的removeAttribute()方法进行删除。

1 pageContext.removeAttribute(JavaBean名称) // 删除page范围内的JavaBean

2 request.removeAttribute(JavaBean名称) // 删除request范围内的JavaBean

3 session.removeAttribute(JavaBean名称) // 删除session范围内的JavaBean

4 application.removeAttribute(JavaBean名称) // 删除application范围内的JavaBean

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package org.gpf;

2

3 public class Count {

4

5 private int count = 0;

6

7 public Count() {

8 System.out.println("======== 一个新的Count实例产生了 ========");

9 }

10

11 public int getCount() {

12 return ++count;

13 }

14

15 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4 count =

5

6 session.removeAttribute("c"); // 删除javaBean

7 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

73577d5a40056065481843728ca1c607.gif

我们本来设置的是session范围内的JavaBean,刷新页面不应该有新的JavaBean产生,但是我们在最后使用了session.removeAttribute()方法将创建的JavaBean删除了,因而每次请求都会产生新的JavaBean。

4.9model 1(JSP+JavaBean)简介

724e692035ad904e2612945b33b6f246.png

Model 1模型出现以前,整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接响应。这样做的一个弊端就是:在界面层(JSP页面)中充斥着大量的业务逻辑代码和数据访问层的代码,Web程序的可扩展性和可维护性非常差。

JavaBean的出现可以使得可以在JSP页面中调用JavaBean封装的数据或者业务逻辑代码,大大提升了程序的可维护性。下面的这张图简单描述了Model 1.

2f924b80a69a69c1b7f5f7a7b082dcc9.png

模型一体现了一种Web应用的分层架构。

4.9阶段项目(使用Model 1完成用户登录)

首先建立一个用户类Users(javabean):

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package org.po;

2

3 /**

4 * 用户类-javabean

5 */

6 public class Users {

7 private String username;

8 private String passwordString;

9

10 public Users() {

11 }

12

13 public String getUsername() {

14 return username;

15 }

16

17 public void setUsername(String username) {

18 this.username = username;

19 }

20

21 public String getPasswordString() {

22 return passwordString;

23 }

24

25 public void setPasswordString(String passwordString) {

26 this.passwordString = passwordString;

27 }

28

29 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

下面编写一个用户业务逻辑类:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package org.dao;

2

3 import org.po.Users;

4

5 /**

6 * 用户的业务逻辑类

7 */

8 public class UsersDAO {

9 public boolean isUserLogin(Users users) {

10 return "admin".equals(users.getUsername())

11 && "admin".equals(users.getPassword());

12 }

13 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

业务逻辑处理的页面dologin.jsp:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

7

8

9

10

11

12

13 request.setCharacterEncoding("utf-8");//防止中文乱码

14 if(userDAO.isUserLogin(loginUser)){

15 //如果用户登录成功则向session中设置用户名和密码

16 session.setAttribute("username", loginUser.getUsername());

17 session.setAttribute("password", loginUser.getPassword());

18 //请求转发

19 request.getRequestDispatcher("login_success.jsp").forward(request, response);

20 }else{

21 //重定向

22 response.sendRedirect("login_failure.jsp");

23 }

24 %>

48304ba5e6f9fe08f3fa1abda7d326ab.png

该项目中主要的修改的dologin.jsp在该页面中没有使用request对象直接从表单中读出数据,而是从javabean中取出属性,并且用户合法性的判断也放在了javabean中很好的体现了Web的分层思想(逻辑与页面分离)。

5.jsp状态管理

5.1http协议的无状态性

http的无状态性是指:当浏览器发送请求给服务器的时候,服务器响应客户端的请求。但是当浏览器再次发送请求给服务器的时候,服务器并不知道它就是刚刚的那个浏览器。——服务器不会记住你。为了保存用户的状态有两种机制:

da09b26de02f2385be32d3768042c294.png

5.2Cookie

Cookie是Web服务器保存在客户端的一系列文本信息。

Cookie的典型应用一:判断注册用户是否已经登录网站。保存用户的登录状态,简化登录的手续(记住密码)。

Cookie的典型应用二:“购物车”的处理。

Cookie的典型应用三:视频网站播放记录的存储。

670eaa1240ed75387c8b8c3b70b179d9.png

在JSP页面中创建和使用Cookie

1 Cookie newCookie = new Cookie(String key,Object value); // 创建Cookie对象

2 response.add(newCookie); // 写入Cookie对象

3 Cookie[] cookies = request.getCookies(); // 读取Cookie对象

Cooike对象的常用方法:

1 void setMaxAge(int expiry); // 设置cookie的有效期【秒】

2 void setValue(String value);// 对已经实例化的cookie对象赋值

3 String getName(); // 获得cookie的名称

4 String getValue(); // 获得cookie的值

5 int getMaxAge(); // 获得cookie的有效时间【秒】

注意:以上方法中的setValue(String value)和String getValue()方法的返回值都是字符串类型——因为Cookie本质上就是一个字符串存储在客户端,无论对它存值还是取值都应该是字符串类型。

5.3案例:Cookie在登录中的应用:

实现记忆用户名和密码的功能。

用户登陆页login.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户登录

7

8

9

10

11 /*获得Cookie中保存的用户名和密码*/

12 String username = "";

13 String password = "";

14

15 Cookie[]cookies = request.getCookies();

16 if(cookies!=null&&cookies.length>0){

17 for(Cookie c:cookies){

18 if(c.getName().equals("username")){

19 username = c.getValue();

20 }

21 if(c.getName().equals("password")){

22 password = c.getValue();

23 }

24 }

25 }

26 %>

27

28 请输入用户名和密码:

29

30

31 用户名:

32 密码:

33

34 十天内记住我

35

36

37

38

48304ba5e6f9fe08f3fa1abda7d326ab.png

处理用户登录的页面dologin.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

处理用户登录

7

8

9

10

登录成功!

11


12

13 //判断用户是否选择了记住密码

14 String[] isUseCookie = request.getParameterValues("isUseCookie");

15 if(isUseCookie!=null&&isUseCookie.length>0){

16 /*把用户名和密码保存在Cookie对象中*/

17 String username = request.getParameter("username");

18 String password = request.getParameter("password");

19 //创建2个Cookie对象

20 Cookie usernameCookie = new Cookie("username",username);

21 Cookie passwordCookie = new Cookie("password",password);

22 usernameCookie.setMaxAge(3600*24*10);//设置cookie生存期10天

23 passwordCookie.setMaxAge(3600*24*10);

24

25 //在客户端保存Cookie对象,需要依赖response对象的addCookie方法

26 response.addCookie(usernameCookie);

27 response.addCookie(passwordCookie);

28 }else{

29 /*使已经保存的cookie对象失效*/

30 Cookie[]cookies = request.getCookies();//得到客户端保存的cookie

31 if(cookies!=null&&cookies.length>0){

32 //遍历Cookie数组

33 for(Cookie c:cookies){

34 if(c.getName().equals("username")||c.getName().equals("password")){

35 c.setMaxAge(0);//设置Cookie的有效期是0,让其马上失效

36 response.addCookie(c);//重新向客户端保存Cookie

37 }

38 }

39 }

40 }

41 %>

42 点击查看用户信息

43

44

48304ba5e6f9fe08f3fa1abda7d326ab.png

用户信息显示页users.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户信息显示

7

8

9

10

用户信息

11


12

13 /*获得Cookie中保存的用户名和密码*/

14 String username = "";

15 String password = "";

16

17 Cookie[]cookies = request.getCookies();

18 if(cookies!=null&&cookies.length>0){

19 for(Cookie c:cookies){

20 if(c.getName().equals("username")){

21 username = c.getValue();

22 }

23 if(c.getName().equals("password")){

24 password = c.getValue();

25 }

26 }

27 }

28 %>

29 用户名:
密码:

30

31

48304ba5e6f9fe08f3fa1abda7d326ab.png

该项目一般情况下能够正常运行,但是当我们输入中文用户名的时候,服务器会抛出一个500的错误。要解决这个问题就需要依靠java网络包中的URLEncoder和URLDecoder,除此之外不要忘记了在每次使用request对象之前首先要设置request对象的编码方式。完整的代码如下:

login.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

7

用户登录

8

9

10

11

12 /*获得Cookie中保存的用户名和密码*/

13 String username = "";

14 String password = "";

15

16 request.setCharacterEncoding("utf-8");

17 Cookie[]cookies = request.getCookies();

18 if(cookies!=null&&cookies.length>0){

19 for(Cookie c:cookies){

20 if (c.getName().equals("username")) {

21 username = URLDecoder.decode(c.getValue(), "utf-8");

22 }

23 if (c.getName().equals("password")) {

24 password = URLDecoder.decode(c.getValue(), "utf-8");

25 }

26 }

27 }

28 %>

29

30 请输入用户名和密码:

31

32

33 用户名:

34 密码:

35

36 十天内记住我

37

38

39

40

48304ba5e6f9fe08f3fa1abda7d326ab.png

dologin.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 contentType="text/html; charset=utf-8"%>

4

5

6

7

处理用户登录

8

9

10

11

登录成功!

12


13

14 //判断用户是否选择了记住密码

15 request.setCharacterEncoding("utf-8");

16 String[] isUseCookie = request.getParameterValues("isUseCookie");

17 if (isUseCookie != null && isUseCookie.length > 0) {

18 /*把用户名和密码保存在Cookie对象中*/

19 //得到登录表单中的内容并编码

20 String username = URLEncoder.encode(

21 request.getParameter("username"), "utf-8");

22 String password = URLEncoder.encode(

23 request.getParameter("password"), "utf-8");

24 //创建2个Cookie对象

25 Cookie usernameCookie = new Cookie("username", username);

26 Cookie passwordCookie = new Cookie("password", password);

27 usernameCookie.setMaxAge(3600 * 24 * 10);//设置cookie生存期10天

28 passwordCookie.setMaxAge(3600 * 24 * 10);

29

30 //在客户端保存Cookie对象,需要依赖response对象的addCookie方法

31 response.addCookie(usernameCookie);

32 response.addCookie(passwordCookie);

33 } else {

34 /*使已经保存的cookie对象失效*/

35 Cookie[] cookies = request.getCookies();//得到客户端保存的cookie

36 if (cookies != null && cookies.length > 0) {

37 //遍历Cookie数组

38 for (Cookie c : cookies) {

39 if (c.getName().equals("username")

40 || c.getName().equals("password")) {

41 c.setMaxAge(0);//设置Cookie的有效期是0,让其马上失效

42 response.addCookie(c);//重新向客户端保存Cookie

43 }

44 }

45 }

46 }

47 %>

48 点击查看用户信息

49

50

48304ba5e6f9fe08f3fa1abda7d326ab.png

users.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 contentType="text/html; charset=utf-8"%>

4

5

6

7

用户信息显示

8

9

10

11

用户信息

12


13

14 /*获得Cookie中保存的用户名和密码*/

15 String username = "";

16 String password = "";

17

18 request.setCharacterEncoding("utf-8");

19 Cookie[] cookies = request.getCookies();

20 if (cookies != null && cookies.length > 0) {

21 for (Cookie c : cookies) {

22 if (c.getName().equals("username")) {

23 username = URLDecoder.decode(c.getValue(), "utf-8");

24 }

25 if (c.getName().equals("password")) {

26 password = URLDecoder.decode(c.getValue(), "utf-8");

27 }

28 }

29 }

30 %>

31 用户名:
密码:

32

33

48304ba5e6f9fe08f3fa1abda7d326ab.png

修正后的项目就支持中文用户名了。Cookie与Session的区别是Cookie存放于浏览器中,浏览器关闭后再打开,已经保存的cookie还是存在。

5.4Session与Cookie对比

Session

Cookie

保存位置

服务端保存用户信息

客户端保存用户信息

保存类型

Session中保存的是Object类型

Cookie中保存的是String类型

生命周期

会话结束,则存储的数据销毁

Cookie可长期保存在客户端

重要性

保存重要信息

保存不重要信息

6.jsp指令【编译时】与动作【运行时】元素

6.1include指令(可以包含其他页面)

语法:

例如我们要在include_command.jsp中包含date.jsp的页面——即:在include_command中显示date.jsp的内容:

date.jsp

1

2

3

4 out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

5 %>

include_command.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

在该页面中使用include指令将刚刚写的date.jsp包含进来

6

7

8

9

在该页面中使用include指令将刚刚写的date.jsp包含进来


10

11

12

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

72092c32498f50cda3ce7188d7b6beda.png

6.2include动作

include动作实际上是JSP动作标签,语法:

其中page属性是需要包含的页面的URL,而flush属性制定了被包含的页面是否从缓冲区中读取。

demo:使用include动作在include_action.jsp中包含date.jsp

include_action.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

include动作

6

7

8

9

在该页面中使用include动作将刚刚写的date.jsp包含进来


10

11

12

48304ba5e6f9fe08f3fa1abda7d326ab.png

使用include动作和include指令在jsp页面的执行效果上没有任何区别。

6.3include指令与include动作的区别

3e952474ed39c1ed28a9590812ef6aca.png

在Tomcat服务器的work目录中删除刚刚发布的工程:

f205194fa0f00cd70c92e09879b71685.png

先访问include_command.jsp

work目录生成以下内容:

0b34b8749018779028adf67a5fbeaaf4.png

打开include_005fcommand_jsp.java发现在它的源代码中有date.jsp的源代码:

out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));

include指令主页面和被包含的页面转换成了同一个Servlet。

在Tomcat的work目录中删除编译生成的Servlet,访问include_action.jsp生成以下文件:

45623f84ae52029fccea75dc0e94c278.png

打开include_005faction_jsp.java发现源代码中并没有包含date.jsp的源代码,而是由下面的一条代码将date.jsp的输出结果包含到该jsp页面:

// 该语句相当于调用date.jsp,并将date.jsp的输出结果返回给该页面

org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "date.jsp", out, false);

6.4forward动作

服务器内部转发指令,语法:

1

2

3 // 相当于

4 request.getRequestDispatcher("url").forward(request,response);

例如:在登陆页中将用户的表单处理交给forward_action.jsp页面处理,forward_action.jsp将该请求通过forward动作转发给users.jsp,users.jsp从request对象中取得用户名和密码给予显示:

login.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户登录

7

8

9

10 请输入用户名和密码:

11

12

13 用户名:

14 密码:

15

16

17

18

48304ba5e6f9fe08f3fa1abda7d326ab.png

forward_action.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

forward动作

6

7

8

9

该页面处理用户提交的表单信息

10

forward动作

11

12

13

14 request.getRequestDispatcher("users.jsp").forward(request, response);

15 --%>

16

17

48304ba5e6f9fe08f3fa1abda7d326ab.png

users.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户信息显示

7

8

9

10

用户信息

11


12

13 request.setCharacterEncoding("utf-8");

14

15 String username = "";

16 String password = "";

17 if(request.getParameter("username")!=null){

18 username = request.getParameter("username");

19 }

20 if(request.getParameter("password")!=null){

21 password = request.getParameter("password");

22 }

23 %>

24 用户名:
密码:

25

26

48304ba5e6f9fe08f3fa1abda7d326ab.png

运行结果:

2ebc68c82f2c3f0affb8405b2be98bed.png

6.5param动作

语法:

1

2

用户将提交的表单交给dologin.jsp处理,dologin.jsp通过forward动作把请求转发给users.jsp(并人为添加表单中没有的内容:邮箱,修改表单中提交的用户名为root),users.jsp通过request.getParamer()方法获得用户名、密码、邮箱并予以显示:

login.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户登录

7

8

9

10 请输入用户名和密码:

11

12

13 用户名:

14 密码:

15

16

17

18

48304ba5e6f9fe08f3fa1abda7d326ab.png

dologin.jsp

1

2

3

4

5

users.jsp

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 contentType="text/html; charset=utf-8"%>

3

4

5

6

用户信息显示

7

8

9

10

用户信息

11


12

13 request.setCharacterEncoding("utf-8");

14

15 String username = "";

16 String password = "";

17 String email = "";

18 if(request.getParameter("username")!=null){

19 username = request.getParameter("username");

20 }

21 if(request.getParameter("password")!=null){

22 password = request.getParameter("password");

23 }

24 if(request.getParameter("email")!=null){

25 email = request.getParameter("email");

26 }

27 %>

28 用户名:
密码:
邮箱:

29

30

48304ba5e6f9fe08f3fa1abda7d326ab.png

效果图:

8a7199c19dd9b538c15c3818d6ee53b4.png

7.jsp案例项目——商品浏览记录的实现

该项目使用Model1(JSP+JavaBean)使用Cookie机制实现。该项目使用到了数据库(数据库中存放了商品表)。实现步骤如下:

178f41acf8453f266d871e698ec26a6c.png

DB-->JavaBean-->JSP。项目的目录结构:

98cbe1bddcc48d22188c841d5c3d942c.png

一、实现DBHelper类:

该类的主要作用是取得数据库的连接并关闭相关资源。

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package util;

2

3 import java.sql.Connection;

4 import java.sql.DriverManager;

5 import java.sql.PreparedStatement;

6 import java.sql.ResultSet;

7 import java.sql.SQLException;

8

9 public class DBHelper {

10 private static final String DRIVER = "com.mysql.jdbc.Driver";

11 private static final String URL = "jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=UTF-8";

12 private static final String USER = "root";

13 private static final String PASSWORD = "mysqladmin";

14

15 private static Connection coon = null;// DB连接对象

16

17 /** 静态代码块加载DB驱动 */

18 static {

19 try {

20 Class.forName(DRIVER);

21 } catch (ClassNotFoundException e) {

22 e.printStackTrace();

23 }

24 }

25

26 /** Singleton设计模式返回DB连接对象 */

27 public static Connection getConnection() throws SQLException {

28 if (coon == null) {

29 coon = DriverManager.getConnection(URL, USER, PASSWORD);

30 return coon;

31 }

32 return coon;

33 }

34

35 /** 清理资源-关闭DB结果集、释放语句对象 */

36 public static void relsaseResource(ResultSet rs,PreparedStatement pstmt){

37 // 释放结果集

38 if (rs != null) {

39 try {

40 rs.close();

41 rs = null;

42 } catch (SQLException e) {

43 e.printStackTrace();

44 }

45 }

46 // 释放语句对象

47 if (pstmt != null) {

48 try {

49 pstmt.close();

50 pstmt = null;

51 } catch (SQLException e) {

52 e.printStackTrace();

53 }

54 }

55 }

56

57 /** 测试DB连接 */

58 public static void main(String[] args) {

59 try {

60 Connection connection = DBHelper.getConnection();

61 if(connection!=null){

62 System.out.println("数据库连接成功!");

63 }else {

64 System.out.println("数据库连接异常!");

65 }

66 } catch (SQLException e) {

67 e.printStackTrace();

68 }

69 }

70 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

如果shopping数据库没有创建可能会抛出异常只需要执行:

create database shopping;

二、商品实体类的设计:

在创建实体类之前先建立好数据库表:

数据库脚本:items.sql

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 /*

2 Navicat MySQL Data Transfer

3

4 Source Server : MySQL50

5 Source Server Version : 50067

6 Source Host : localhost:3306

7 Source Database : shopping

8

9 Target Server Type : MYSQL

10 Target Server Version : 50067

11 File Encoding : 65001

12

13 Date: 2014-08-27 12:12:31

14 */

15

16 SET FOREIGN_KEY_CHECKS=0;

17

18 -- ----------------------------

19 -- Table structure for items

20 -- ----------------------------

21 DROP TABLE IF EXISTS `items`;

22 CREATE TABLE `items` (

23 `id` int(11) NOT NULL auto_increment,

24 `name` varchar(50) default NULL,

25 `city` varchar(50) default NULL,

26 `price` int(11) default NULL,

27 `number` int(11) default NULL,

28 `picture` varchar(500) default NULL,

29 PRIMARY KEY (`id`)

30 ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

31

32 -- ----------------------------

33 -- Records of items

34 -- ----------------------------

35 INSERT INTO `items` VALUES ('1', '沃特篮球鞋', '佛山', '180', '500', '001.jpg');

36 INSERT INTO `items` VALUES ('2', '安踏运动鞋', '福州', '120', '800', '002.jpg');

37 INSERT INTO `items` VALUES ('3', '耐克运动鞋', '广州', '500', '1000', '003.jpg');

38 INSERT INTO `items` VALUES ('4', '阿迪达斯T血衫', '上海', '388', '600', '004.jpg');

39 INSERT INTO `items` VALUES ('5', '李宁文化衫', '广州', '180', '900', '005.jpg');

40 INSERT INTO `items` VALUES ('6', '小米3', '北京', '1999', '3000', '006.jpg');

41 INSERT INTO `items` VALUES ('7', '小米2S', '北京', '1299', '1000', '007.jpg');

42 INSERT INTO `items` VALUES ('8', 'thinkpad笔记本', '北京', '6999', '500', '008.jpg');

43 INSERT INTO `items` VALUES ('9', 'dell笔记本', '北京', '3999', '500', '009.jpg');

44 INSERT INTO `items` VALUES ('10', 'ipad5', '北京', '5999', '500', '010.jpg');

48304ba5e6f9fe08f3fa1abda7d326ab.png

在MySQL中查询:

c7453fd59983fef0e84bf27ac16cff9e.png

建立实体类(Items):也就是javabean其属性与DB中的各个字段一一对应。

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package entity;

2

3 /**

4 * 商品类(与DB中的表名一致)-javabean 属性和DB中表的字段完全一致

5 */

6 public class Items {

7 private int id;

8 private String name;

9 private String city;

10 private int price;

11 private int number;

12 private String picture;

13

14 public Items() {

15 }

16

17 public int getId() {

18 return id;

19 }

20

21 public void setId(int id) {

22 this.id = id;

23 }

24

25 public String getName() {

26 return name;

27 }

28

29 public void setName(String name) {

30 this.name = name;

31 }

32

33 public String getCity() {

34 return city;

35 }

36

37 public void setCity(String city) {

38 this.city = city;

39 }

40

41 public int getPrice() {

42 return price;

43 }

44

45 public void setPrice(int price) {

46 this.price = price;

47 }

48

49 public int getNumber() {

50 return number;

51 }

52

53 public void setNumber(int number) {

54 this.number = number;

55 }

56

57 public String getPicture() {

58 return picture;

59 }

60

61 public void setPicture(String picture) {

62 this.picture = picture;

63 }

64

65 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

三、实现业务逻辑类(数据访问层DAO)

该类需要完成的功能:

分析:

1.在index.jsp中我们需要展示所有的商品信息。——获得所有商品

2.当用户点击任意一种商品后会将id通过URL传递给details.jsp,而在details.jsp中我们需要——根据id获得对应商品。

3.根据Cookie传入的字符串获得最近浏览的5条记录。

思考:如何将浏览记录保存在Cookie中?

回答:只需要保存商品的ID即可,因为每个商品的ID是唯一的。

实现:把每次浏览的商品ID保存一个字符串中,将这个字符串保存在Cookie中,ID和ID之间用分隔符分隔,每次取出前5条记录。

显示所有商品的主页index.jsp

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4 contentType="text/html; charset=utf-8"%>

5

6

7

8

9

欢迎光临网上商城

10

11 div {

12 float: left;

13 margin: 10px;

14 }

15

16 div dd {

17 margin: 0px;

18 font-size: 10pt;

19 }

20

21 div dd.dd_name {

22 color: blue;

23 }

24

25 div dd.dd_city {

26 color: #000;

27 }

28

29

30

31

32

商品展示

33


34

35

36 border="0">

37

38

39

40

41 ItemsDAO itemsDAO = new ItemsDAO();

42 ArrayListlist = itemsDAO.getAllItems();

43 if(list!=null&&list.size()>0){

44 //遍历所有的商品

45 for(Items item:list){

46 %>

47

48

49

50

51 <%=item.getPicture()%20%>

52

53

54

55

产地:  价格:¥

56

57

58

59 }

60 }

61 %>

62

63

64

65

66

67

68

48304ba5e6f9fe08f3fa1abda7d326ab.png

显示商品详细信息的details.jsp

961ddebeb323a10fe0623af514929fc1.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3

4

5

6

7

8

欢迎光临网上商城

9

10 div{

11 float:left;

12 margin-left: 30px;

13 margin-right:30px;

14 margin-top: 5px;

15 margin-bottom: 5px;

16 }

17 div dd{

18 margin:0px;

19 font-size:10pt;

20 }

21 div dd.dd_name

22 {

23 color:blue;

24 }

25 div dd.dd_city

26 {

27 color:#000;

28 }

29

30

31

32

33

商品详情


34

35

36

37

38

39 Items item = new ItemsDAO().getItemsById(Integer.parseInt(request.getParameter("id")));

40 if(item!=null){

41 %>

42

43

44

45

<%=item.getPicture()%>

46

47

48

49

50

51

产地:

52

53

54

价格:¥

55

56

57

58

59 }

60 %>

61

62

63 String list = "";

64 // 从客户端获得Cookie集合

65 Cookie[]cookies = request.getCookies();

66 if(cookies!=null&&cookies.length>0){

67 for(Cookie c:cookies){

68 if(c.getName().equals("ListViewCookie")){

69 list = c.getValue();

70 }

71

72 String[] arr = list.split(",");

73 // 相同商品只在浏览记录中存放一次

74 if(Arrays.binarySearch(arr, request.getParameter("id"))<0){

75 list += request.getParameter("id") + ",";

76 }

77 // 如果浏览记录超过1000条,则清空Cookie

78 if(arr!=null&&arr.length>1000){

79 list = "";// 清零-置空串

80 }

81 Cookie cookie = new Cookie("ListViewCookie",list);

82 response.addCookie(cookie);

83 }

84 }

85 %>

86

87

88

89 您浏览过的商品

90

91

92 ArrayListitemsList = new ItemsDAO().getViewList(list);

93 if(itemsList!=null&&itemsList.size()>0){

94 for(Items i:itemsList){

95 %>

96

97

98

<%=i.getPicture()%20%>

99

100

产地:  价格:¥

101

102

103

104 }

105 }

106 %>

107

108

109

110

111

112

113

48304ba5e6f9fe08f3fa1abda7d326ab.png

主业务逻辑类ItemsDAO

8f900a89c6347c561fdf2122f13be562.png View Code

a13f8189a4ef70a377f5e2989da892de.png

d033c9b3c3173f050e2a7fb6f1581927.png

Tips:

解决中文乱码:

1)在执行获取请求参数前设置编码:

request.setCharacterEncoding(“汉字编码”);

2)转换字符编码:

1   //获取原始的请求参数值

2 String rawName = request.getParameter("name");

3 //将请求参数值使用ISO-8859-1字符串分解成字节数组

4 byte[] rawBytes = rawName.getBytes("ISO-8859-1");

5 //将字节数组重新编码成字符串

6 String name = new String(rawBytes , "gb2312");

3)获取请求参数同时转换编码:

request.getParameter(“name”).getBytes ("ISO-8859-1");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值