文档库 最新最全的文档下载
当前位置:文档库 › Java相关课程系列笔记之九Servlet学习笔记(建议用WPS打开)

Java相关课程系列笔记之九Servlet学习笔记(建议用WPS打开)

Java相关课程系列笔记之九Servlet学习笔记(建议用WPS打开)
Java相关课程系列笔记之九Servlet学习笔记(建议用WPS打开)

Servlet学习笔记

Java相关课程系列笔记之九

笔记内容说明

Servlet(程祖红老师主讲,占笔记内容100%);

目录

一、Servlet概述 (1)

1.1 B/S架构(了解) (1)

1.2什么是Servlet (1)

1.3什么是Tomcat (2)

1.4如何写一个Servlet(不使用开发工具) (3)

1.5使用MyEclipse开发Servlet (5)

1.6 Servlet是如何运行的 (6)

1.7常见错误及解决方式 (6)

1.8案例:根据请求次数显示结果和显示当前时间 (7)

二、HTTP协议 (8)

2.1什么是HTTP协议 (8)

2.2通讯的过程 (8)

2.3数据格式 (8)

2.4 TCP/IP Monitor的使用 (9)

2.5 get请求与post请求 (9)

2.6如何读取请求参数 (9)

2.7访问数据库(MySql) (10)

2.8案例:添加员工(访问MySql数据库) (10)

2.9异常:IllegalStateException (11)

三、编码问题 (12)

3.1 Java语言在内存当中默认使用的字符集 (12)

3.2编码 (12)

3.3解码 (12)

3.4 Servlet如何输出中文 (12)

3.5如果表单有中文参数值,也需要注意编码问题 (12)

3.6案例:根据请求正确显示中文 (12)

3.7将中文数据插入到数据库 (13)

四、重定向 (14)

4.1什么是重定向 (14)

4.2如何重定向 (14)

4.3注意两个问题 (14)

4.4两个特点 (14)

4.5重定向原理图:以2.8案例为例 (14)

五、DAO (15)

5.1什么是DAO (15)

5.2如何写一个DAO (15)

5.3工厂类 (15)

六、工厂设计模式 (16)

6.1什么是工厂 (16)

6.2使用工厂设计模式的好处 (16)

6.3如何使用工厂模式 (16)

6.4案例:为2.8案例添加新功能,并使用DAO和工厂模式 (16)

1

七、Servlet容器处理细节 (19)

7.1 Servlet容器如何处理请求资源路径以及匹配 (19)

7.2一个Servlet如何处理多种请求 (19)

八、Servlet的生命周期 (20)

8.1 Servlet的生命周期的含义 (20)

8.2 Servlet生命周期的四个阶段 (20)

8.3实例化 (20)

8.4初始化 (20)

8.5就绪 (20)

8.6销毁 (21)

8.7 Servlet生命周期图 (21)

8.8 Servlet生命周期相关的几个接口与类 (21)

九、JSP(简要介绍,详细内容见JSP笔记) (23)

9.1什么是JSP (23)

9.2为什么要使用JSP (23)

9.3 JSP与Servlet的关系 (23)

9.4如何写一个JSP文件 (23)

9.5 JSP是如何运行的 (23)

9.6指令 (24)

9.7案例:创建emplist.jsp页面,将表示逻辑交给JSP处理 (24)

十、请求转发 (26)

10.1什么是转发 (26)

10.2如何转发 (26)

10.3编程需要注意的两个问题 (26)

10.4转发原理图 (26)

10.5转发的特点 (27)

10.6转发和重定向的区别 (27)

10.7何时用重定向 (27)

10.8何时用转发 (27)

10.9案例:修改6.4案例中step7中的ListEmpServlet.java (28)

十一、异常的处理 (30)

11.1用输出流out (30)

11.2用转发的方式 (30)

11.3让容器处理系统异常 (30)

11.4案例:将10.9案例中的step3中的所有catch块修改 (30)

十二、路径问题 (31)

12.1什么是相对路径 (31)

12.2什么是绝对路径 (31)

12.3如何写绝对路径 (31)

12.4如何防止硬编码 (31)

12.5案例:相对、绝对路径对比 (31)

12.6四种情况下,正确的绝对路径写法 (32)

十三、状态管理 (33)

13.1什么是状态管理 (33)

2

13.3 cookie (33)

13.4如何创建一个cookie (33)

13.5查询cookie (33)

13.6编码问题 (34)

13.7 cookie的生存时间 (34)

13.8 cookie的路径问题 (34)

13.9 cookie的限制 (35)

13.10案例:写一个CookieUtil (35)

13.11 session(会话) (36)

13.12如何创建一个session对象 (36)

13.13 HttpSession接口中提供的常用方法 (36)

13.14 session的超时 (37)

13.15用户禁止cookie以后,如何继续使用session (37)

13.16 url重写 (37)

13.17 session的优点 (37)

13.18 session的缺点 (38)

13.19案例:session验证和访问次数 (38)

13.20案例:验证码 (39)

13.21案例:购物车 (41)

十四、过滤器 (45)

14.1什么是过滤器 (45)

14.2如何写一个过滤器 (45)

14.3案例:敏感字过滤器 (45)

14.4过滤器的优先级 (46)

14.5初始化参数 (47)

14.6优点 (47)

十五、监听器 (48)

15.1什么是监听器 (48)

15.2容器会产生两大类事件 (48)

15.3如何写一个监听器 (48)

15.4 ServletContext(Servlet上下文) (48)

15.5如何获得Servlet上下文 (48)

15.6 Servlet上下文的作用 (48)

15.7案例:统计在线人数 (49)

十六、上传文件 (51)

16.1如何上传文件 (51)

16.2案例:上传文件 (51)

十七、Servlet线程安全问题 (53)

17.1为何Servlet会有线程安全问题 (53)

17.2如何处理线程安全问题 (53)

十八、Servlet小结 (54)

18.1 Servlet基础 (54)

18.2 Servlet核心 (54)

3

18.4数据库访问 (54)

18.5过滤器和监听器 (54)

18.6典型案例和扩展 (54)

十九、其他注意事项 (55)

19.1连接数据库的工具 (55)

19.2知名网站 (55)

19.3 C/S架构:Client/Server (55)

19.4 B/S架构:Browser/Server (56)

4

一、Servlet概述

1.1 B/S架构(了解)

1)什么是B/S架构

客户端使用浏览器,服务端使用web浏览器,客户端跟服务器之间使用HTTP协议进行通讯。

2)优点

①客户端不需要单独安装(因为使用浏览器);C/S架构比较麻烦的是需要单独安装每个客户端,并且一旦客户端版本发生改变,就需要再次安装。

②开发相对简单;C/S架构需要我们分别在,客户端和服务器端编写相应的通信处理模块和自定义协议,而B/S架构使用标准的HTTP协议(即不再需要自定义协议),而且浏览器与Web服务器已经包含了相应的通信模块了。

1.2什么是Servlet

Sun公司制订的一种用来扩展Web服务器功能的组件规范。

1)扩展web服务器功能

早期(2000年左右)的Web服务器:apache的web server、微软的iis。只能够处理静态资源(即需要事先将html文件写好),不能够处理动态资源的请求(即需要依据请求参数然后进行计算,生成相应的页面)。

为了让这些web服务器能够处理动态资源的请求,需要扩展他们的功能。

早期使用的是CGI技术(Common Gateway Interface通用网关接口),可以使用很多语言编写,如perl,C/C++等来开发CGI程序。但是CGI程序有几个问题,比如开发比较复杂(因为需要程序员自己去分析请求参数)、性能不佳(因为当Web服务器收到请求之后,会启动一个CGI进程来处理请求)、CGI程序依赖平台(可移植性不好)。

现在,可以使用Servlet来扩展。

当浏览器将请求发送给Web服务器(比如:apcahe的web server),Web服务器会向Servlet容器发送请求,Servlet容器负责解析请求数据包。当然,也包括网络通讯相关的一些处理,然后将解析之后的数据交给Servlet来处理(Servlet只需要关注具体的业务处理,不用关心网络通讯相关的问题)。

1

2

◆ 注意事项:可以不使用服务器,而直接向Servlet 容器发送请求,因为Servlet 容器

里面也有个通信模块,所以也可直接把Servlet 容器当作简单的Web 服务器来使用。

2)组件规范

①组件:是符合一定规范,并且实现部分功能的可以单独部署的软件模块。组建必须要部署到容器里面才能运行。

②容器:也是符合一定规范,并且提供组件的运行环境的程序。

◆ 注意事项:单个的组件、单个的容器都是没意义的,都不能单独运行,需要放在一

起才能运行。

1.3什么是Tomcat

Tomcat 本身是一个Servlet 容器,即可以提供Servlet 运行环境的一个程序,但是Tomcat 还提供了Web 服务器所具有的所有功能,所以我们也称Tomcat 是一个Web 服务器。Tomcat 的默认端口是8080。

1)安装Tomcat (https://www.wendangku.net/doc/0f881928.html, 下载)

①Linux 系统下安装和配置的步骤

step1:解压到/home/soft01下

step2:配置环境变量

cd /home/soft01

vi .bash_profile

JA V A_HOME:jdk 的主目录

CA TALINA_HOME:tomcat 的主目录

PATH:CA TALINA_HOME/bin step3:启动Tomcat

cd /home/soft01/tomcat 主目录/bin sh startup.sh 或者sh catalina.sh run 接下来,可以打开浏览器,输入 http://localhost:8080,验证是否配置成功。

step4:关闭Tomcat

cd /home/soft01/tomcat 主目录/bin

sh shutdown.sh

②Windows系统下安装和配置的步骤

step1:解压到某个盘下

step2:配置环境变量

JA V A_HOME(JDK的主目录)必须配置

CA TALINA_HOME(Tomcat的主目录)可以不配置

PATH(Tomcat的bin目录)可以不配置

“我的电脑”右键“属性”,打开“系统属性”的“高级”选项卡,找到“环境变量。

新建“用户变量”。

新建JA V A_HOME。

◆注意事项:新建系统变量或新建用户变量均可,建议新建用户变量。

新建CA TALINA_HOME (可以不配置)。

新建PA TH(可以不配置)。

◆注意事项:

如果环境变量中已经有PA TH,修改该PATH即可,使用“;”分

号作分隔,如下所示:

PATH C:\Program Files\Java\jdk1.6.0_06\bin ;

D:\apache-tomcat-5.5.23\bin

Windows操作系统下以“;”分号为分隔符;linux系统下以“:”

冒号为分隔符。

step3:启动Tomcat

进入启动Tomcat的bin目录下,双击“startup.bat”。

接下来,可以打开浏览器,输入http://localhost:8080,验证是否配置成功。

step4:关闭Tomcat

进入启动Tomcat的bin目录下,双击“shutdown.bat”。

2)Tomcat目录结构简介

①bin目录:存放启动和关闭服务器的一些脚本(命令)。

②common目录:共享(部署在该服务器上的所有程序都可以使用)的一些jar包。

③conf目录:存放服务器的一些配置文件。

④webapps目录:部署目录。

⑤work目录:服务器运行时,生成的一些临时文件。

1.4如何写一个Servlet(不使用开发工具)

step1:先写一个Java类,实现Servlet接口或者继承HttpServlet抽象类。

public class HelloWorldServlet extends HttpServlet {

//Tomcat会自动调用service,自己不用再去写方法调用了,所以必须把名字写对!

public void service(HttpServletRequest request,HttpServletResponse response)

throws ServletException,IOException{

//异常必须写两个,不能写成Exception,也不能再多个异常

//设置一个消息头content-type,告诉浏览器返回的数据类型是一个html文档,以及编码格式。此外,还可以告诉服务器,在使用out输出时,使用指定的编码格式进行编码response.setContentType("text/html;charset=utf-8"");

//通过响应对象,获得一个输出流

3

PrintWriter out=response.getWriter();

//调用流的方法进行输出,其实质是将处理结果写到了response对象上

out.println("Hello World");

/** out.close()不调用也可以,因为Servlet方法执行完毕,容器会自动调用out.close方法*/ out.close(); } } step2:执行编译操作:javac -d . HelloWorldServlet.java

但是会报错,找不到某些类!其中-d . 代表把编译后的文件放在当前文件夹下。

把Tomcat安装目录中common中lib中的servlet-api.jar和刚编写类放一起(是编译时需要用的jar)。

再次编译:javac -cp servlet-api.jar -d . HelloWorldServlet.java,其中-cp servlet-api.jar表示告诉Java编译器去哪里找需要的class文件(到servlet-api.jar的jar包中找)。

step3:打包,即创建一个具有如下结构的文件夹:

appname(文件夹名起应用名)

|--WEB-INF(必须大写)

|--classes(文件夹,放.class文件)

|--lib(文件夹,放.jar文件,可没有)

|--web.xml(部署描述文件url-pattern)

将编译好的.class文件放入classes文件夹中(如有包,则一起放入)。

web.xml文件内容:

xmlns="https://www.wendangku.net/doc/0f881928.html,/xml/ns/j2ee"

xmlns:xsi="https://www.wendangku.net/doc/0f881928.html,/2001/XMLSchema-instance"

xsi:schemaLocation="https://www.wendangku.net/doc/0f881928.html,/xml/ns/j2ee

https://www.wendangku.net/doc/0f881928.html,/xml/ns/j2ee/web-app_2_4.xsd">

helloWorld

Servletday01.HelloWorldServlet

helloWorld

/hello

step4:部署,将step3创建的文件夹拷贝到Servlet容器特定的文件夹下面(拷贝到Tomcat 的webapps目录下)。

注意事项:也可以将step3创建的文件夹使用jar命令进行压缩,生成.war为后缀的文件,然后拷贝。

step5:启动Servlet容器,访问Servlet。

访问格式:http://ip:port/appname/url-pattern

比如在浏览器地址栏输入:http://localhost:8080/web01/hello

4

1.5使用MyEclipse开发Servlet

step1:配置MyEclipse,使得MyEclipse能够管理Tomcat。

1)点击工具栏上的“Run/Stop/Restart MyEclipse Servers”图标旁边的下拉箭头,选择“Configure Server”。

2)在弹出的对话框“Preferences”中展开“MyEclipse”--“Servers”--“Tomcat”--“Tomcat5.X”

◆注意事项:选择你目前电脑上Tomcat的版本,此处以Tomcat5为例。

3)将Tomat server选项置为“Enable”(默认为“Disable”)。

4)点击“Tomcat home directory”之后的“Browse”按钮,选择Tomcat主目录,确定,然后“Tomcat base directory”和“Tomcat temp directory”自动生成,点击“OK”。

◆注意事项:两项可改可不改的:

Tomcat下的JDK--“Tomcat JDK name”是自己已安装的JDK(Tomcat也是java 写的也得依赖JDK)。

建议Tomcat下的Launch--“Tomcat launch mode”设置为Run model,默认为Debug mode而该模式在有些时候会显示不正常。

5)回到工具栏上的“Run/Stop/Restart MyEclipse Servers”图标旁边的下拉箭头,选择Tomcat 5.x,点击“Start”。

6)当在控制台显示“Server startup in XXX ms“,则Tomcat启动成功。

◆注意事项:如果出现“Address already in use:JVM_Bind”异常,则说明已经启动了

一个Tomcat。解决办法:运行shutdown命令,关闭之前开启的Tomcat。

step2:建立一个Web Project(Web工程),填写“Project name”,JDK最好选5.0,其他选项默认,点击“Finish”。

step3:编写Java类和web.xml文件。

step4:部署项目到Tomcat服务器。

1)点击工具栏“Deploy MyEclipse J2EE Project to Server”按钮。

2)弹出对话框“Project Deployments”,点击“Add”按钮。

3)弹出“New Deployment”对话框,选择“Tomcat 5.x”,点击“Finish”,最后点击"OK"。

◆注意事项:在对话框“Project Deployments”对话框有4个按钮,常用的为

①“Add”按钮:在Tomcat服务器上增加新应用。

②“Remove”按钮:删除Tomcat服务器上的新应用。

③“Redeploy”按钮:重新部署该应用,一般每次修改后都需要重新部署一下。step5:访问Tomcat服务器上的Servlet实例。

访问格式:http://ip:port/appname/url-pattern

比如在浏览器地址栏输入:http://localhost:8080/web01/hello

◆注意事项:

在IDE工具(集成开发环境)中启动Tomcat部署项目后,不需要重新启动服务器,系统会自动部署。

IDE工具简化了Servlet的开发步骤:

第1步写一个java类手动

第2步编译自动

第3步打包自动

第4步部署不用手动拷贝,点一下

第5步启动服务器,访问servlet 手动

默认情况下,应用名和工程名相同。

5

工程--属性--MyEclipse--Web--Web Context可修改部署后的应用名。

新建Web工程时也可以手动在Context root RUL中更改应用名。

1.6 Servlet是如何运行的

比如,在浏览器地址栏输入:http://ip:port/web01/hello(web01/hello为请求资源路径)。step1:浏览器依据ip和port建立与Servlet容器之间的连接。

step2:浏览器将请求数据打包(即按照http协议的要求,将相关数据封装成一个数据包,一般称之为请求数据包)并发送给Servlet容器。

step3:Servlet容器解析请求数据包,并将解析之后得到的数据放到已创建的request对象上,同时,容器也已经创建好了一个response对象。

step4:Servlet容器依据请求资源路径(即/web01/hello)找到Servlet的配置,然后创建Servlet 对象(根据xml文件里配置的类而创建)。

step5:Servlet容器接下来调用Servlet对象的service方法,并且会将事先创建好的request对象和response对象作为service方法的参数传递给Servlet对象。

step6:Servlet可以通过request对象获得请求参数,进行相应的处理,然后将处理结果写到response对象上。

step7:Servlet容器读取response对象上的数据,然后将处理结果打包(响应数据包)并发送给浏览器。

step8:浏览器解析响应数据包,将返回的数据展现给用户。

1.7常见错误及解决方式

1)404:是一个状态码(是一个三位数字,由服务器发送给浏览器,告诉浏览器是否正确处理了请求),404的意思是说:服务器依据请求资源路径,找不到对应的资源。

解决:①依据http://ip:port/appname/url-pattern检查你的请求地址是否正确。

②仔细检查web.xml,特别要注意servlet-name是否一致。

2)500:服务器处理出错,一般是因为程序运行出错。

解决:①检查程序的代码,比如:是否继承。

②检查web.xml,类名要填写正确。

3)405:服务器找不到对应的service方法。

解决:检查service方法的签名(方法名、参数类型、返回类型、异常类型)。

6

1.8案例:根据请求次数显示结果和显示当前时间

eg1:在地址栏输入http://localhost:8080/web01/hello?qty=5后,获得5个Hello World 注意事项:qty:请求参数名字。5:请求次数为5。

public void service(HttpServletRequest request,

HttpServletResponse response) throws ServletException,IOException{ //读请求参数值,返回值是String

String qtyStr=request.getParameter("qty"); int qty=Integer.parseInt(qtyStr);//转成整数

String rs=""; for(int i=0;i

rs+="

Hello World
"; } //输出处理结果,设置一个消息头content-type,告诉浏览器返回的数据类型是一个html文档

response.setContentType("text/html");

PrintWriter out=response.getWriter();//通过响应对象,获得一个输出流

//调用流的方法进行输出,其实质是将处理结果写到了response对象上

out.println(rs); out.close(); }

eg2:在网页上显示当前时间

step1:Java类中写

public void service (HttpServletRequest request,

HttpServletResponse response) throws ServletException,IOException{ response.setContentType("text/html");//告诉浏览器返回的数据类型是一个html文档

PrintWriter out=response.getWriter();//通过响应对象,获得一个输出流

Date date=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

String now=sdf.format(date); out.println(now);//输出到页面out.close(); } step2:web.xml中写:

Date

Servletday01.DateDemo

Date

/date

7

8 二、HTTP 协议

2.1什么是HTTP 协议

HTTP (Hypertext transport protocol )是超文本传输协议。是一种应用层协议,由W3C 制定,它定义了浏览器(或者其他客户端)与Web 服务器之间通讯的过程及数据格式。

2.2通讯的过程

step1:浏览器建立与Web 服务器之间的连接(Socket )。

step2:浏览器要将请求数据打包(请求数据包),然后发送给Web 服务器。

step3:Web 服务器将处理结果打包(响应数据包),然后发送给浏览器。

step4:Web 服务器关闭连接。

注意事项:特点:一次请求,一次连接。优点:Web 服务器可以利用有限的连接个数为

尽可能多的客户服务(效率高)。如果浏览器要再发请求,就必须重新建立一个新的连接。

2.3数据格式

1)请求数据包

①请求行:请求方式+请求资源路径+协议描述。

②若干消息头:消息头是一些键值对,一般由W3C 定义,有特定的含义。浏览器和服务器之间,可以通过发送消息头来传递一些特定的信息,比如:浏览器可以通过user-agent 消息头来通知服务器浏览器的类型和版本。

③实体内容:只有当请求方式为post 时,浏览器才会将请求参数添加到实体内容里面,如果请求方式为get ,浏览器会将请求参数添加到请求资源路径的后面。

2)响应数据包

①状态行:协议描述+状态码+状态描述。

②若干消息头:服务器也可以发送一些消息头给浏览器,比如content-type ,告诉浏览器服务器返回的数据类型和编码格式(字符集,比如:UTF-8、ISO-8859-1)。

③实体内容:程序处理之后,返回的结果。

3)截获数据包,使用MyEclipse 中的TCP/IP

Monitor ,TCP/IP Monitor 相当于一个代理服务器,它的原理图如下:

2.4 TCP/IP Monitor的使用

1)Window--Show View--Other--MyEclipse Common--TCP/IP Monitor

2)在TCP/IP Monitor的空白处点右键--Properties--弹出对话框点Add,增加新的监视器:

3)点击Start,启动代理服务器--OK。

4)测试1.8案例eg1,地址栏输入:http://localhost:8888/web01/hello?qty=5,注意使用代理端口号!执行完毕,即可查看TCP/IP Monitor出现的内容。

2.5 get请求与post请求

1)哪些情况下,浏览器会使用get方式发请求:

①直接在浏览器地址输入某个地址。②点击链接地址。

③表单默认的提交方法:

2)哪些情况下,浏览器会用post方法发请求:

①设置表单的method属性值为“post”。

3)get请求的特点:

①get请求会将请求参数添加到请求资源路径的后面,因为请求行存放的数据大小有限(也就是地址栏的最长字节数),所以get请求只能提交少量的数据。

②get请求会将请求参数显示在浏览器地址栏,不安全(比如,路由器会记录整个地址)。

4)post请求的特点:

①post请求会将请求参数添加到实体内容里面,所以,可以提交大量的数据。

②post请求不会将请求参数显示在浏览器地址栏,相对安全一些。但是,post请求并不会对请求参数进行加密处理。用HTTPS协议进行加密处理。

◆注意事项:服务器不关心是用浏览器还是Java程序发送的请求,只要符合协议格式,

都会处理。

2.6如何读取请求参数

1)方法一:String request.getParameter(String paraName);

①如果paraName(即参数名称)与实际的参数名称不一致,会获得null(不报错)。

②在使用表单提交数据时,如果用户没有填写任何的值,会获得空字符串"" 。

2)方法二:String[] request.getParameterValues(String paraName);

①当有多个参数且名称相同时,使用该方法。比如:?city=bj&city=cs&city=wh

◆注意事项:getParameterValues方法也可用于只有一个参数的情况。

9

2.7访问数据库(MySql)

1)使用MySql数据库

①登录MySql:mysql -uroot;//登录mysql,使用root用户权限

②查看当前所有的数据库:show databases;

③创建一个新的数据库:create database db_chang default character set utf8;//创建db_chang数据库,默认是用utf8编码集(不能写减号- )

④使用某个数据库:use db_chang;

⑤查看当前数据库有哪些表:show tables; drop table tablname;//删表

⑥建表:

create table chang_emp( id int primary key auto_increment,

name varchar(50), salary double, age int );

insert into chang_emp(name,salary,age) values("tom",10000,23);

注意事项:auto_increment:自增长列,即插入记录时,数据库会自动为该列赋一个唯一的值(相当于Oracle中的序列sequence)。

2)使用JDBC访问数据库

step1:将JDBC驱动放到WEB-INF\lib下

step2:编写JDBC代码,需要注意异常的处理!

2.8案例:添加员工(访问MySql数据库)

step1:addEmpMySql.html页面内容:

添加员工 姓名:
薪水:
年龄:

step2:ListEmpServlet.java中service方法内容:

Connection conn=null;

try { Class.forName("com.mysql.jdbc.Driver");

conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_chang","root","");

Statement state=conn.createStatement();

ResultSet rs=state.executeQuery("select * from chang_emp order by id");

response.setContentType("text/html;charset=utf-8");

PrintWriter out=response.getWriter();

out.println("

");

out.println("

");

while(rs.next()){ long id=rs.getLong("id"); String name=rs.getString("name");

double salary=rs.getDouble("salary"); int age=rs.getInt("age");

out.println("

" +

"

"); }

out.println("

id姓名薪水年龄
"+id+""+name+""+salary+""+age+"
");

out.println( "再次添加新员工"); out.close();

}catch(Exception e) { e.printStackTrace();

}finally{ if(conn!=null){ try { conn.close();

}catch (SQLException e) { e.printStackTrace(); } } }

10

11 step3:AddEmpMySql.java 中service 方法内容:

request.setCharacterEncoding("utf-8");

String nameStr=request.getParameter("name");

String salaryStr=request.getParameter("salary"); String ageStr=request.getParameter("age");

PrintWriter out=response.getWriter();

Connection conn=null;//将员工信息插入到数据库

try { Class.forName("com.mysql.jdbc.Driver"); conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_chang","root","");

/** 此处不妥~若插入中文数据,会出现乱码!具体措施详见第三章!! */

PreparedStatement prep=conn.prepareStatement(

"insert into chang_emp(name,salary,age) values(?,?,?)");

prep.setString(1, nameStr); prep.setDouble(2, Double.parseDouble(salaryStr)); prep.setInt(3, Integer.parseInt(ageStr)); prep.executeUpdate();

/** response.setContentType("text/html;charset=utf-8"); out.println("添加成功"); out.println("再次添加");//不使用重定向 */ response.sendRedirect("list");//使用重定向,详见第四章 out.close();

} catch (Exception e) {

/** 异常发生之后,首先记录日志,一般会将日志记录到文件里面,可以用一些日志工具,比如log4j 来记录 */

e.printStackTrace();

/** 接下来,看异常能否恢复,如果能,则编写处理代码。如果不能,则提示用户稍后重试。一般来说,系统异常是不能恢复的,所谓系统异常:指的是不是因为程序的原因产生的异常,比如:数据库服务停止、连接数据库的网络中断等 */

response.setContentType("text/html;charset=utf-8");

out.println("系统繁忙,稍后重试");

out.println("重试");

}finally{ //与step2相同,此处略 }

step4:web.xml 内容(为了省纸,采取如下格式)

AddEmpMySql

Servletday02.AddEmpMySql

ListEmpServlet

Servletday02.ListEmpServlet

AddEmpMySql

/addempmysql

ListEmpServlet

/list

step5:在浏览器地址栏输入http://localhost:8080/应用名/list 则访问出员工列表页面。

2.9异常:IllegalStateException

出现如下错误可以不用理会,是因为Tomcat 热部署造成的,重新手动部署一下即可:

三、编码问题

3.1 Java语言在内存当中默认使用的字符集

默认会用“Unicode”编码格式(字符集)来保存字符。

3.2编码

把Unicode这种编码格式对应的字节数组,转换成某种本地编码格式(比如GBK)对应的字节数组,从而保存。Unicode-->GBK。

3.3解码

把某种本地编码格式的字节数组转换成Unicode这种编码格式对应的字节数组。GBK-->Unicode。

◆注意事项:服务器默认使用ISO-8859-1编码格式,使用1个字节保存,无法存中文!

因此中文会出现乱码。

3.4 Servlet如何输出中文

需要调用:response.setContentType("text/html;charset=utf-8");其中charset=utf-8表示:1)用来指定编码格式,只要支持中文即可,比如也可设置为charset=gbk。

2)作用两个:①生成一个content-type消息头,告诉浏览器返回的数据类型和编码格式。

②服务器在输出时,会使用指定的编码格式进行编码。

3.5如果表单有中文参数值,也需要注意编码问题

因为,当表单提交的时候,浏览器会对表单中的数据进行编码(会使用打开表单时的编码格式进行编码),而服务器默认情况下,会使用ISO-8859-1去解码,所以,会产生乱码问题。

1)解决方式一:

step1:先保证表单所在的页面按照指定的编码格式打开。即:

已是一种规范(模拟content-type消息头,告诉浏览器正在解析的数据类型和编码格式)。

step2:调用request.setCharacterEncoding("utf-8");意思是告诉服务器,使用指定的编码格式进行解码。

◆注意事项:该方法只能用于"post"请求!注意代码放置顺序,在

request.getParameter()方法前。

2)解决方式二:

step1:同方式一的第一步。

step2:使用new String(str.getBytes("iso-8859-1"),"utf-8");

比如:String name=request.getParameter("uname");

name = new String(name.getBytes("iso-8859-1"),"utf-8");

3.6案例:根据请求正确显示中文

step1:表单页面

请输入数量: 打招呼的人:

12

step2:HelloWorldServlet类中service方法写

//request.setCharacterEncoding("utf-8");//方式一

String qtyStr=request.getParameter("qty");//读请求参数值

int qty=Integer.parseInt(qtyStr);//转成整数

String uname=request.getParameter("uname");

uname = new String(uname.getBytes("iso-8859-1"),"utf-8");//方式二

String rs="";//处理请求,生成处理结果

for(int i=0;i"; } /** 输出处理结果,设置一个消息头content-type,告诉浏览器返回的数据类型是一个html 文档,以及编码格式。此外,还可以告诉服务器,在使用out输出时,使用指定的编码格式进行编码*/

response.setContentType("text/html;charset=utf-8");

PrintWriter out=response.getWriter();//通过响应对象,获得一个输出流

out.println(rs);//调用流的方法进行输出,其实质是将处理结果写到了response对象上

out.close();

3.7将中文数据插入到数据库

程序从内存Unicode编码格式--->数据库中的某种本地格式。

step1:要确保数据库支持中文,即正确设置数据库的字符集。

例如,建MySql的数据库时设置编码:create database db_chang default character set utf8; step2:JDBC驱动必须能够正确地进行编码和解码。有些MySql的驱动不能够正确进行编码和解码(默认使用ISO-8859-1进行编码和解码),可以在JDBC的URL后添加:“useUnicode=true&characterEncoding=utf8”。

例如:conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_chang?" +

"useUnicode=true&characterEncoding=utf8","root","");

◆注意事项:

MySql中utf不能写“-”,记得数据库名后有个“?”。

MySql客户端也是一个程序,也会有编码问题,若你的程序中数据显示正常,而MySql客户端中查询的数据为乱码,则更改下编码,使用:set names gbk;命

令。

13

14 四、重定向

4.1什么是重定向

服务器发送一个302状态码及一个Location 消息头(值是一个地址,称为重定向地址),通知浏览器立即向重定向地址发请求。

4.2如何重定向

使用response.sendRedirect(String url); 4.3注意两个问题

1)重定向之前,不要调用out.close();会报错!

out.println("添加成功");//能看到这个输出!(如果不写这个输出,则响应为空白页)

out.close(); response.sendRedirect("list");//看不到重定向结果!

2)重定向之前,服务器会先清空response 对象上缓存的数据。Servlet 只允许同时发送一个响应。

out.println("添加成功");//看不到这个输出!缓存数据被清空(响应一)

response.sendRedirect("list");//能看到重定向结果!(响应二) out.close();

4.4两个特点

1)重定向的地址是任意的(前提要存在否则报404)。

2)重定向之后,浏览器地址栏的地址会变成重定向地址。

4.5重定向原理图:以2.8案例为例

相关文档