============day01============================ 1、什么是servlet?
sun(oracle)公司制订的一种用来扩展
web服务器功能的组件规范。
(1)扩展web服务器功能
大多数的web服务器(apache
http server, iis等)只能够处理静态
资源的请求(即需要事先将html文件写
好),不能够处理动态资源的请求(即需要
依据请求参数进行计算,然后生成相应
的页面)。
早期,使用cgi程序来扩展web
服务器功能。
cgi(common gateway interface
通用网关接口),可以使用c,perl等语言
来开发符合cgi规范的程序。
因为cgi程序开发比较复杂,可移值
性不好,性能不好,所以,现在用得不多了。
可以使用servlet来扩展web服务器功能。
(2)组件规范
a,组件是什么?
符合一定规范,并且实现部分功能的软件模块。
b,容器是什么?
符合一定规范,提供组件运行环境的程序。
2、如何开发一个servlet?
step1,写一个java类,实现Servlet
接口或者继承HttpServlet抽象类。
step2,编译。
step3,打包。
建立一个具有如下结构的文件夹。
appname
WEB-INF
classes(放.class文件)
lib(放.jar文件,可选)
web.xml(描述文件)
step4,部署
将step3创建的文件夹拷贝到servlet 容器特定的文件夹下面。
注意:也可以将step3创建的文件夹使用jar命令进行压缩(压缩文件必须以
.war为后缀)。
step5,访问servlet
启动servlet容器,在浏览器地址栏
输入:
http:// ip:port/appname/servlet-url
http://localhost:8088/firstweb/sayHello
3、tomcat的安装与简单使用
tomcat是一个servlet容器,同时,也
是一个简单的web服务器。
(1)安装
step1,解压
/opt/apache-tomcat5.5.23.tar.gz
/home/soft01
step2,配置环境变量
JAVA_HOME:jdk安装的路径
step3,启动tomcat
cd /home/soft01/apache5.5/bin
sh startup.sh (sh catalina.sh run)
step4,打开浏览器,输入
http://localhost:8080
step5,关闭tomcat
sh shutdown.sh
4、使用myeclipse开发一个简单的servlet
step1,配置myeclipse,让myclipse可以
管理tomcat。
step2,创建一个web工程。
5 servlet的运行
1)浏览器依据ip,port建立与servlet容器之间的连接
2)浏览器将请求数据打包(生成请求数据包)并发送给容器
3)容器拆包(解析请求数据包),将解析的结果封装到request对象上,同时,容器还会创建一个responsr对象。
4)容器依据请求资源路径找到servlet的配置信息,然后创建该servlet对象。
5)容器调用servlet的service方法(会将事先创建好的request,response作为参数传递进来)。
6)servlet方法里进行业务逻辑的处理,可以调用resvlet会得请求参数,也可以将出路结果写到response。
7)容器从response对象昂上获取处理结果,然后打包(相应数据包)发送给浏览器
8)浏览器解析相应生成相应的界面
练习:
写一个servlet,输出当前的系统日期。
http://ip:port/web01lab/date
会输出2014-02-11
==============dayo2==========================
1,常见错误及解决方式
(1)404
1)含义:服务器依据请求资源路径,找不到对应的
资源。
2)错误原因:
a,请求资源路径写错。
b,servlet-name写错。
c,忘记部署。
3)解决方式:
a,按照http://ip:port/appname/servlet-url
来检查请求资源路径。
b,检查web.xml配置文件,注意servlet-name的配置。
注:
404是一个状态码(是一个三位数字,由w3c定义,表示服务器处理请求的一种状态)。
(2)405
1)含义: 找不到处理方法。
2)错误原因:
service方法没有按照标准的格式来写。
3)解决方式:
仔细检查service方法的签名。
(3)500
1)含义: 系统错误
2)错误原因:
a,
b,程序运行出错。
3)解决方式:
a,检查web.xml配置文件,检查
b,检查程序源代码:
比如检查程序有没有对用户输入的参数进行合法性检查,程序运行过程当中,依赖的一些资源
(数据库等)有没有发生异常。
2,http协议(了解)
(1)什么是http协议?
由w3c制订一种网络应用层协议,制订了浏览器和web服务器之间如何通信以及通信过程当中所使用
的数据格式。
1)如何通信
step1,建立连接
step2,浏览器打包请求数据并发送
step3,服务器打包响应数据并发送
step4,服务器立即关闭连接
如果浏览器要再次发送请求,必须重新建立一个新的连接。即“一次请求,一次连接”。
优点:服务器可以利用有限的连接为尽可能多的
客户端(浏览器)服务。
缺点:状态无法管理(后面会讲)。
2)数据格式
a,请求数据包
请求行: 请求方式请求资源路径协议类型和版本
消息头:是一些键值对,由w3c定义,表示一些
特定的含义,比如浏览器可以发送"User-Agent"
消息头告诉web服务器,浏览器的类型和版本。
实体内容:如果发送的是get请求,实体内容没有
任何数据。只有发送post请求,才会有数据(
请求参数)。
b,响应数据包
状态行:协议类型的版本状态码状态描述
常见的状态码:
200: 正常
404:
500:
消息头:服务器也可以发送一些消息头给浏览器,
比如"content-type",告诉浏览器服务器返
回的数据类型。
实体内容:程序处理的结果。
(2)两种请求方式(get/post)
1)哪一些情况下,浏览器发送get请求?
a,直接输入访问地址
b,点击链接
c,表单默认的提交方式
2)get请求的特点
a,将请求参数添加到请求行,只能提交少量的
数据(因为请求行只能存放大约2k左右的数据)。
b,会将请求参数显示在浏览器地址栏,很不安全
(比如,路由器就会记录请求地址)
3)哪一些情况下,浏览器发送post请求?
a,设置表单的method属性值为"post"。
4)post请求的特点
a,将请求参数添加到实体内容里面,可以提交
大量的数据。
b,不会将请求参数显示在浏览器地址栏,相对
安全(不会加密)。
3、servlet输出中文要注意什么问题?
(1)编码知识:
a,java语言在内存当中,使用unicode字符集来保存字符。
b,编码: 将unicode字符集对应的字节数组转换成某种本地字符集(gbk,utf-8等)对应的字节数组。
c,解码:将某种本地字符集(gbk,utf-8等)对应的字节数组转换成unicode字符集对应的字节数组。
(2)产生乱码问题的原因?
out在输出时,默认会使用"iso-8859-1"来进行编码。
(3) 解决方式
response.setContentType("text/html;charset=utf-8");
4、表单的使用
(1)如何获得请求参数值?
1)String request.getParameter(String paramName);
注意:
a,参数名(paramName)不能写错,否则会返回null。
b,注意检查参数值是否为""。
2)String[] request.getParameterValues(
String paramName);
a,当有多个参数名相同,使用该方法。
(2)中文参数值如何读取?
1)乱码产生的原因
当提交表单时,浏览器会对表单中的中文参数进行编码(会使用打开表单所在的页面的字符集,
比如"utf-8")。
服务器端默认情况下,会使用"iso-8859-1"去解码。
2)解决方式
a,方式一
step1,保证表单所在的页面按照指定的字符
集打开。
比如,对于html文件,应该要添加上
content="text/html;charset=utf-8">
step2,服务器端按照指定的字符集解码
request.setCharacterEncoding("utf-8");
注:该方法只针对post请求有效
b,方式二:
step1,同上。
step2, new String(
username.getBytes("iso-8859-1"), "utf-8");
5,mysql的简单使用
(1)登录mysql
//使用root用户来登录mysql
mysql -uroot;
(2)查看当前有哪些数据库
show databases;
(3)创建一个新的数据库
//创建一个数据库(jsd1312db)并且
//设置缺省的字符集是utf-8
create database jsd1312db default
character set utf8;
(4)使用某个数据库
use jsd1312db;
(5)查看当前数据库有哪些表
show tables;
(6)建表
create table t_emp(
id int primary key auto_increment,
name varchar(50),
salary double,
age int
)type=innodb;
auto_increment:自增长列,插入记录时,数据库
会自动为该列赋一个唯一的值(在该列原有值的
基础上加1)。
type=innodb: 让该表支持事务。
==============dayo3==========================
1、servlet使用jdbc访问数据库
step1,将jdbc驱动(.jar文件)拷贝到WEB-INF\lib下。
step2,在servlet类里面编写jdbc代码访问数据库,
需要注意异常的处理。
http://192.168.173.64:8080/web03/list
练习:
写一个ListEmpServlet,以表格的方式显示所有员工信息(id,name,salary,age)。
2、重定向
(1)什么是重定向?
服务器通知浏览器向一个新的地址发请求。
服务器一般是通过发送一个302状态码和一个Location 消息头(值是一个地址,称为重定向地址),浏览器
收到之后,会立即向重定向地址发请求。
(2)如何重定向?
response.sendRedirect(String url);
(3)需要注意的问题
a,重定向之前,容器会先清空response对象上
缓存的数据。
b,重定向之前,不能够调用out.close(),out.flush();
(4)特点
a,重定向的地址是任意的。
b,重定向之后,浏览器地址栏的地址会变。
练习:
完成删除某个指定员工的功能。
3、dao(data access object)
(1)dao是什么?
封装了数据访问逻辑的模块。
(2)如何写一个dao?
step1,实体类
step2,写一个java类,提供操作表的所有的方法。==============dayo4==========================
1、servlet容器如何处理请求资源路径?
比如,在浏览器地址栏输入
http://ip:port/appname/abc.html
step1,容器依据应用名("/appname")找到应用
所在的文件夹。
step2,容器会假设访问的是一个servlet,然后
比较
1)精确匹配
要求
2)通符配匹配
使用"*"来匹配任意的0个或者多个字符。
比如:
3)后缀匹配
使用"*."开头,后接任意的1个或者多个字符。
比如:
匹配所有以".do"结尾的请求。
step3,如果以上均不匹配,容器会认为访问的是一
个文件,然后查找该文件。找到了就返回,找不到
返回404。
2、让一个servlet处理多种请求。
step1, 使用后缀匹配。
step2,分析请求资源路径,然后进行不同的处理。
3、将中文保存到数据库需要注意的问题
(1)数据库要设置好支持中文的字符集。
比如
create database jsd1302db
default character set utf8;
(2)jdbc驱动要能够正确进行编码和解码。
某些jdbc驱动默认情况下,会按照"iso-8859-1"
进行编码和解码。对于mysql驱动程序,可以添加
两个参数
jdbc:mysql://localhost:3306/jsd1312db?
useUnicode=true&characterEncoding=utf8
以上两个参数的作用:告诉jdbc驱动如何编码
和解码。
4、servlet的生命周期
(1)什么是servlet的生命周期?
servlet容器如何创建servlet对象,如何
对创建好的servlet对象进行初始化操作,如何
调用servlet对象的方法处理请求以及销毁
servlet对象的整个过程。
(2)servlet的生命周期分成几个阶段?
1)实例化
a,什么是实例化?
容器调用servlet的构造器,创建一个servlet对象。
注:
容器在默认情况下,不管收到多少个请求,
只会创建一个servlet对象。
b,什么时候实例化?
情况1:收到请求之后,才进行实例化操作。
情况2: 容器在启动之后,事先创建好
servlet对象。需要配置:
值越小,优先级越高(优先级高的会先被
创建)。
2)初始化
a,什么是初始化
容器在创建好servlet对象之后,会立即调用
该对象的init方法。
b,如何实现自已的初始化处理逻辑
b1,GenericServlet已经提供了init方法的
实现(将容器传递进来的ServletConfig对象保存
下来了)。
b2,如果要实现自已的初始化处理逻辑,
只需要override init()方法。
c,init方法只会执行一次。
d,初始化参数的使用
step1,使用
比如:
step2,
String ServletConfig.getInitParameter(
"company");
3)就绪
a,什么是就绪
容器收到请求之后,会调用servlet对象的
service方法来处理请求。
b,如何实现自已的业务处理逻辑?
b1,HttpServlet已经实现了service方法。
b2,HttpServlet的service方法是这样实现的:
依据请求方式调用对应的doGet/doPost方法。
doGet/doPost需要开发人员去override。
b3,如何实现自已的业务处理逻辑?
方式一: override HttpServlet的doGet,
doPost方法。
方式二: override HttpServlet的service
方法。
4)销毁
a,什么是销毁?
容器在删除servlet对象之前,会调用该
对象的destroy方法。
b,destory方法只会执行一次。
c,destory方法一般用于释放资源。
(3)生命周期相关的几个类与接口。
1)Servlet接口
init(ServletConfig config)
service(ServletRequest req,ServletResponse res)
destroy()
2)GenericServlet抽象类
实现了Servlet接口中的部分方法
init
destroy
3) HttpServlet抽象类
继承了GenericServlet,实现了service方法
==============dayo5==========================
1、jsp(java server page)是什么?
sun公司制订的一种服务器端动态页面生成技术规范。
(1)因为直接使用servlet虽然也可以生成动态页面,
但是过于繁琐(需要使用out.println输出),并且不利于
维护(如果要修改页面,需要修改java代码),所以,
sun公司才制订了这样一种规范,可以非常方便地
生成动态页面。
(2)jsp其实是一个以".jsp"为后缀的文件,该文件的内容
主要是html和少量的java代码。容器会将jsp文件先
转换成一个对应的servlet然后执行。
2、如何写一个jsp文件?
step1,创建一个以".jsp"为后缀的文件。
step2,在该文件里面,可以添加如下的内容:
1)html(css,javascript):直接写。
2)java代码:
a, java代码片断
<% java代码; %>
b, jsp表达式
<%= java表达式%>
3)隐含对象
a,什么是隐含对象?
可以直接使用的对象,比如out,request,response
b,为什么可以直接使用这些隐含对象?
因为容器会自动添加获得这些对象的代码。
4)指令
a,什么是指令?
告诉容器,在将jsp文件转换成java类时做一些
额外的处理,比如导包。
b,指令的语法
<%@ 指令名称属性名称=属性值%>
c,page指令
import属性:导包。
比如<%@page import="java.util.*"%>
<%@page import="java.text.*,java.util.*"%>
contentType属性:设置response.setContentType
的内容。
比如
<%@page contentType="text/html;charset=utf-8"%> pageEncoding属性:告诉容器jsp文件的编码。
因为某些容器在读取jsp文件时,默认会按照
"iso-8859-1"去解码,所以,最好设置该属性,
这样,容器就会按照指定的字符集去解码了。
d,include指令
file属性:告诉容器,在将jsp文件转换成
servlet类的时候,在该指令所在的位置插入
file属性指定的文件的内容。
3、jsp是如何执行的?
step1,容器先将jsp文件转换成一个
java类(Servlet类)。
a, html(css,javascript) ----> 放到service
方法里,使用out.write输出。
b,<% %> ------> 放到service方法里,照搬。
c,<%= %> -----> 放到service方法里,使用
out.print输出。
step2,调用servlet(包括编译,然后实例化,初始化...)。
注意:
容器收到访问jsp的请求之后,先查看该jsp
对应的servlet实例是否存在,如果存在,就直接
调用该实例的方法。如果不存在,或者jsp文件的
内容发生了改变,则容器要将jsp重新转换成对应的
servlet类,然后实例化。
练习:
使用美工提供的静态页面完成员工列表。
4、转发
(1)什么是转发?
一个web组件(servlet/jsp)将未完成的处理交给
另外一个web组件继续做。
常见的场景:
一个servlet获得数据之后,转发给一个
jsp来展现数据。
(2)如何转发?
step1,绑订数据到request对象上。
request.setAttribute(String name,Object obj);
step2,获得转发器
RequestDispatcher rd =
request.getRequestDispatcher(String url);
step3,调用转发器的方法来转发
rd.forward(request,response);
//如果绑订值不存在,返回null。
Object request.getAttribute(String name);
==============dayo6==========================
1,比较转发与重定向
(1)转发是一次请求,重定向是两次请求。
转发所涉及的各个web组件可以共享request和
response对象,而重定向不行。
注:request对象和response对象的生存时间是
一次请求与响应期间。当响应发送完毕,容器会立即
销毁与之对应的request和response对象。
(2)转发之后,浏览器地址栏的地址不变,而重定向
会变。
(3)转发的目的地限定于同一个应用,而重定向没有
任何限制。
(4)转发是一件事情未完成,而重定向是一件事情已经
做完。
2、路径问题
(1)什么是路径问题?
在链接,表单提交,重定向以及转发的时候,如何填写相对路径与绝对路径。
(2)什么是相对路径?
不以"/"开头的路径,比如