1、servlet是什么?
(1)是sun公司制订的一种用来扩展web服务器功能的组件规范。
a, 扩展web服务器功能
早期的web服务器(比如 apache http server,微软的iis)只能够处理静态资源(需要事先将html文件写好,放到服务器特定的文件夹下面)
的请求,不能够处理动态资源(需要依据请求参数进行计算,动态生成相应的html)的请求。
早期,要扩展web服务器的功能,可以使用cgi程序来扩展:事先将cgi程序(使用perl,c等语言开发的,符合cgi编程规范的程序)写好,
然后将cgi程序放到web服务器特定的文件夹下面。当web服务器收到请求之后,会调用cgi程序来处理。
cgi程序编写比较复杂(因为需要程序员自己处理请求参数),而且程序的可移值性不好(因为开发cgi程序的语言,比如perl,c都是与平台有关的语言)。
b, 组件规范
b1,组件是什么?
符合相应的规范、并且实现了部分功能的、需要部署在相应的容器上运行的软件模块。
b2,容器是什么?
容器是一个符合相应的规范,并且提供组件的运行环境的程序。
2、servlet容器
(1) servlet容器除了可以运行servlet以外,还可以直接充当 一个简单的web服务器。
比如tomcat本身是一个servlet容器,但是,也可以直接接受浏览器的请求。
(2) tomcat的安装与简单的使用
1)安装 ( http://www.apache.org下载)
step1, 先解压tomcat到/home/soft01下
(压缩文件在/opt/apache-tomcat-5.5.23.tar.gz)
step2, 配置环境变量
cd /home/soft01
vi .bash_profile
添加
JAVA_HOME:jdk安装的路径,比如
/opt/jdk1.6
CATALINA_HOME:tomcat的安装路径,
比如 /home/soft01/tomcat5.5
PATH: /home/soft01/tomcat5.5/bin
step3, 启动tomcat
cd /home/soft01/apache-tomcat5.5/bin
sh startup.sh(或者 sh catalina.sh run)
然后打开浏览器,输入 http://localhost:8080
step4, 关闭tomcat
sh shutdown.sh
2) 安装完之后,tomcat的几个主要的文件夹的作用(了解)
a,bin: 是一些执行文件,比如启动和关闭tomcat的文件。
b,common: 放在这个文件夹下的jar文件,可以被部署到该容器上的所有的程序共享。
c,conf: tomcat的配置文件。
d, webapps: 部署文件夹,就是说,当我们开发完了一个servlet,需要将servlet拷贝到这儿。
e, work: tomcat在运行时, 生成的一些临时文件。
3、如何写一个servlet?
step1, 写一个java类(servlet只能够使用java语言来开发)实现Servlet接口或者继承HttpServlet类。
step2, 编译 (使用javac命令 生成字节码文件)
step3, 打包,即建立一个具下如下结构的文件夹:
appname(应用名称)
WEB-INF
classes(.class文件)
lib(可选,放.jar文件)
web.xml(部署描述文件)
step4, 部署
将step3生成的文件夹拷贝到servlet容器特定的文件夹下面(比如,tomcat对应的是webapps)。
也可以将step3生成的文件夹使用jar命令压缩成.war为后缀的文件,然后再拷贝。
step5,启动servlet容器
http://ip:port/appname/servlet-url
ip: servlet容器所在的机器的ip地址。
port: servlet容器监听的端口号。
servlet-url: web.xml文件当中,servlet 的 url-pattern的配置。
4、使用myeclipse开发servlet
(1)启动myeclipse,让myeclipse来管理tomcat。
点击"run/stop/restart myeclipse servers"
选择"config server",在弹出的窗口中,选择
"myeclipse-application servers-tomcat-tomcat5.x"
在右边,配置好tomcat的主目录。
(2)建一个web工程
5、servlet是如何运行的?
比如,我们在浏览器地址栏输入http://ip:port/web01/hello
step1, 浏览器依据ip,port建立与servlet容器之间的连接。
step2, 浏览器将一些数据打包(一些消息头、请求参数等等),然后将请求数据包发送给容器。
step3, 容器收到请求数据包之后,会拆包(将请求数据包中的数据解析出来),并且将得到的数据放到request对象上,同时,容器还会创建response对象。
step4, 容器要依据请求资源路径("/web01/hello")找到对应的servlet的配置信息(servlet-class),然后,创建这个servlet对象。
step5, 容器会调用servlet对象的service方法。容器会将request对象,response对象作为参数进行传递。所以,在service方法里,可以通过request对象获得请求参数,并且进行相应的处理,
也可以将处理结果通过response对象发送给客户端(浏览器)。容器为servlet提供了网络相关的基础服务,开发人员在写servlet时,不用了解http协议。
step6, 容器通过response获得处理结果,然后打包(响应数据包)并且发送给浏览器。
step7, 浏览器将容器返回的数据包进行解析(拆包), 获得相应的数据,然后生成相应的页面。
6、常见问题及解决方式
(1) 404 : 服务器依据请求资源路径找不到对应的资源。
a, 状态码:是一个三位数字,由web服务器发送给客户端(浏览器)表示服务器处理的一种状态。
b,错误原因:
请求资源路径写错了。
c,解决方式:
依据 http://ip:port/appname/servlet-url检查
你写的请求资源路径。
另外,还需要检查一下web.xml文件, servlet-name有没有写正确。
(2) 500: 系统出错
a,错误原因
程序运行时出错。
b,解决方式
b1, 检查程序代码。
另外,还需要注意
b2, 检查 servlet-class的配置, 有没有把类名写错(必须是完整的类名)。
b3, 必须继承HttpServlet
(3) 405: 容器找不到service方法。
解决方式: 检查service方法的签名。
7、如何获得请求参数值
http://ip:port/web01/hello?name=jetty
1) String request.getParameter(String paraName);
该方法的作用是:依据参数名(paraName)获取参数值。
在使用时,需要注意两点:
a, 如果参数名写错,返回null。
b,有可能返回""。
另外还要注意:
在服务器端获得请求参数值以后,一般需要做 合法性验证,比如判断获取的值是否为 null或者 ""。
2)String[]
request.getParameterValues(String paraName);
http://ip:port/web01/hello?name=jetty&age=22&interest=snooke&interest=cooking
a, 当有多个参数名相同时,用该方法。
8、http协议(了解)
(1)什么是 http协议(超文本传输控制协议)?
是由w3c制订的一种 网络应用层协议,它制订了浏览器与web服务器之间如何通讯以及数据传递的格式。
(2)如何通讯的
step1, 浏览器建立与web服务器之间的连接
step2, 浏览器按照http协议的要求打包(打包之后的数据称之为请求数据包),然后送请求数据包给web服务器。
step3, web服务器处理请求之后,结果也需要打包(响应数据包),将响应数据包发送给浏览器。
step4, web服务器立即关闭连接。如果浏览器要再向web服务器发请求,需要重新建立一次新的连接。
特点:
一次请求,一次连接。好处是,web服务器可以利用有限的连接个数为尽可能多的客户端进行服务。
(3)数据格式
1) 请求数据包
a,请求行: 请求方式 请求资源路径 协议类型和版本
b,若干消息头:
所谓"消息头",就是一些由w3c定义的key,value对,浏览器与web服务器彼此可以相互的发送,表示一些特定的含义,比如,浏览器可以向web服务器发送一个"User-Agent"消息头,
告诉web服务器浏览器的类型和版本。消息头基本上由浏览器或者web服务器自动生成的,有些时候,需要开发人员通过编程的方式来额外生成一些消息头。
c,实体内容
只有当请求方式是post方式的时候,浏览器才会将请求参数放到这儿,如果请求方式是get方式,则请求参数会添加到请求资源路径的后面。
2) 响应数据包
a,状态行:协议的类型和版本 状态码 状态描述所谓状态码,就是一个由w3c定义的一个三位数字,表示web服务器处理请求的状态,
比如:
404: 表示web服务器依据请求资源路径,找不到对应的资源。
500: 系统错误。
200: 正常
b,若干消息头
web服务器也可以发送一些消息头给浏览器,比如,content-type,告诉浏览器,服务器返回的数据类型和编码格式。
c,实体内容
程序处理的结果。
9、get请求与post请求
(1)哪一些情况下,浏览器会使用get方式发请求
a, 直接在浏览器地址栏输入某个地址
b, 点击链接
c, 表单默认的提交方式
(2)哪一些情况下,浏览器会使用post方式发请求
a, 设置了表单的method="post"
(3) get方式的特点
a,会将 请求参数添加到请求资源路径的后面,所以,能够提交的数据 大小有限制(只能提交少量的数据,因为请求行最多只能存放大约 4k左右的数据)。
b,会将 请求参数添加到浏览器地址栏,不安全(这些地址会被路由器记录)。
(4) post方式的特点
a,会将请求 参数添加到实体内容里面,提交的 数据大小可以很大。
b,不会将请求参数显示在浏览器地址栏,所以, 相对安全。
不管是get还post方式,都不会对 请求参数进行加密,
所以,如果是敏感数据,一般都需要加密处理(https)。
10、编码解码知识
1)基础知识
(1) java语言在内存当中,保存的所有的字符都是使用 unicode编码格式来保存的。
(2)所谓“ 编码",就是 将unicode这种编码格式对应的字节数组转换成某种本地编码格式(比如gbk) 对应的字节数组。
(3)所谓“ 解码”,就是 将某种本地编码格式(比如gbk)对应的字节数组转换成unicode这种编码格式对应的 字节数组。
2)如果servlet要输出中文,要怎么处理?
需要调用 response.setContentType("text/html;charset=utf-8");
注意:
a,编码格式可以是"utf-8","gbk"(支持中文的就可以)。
b,这句话的作用有两个:
作用1:生成一个content-type消息头,告诉浏览器,服务器返回的数据类型和编码格式。
作用2: out在输出时,会使用指定的编码格式进行编码。
3)如果要编写一个 html文件,里面包含了中文,则需要添加
<meta http-equiv="content-type" content="text/html;charset=utf-8">
作用是模拟一个content-type消息头,告诉浏览器,返回的数据类型和编码格式。
4) 如果表单当中,有 中文参数值,需要进行如下的处理:
(1)如果不处理的话,有可能会产生乱码因为,所有浏览器,会对表单中的数据进行编码(会使用打开表单所在的页面时的编码格式进行编码),
而服务器在默认情况下,一般使用iso-8859-1去解码,这样,编码和解码所使用的编码格式不一致,所以,会产生乱码。
(2)解决方式
1)方式一:
step1, 要保证页面按照指定的编码格式打开。
比如,对于静态页面(html),要使用 <meta http-equiv="content-type" content="text/html;charset=utf-8">
step2, 使用 request.setCharacterEncoding("utf-8");该方法会指定容器按照指定的编码格式去解码。需要注意,该方法 只对post请求有效。
2)方式二:
step1,同上。
step2,
new String(name.getBytes("iso-8859-1"), "utf-8");
11、重定向
(1)什么是重定向?
服务器向浏览器发送一个 状态码302及一个消息头 Location( 里面包含了一个地址,称之为重定向地址),
浏览器收到之后,会立即向重定向地址发请求。
也可以简单地理解为:服务器通知浏览器向一个新地址发请求。
(2)如何重定向?
response.sendRedirect(String url);
url:就是重定向地址,也就是说,让浏览器马上访问的地址,该地址是任意的。
(3)编程需要注意的两个问题
1)重定向之前, 不能够调用out.close方法。
2)重定向之前,servlet容器会将 response对象上缓存的数据清空。
(4)重定向的特点
1)重定向之后, 浏览器地址栏的地址会变成重定向地址。
2)重定向的地址是任意的。
2、将中文添加到数据库
step1, 应用程序能够正确处理编码问题。
a, 静态页面(html)
<meta http-equiv="content-type" content="text/html;charset=utf-8">
b, servlet要添加
request.setCharacterEncoding("utf-8"); 要保证表单是post方式来提交。
step2,数据库要支持中文
create database jd1305db default character set utf8;
step3, 要保证jdbc驱动程序能够支持中文
jdbc:mysql://localhost:3306/jd1305db?useUnicode=true&characterEncoding=utf8
告诉jdbc驱动,使用utf8这种编码格式进行编码。如果不这样设置,某些mysql的驱动默认情况下,会使用 iso-8859-1进行编码。