程序的演变过程:
1.单机程序:txt文档,word文档,ppt文档
2.两层CS架构
客户端client: 设计用户界面和少量逻辑代码
服务端service: 数据库(大量逻辑代码)
优点:交互简单
缺点:业务逻辑使用数据库编程语言编写在程序移植方面非常差,需要重新编写业务逻辑代码
3.三层CS架构
c: client,用户界面设计和少量的业务逻辑
s: 应用服务器 ,大量的逻辑代码
db: 数据库 ,只进行数据的交互
优点:移植性好
缺点:开发客户端成本高,维护性差
4.BS架构
B: browser,浏览器
S:server ,应用服务器,所有业务逻辑代码
db:数据库 ,只进行数据的交互
优点:只遵循浏览器的HTTP通信协议即可,无客户端开发成本,所有逻辑代码都在服务端开发,移植性好
- Servlet
概念:是Sun公司制定的用于扩展web应用服务器的一个组件规范。
web--应用服务器功能:可以部署bs架构项目的服务器。最开始,web应用服务器只能进行一些静态资源的处理。无法满足需要经过计算得到的静态资源。之后出现了CGI,通用编程接口,来实现动态技术。但是CGI编程非常复杂不利于开发与维护,之后才出现看替代CGI的技术Servlet。
组件:
通过继承或实现某些类或接口,符合一定规范,可以完成部分功能,并且需要部署到容器里的组件。
容器:就是能实现组件功能的一个程序。
- Tomcat
- 是apache基金会的一个servlet容器。也相当于一个微型web应用服务器
(未来一周涉及到的web容器,servlet容器都是同一个东西)
2.安装:
解压,放于某一路径下
3.在conf文件夹下
server.xml里的<Connector port =”8080.....”>
修改成你想要的端口号:不修改的话可能会与Oracle的http协议相撞
- 启动服务器
Window:
startup.bat
linux:
start.sh
PS:启动后窗口不要关闭
异常:
闪退:没有配置JAVA_HOME环境变量
Address already in use:.......port 端口号被占用。
5、打开任意浏览器进行测试:
http://localhost:port
例子:
出现一只猫 即成功
- 手工编写一个web程序。
web程序的组织架构
(1)appName:
--WEB-INF
--classes
---xxx.class
---lib(可选)
---xxx.jar
---web.xml
--index.html(可选)
(2) 自定义一个源文件(如:HelloWorld)
0)先导包
1)继承HttpServlet
2)重写service方法
3)获取流对象,输出信息
(3) 编译源文件
javac -classpath servlet-api.jar的全路径 源文件.java
(4) 将class文件放入组织架构里的classes文件夹下
(5) 编写web.xml
1)、注册servlet组件
<servlet>
<!-- 组件昵称 -->
<servlet-name>firstweb</servlet-name>
<!-- 组件的类全名 -->
<servlet-class>HelloWorld</servlet-class>
</servlet>
2)、注册servlet组件的映射信息
<servlet-mapping>
<!-- 必须与组件昵称一致 -->
<servlet-name>firstweb</servlet-name>
<!-- url-pattern的值与浏览器地址栏上的值必须匹配 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
(6)部署项目到服务器中
将(1)的整个组织架构放入webapps中
(7)启动服务器
(8)使用浏览器访问服务器中的项目
http://ip:port/appName
访问的是项目的首页
http://ip:port/appName/url-pattern
web服务器,web容器,Servlet容器都是同一个东西
三、Servlet的组织结构
appName
WEB-INF
classes
xxx.class文件
lib(可选)
web.xml
index.html(可选)
四、tomcat服务器
1、安装(略)
2、检测环境变量:JAVA_HOME
3、启动程序
bin\startup.bat
4、关闭程序
bin\shutdown.bat
5、webapps:web项目部署的位置
五、手动开发一个web程序
(1)编写一个源文件:继承HttpServlet
重写service方法
(2)将源文件编译成字节码文件
javac -classpath servlet-api.jar的全路径 源文件.java
(3)编写web.xml
<servlet>
<servlet-name>随便起</servlet-name>
<servlet-class>comhyxy.web.java文件名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>随便起</servlet-name>
<url-pattern>/随便起</url-pattern>
</servlet-mapping>
定义的标识以login为例
在浏览器中输入的是http://localhost/8088/.项目名/定义的标识
http://localhost/8088/.项目名/login.html--->查看登录界面
http://localhost/8088/.项目名/login?username=xiaoming&password=123456&hobby=movie
查看你规定的用户名,密码,爱好等
(4)按照web程序组织结构进行存放
(5)启动tomcat服务器
(6)在浏览器上访问
http://ip:port/appName/url-pattern
新课
六、使用IDE(Integerated Drive Electronics)配置tomcat
1、配置tomcat
window-->preferences-->servers-->runtime environment-->tomcat-v7.0-->next
-->browser-->硬盘上的tomcat-->finish-->apply and close
2、显示tomcat
window-->show view-->servers-->点击连接-->选中tomcat-v7.0--finish
3、设置tomcat的参数信息
双击tomcat
配置server locations
选择 use tomcat installation
修改webapps
七、使用IDE开发web项目
1、new-->dynamic web project
2、起名后-->next-->next-->选择web.xml-->finish
3、定义Servlet组件,编写servlet规范的程序
4、配置web.xml
5、部署项目
右键点击(控制台的)servers里的tomcat-->add and remove-->添加要部署的项目-->finish
6、启动tomcat
7、使用浏览器访问
练习:开发第四个项目:fourweb
在浏览器上显示一组双色球
package com.hyxy.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class twoColorBalls extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
response.setCharacterEncoding("GB2312");
Set<String> set1 = new TreeSet<String>();
while(true){
int sui1 = (int) (Math.random() * 33) + 1;// 获取33以内的数字
set1.add(sui1<10?"0"+sui1:""+sui1);//将元素存入集合中
if (set1.size() == 6) {//存满六个红色球,则结束循环
break;
}
}
PrintWriter pw=response.getWriter();
Set<String> set2 = new TreeSet<String>();
int sui2 = (int) (Math.random() * 16) + 1;// 获取16以内的数字
set2.add(sui2<10?"0"+sui2:""+sui2);
pw.println("红球:" + set1 + " 蓝球:" + set2);
pw.close();
}
}
web.xml里面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>fourweb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>ball</servlet-name>
<servlet-class>com.hyxy.web.twoColorBalls</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ball</servlet-name>
<url-pattern>/color</url-pattern>
</servlet-mapping>
</web-app>
八、错误代码及其解决方法
服务器在处理完业务逻辑后,会响应浏览器,响应的内容包含了状态编码(数字类型)
200:表示成功处理业务。
404:服务器处理的路径存在问题,找不到相关请求资源
如:
(1)在地址栏上的路径有问题(大小写不对)
(2)<url-pattern>的值与地址栏路径不一致
(3)两个servlet-name不一致
(4)没有部署项目
(5)项目的组织结构有问题
405:容器找不到Servlet组件的service方法
(1)方法名写错
(2)方法的参数类型有问题
(3)方法的异常,返回值有问题
500:容器找不到Servlet组件
(1)没有继承HttpServlet或实现Servlet接口
(2)<servlet-class>写的有错
(3)service里的逻辑出现了问题
九、HTTP协议
1、概念
它是w3c(万维网联盟)定义的一种用于应用层的协议,即规定了浏览器与web服务器如何通信和通信的数据格式。
2、如何通信
(1)浏览器与服务器之间先建立连接
(2)浏览器将数据打包发送给服务器--->发送请求request
(3)服务器要将数据打包发送给浏览器-->发送响应response
(4)断开连接
一次连接后就断开一次:为使服务器端有限的连接数做到客户端的多次连接。
3、数据格式
请求数据包
请求行:请求方式 + 请求资源路径 + 协议版本
get +/firstweb/hello http/1.1
消息头:w3c组织定义的一些键值对,用来向服务器发送一些特定的数据。如浏览器的类型及其版本。
如:
User-agent: Edge/17.1736
Accept:text/html
.....
实体内容:请求方法为post请求时,实体内容才有数据。
响应数据包
状态栏:服务器端处理数据的结果。
格式: 协议版本+状态编码+状态描述信息
如: http/1.1 200 ok
消息头:服务器端要告诉浏览器的一些特定信息
Connect: keep-Alive
Date:.....
ContentType:text/html
实体内容:服务器端处理后的数据
十、Servlet如何处理HTTP协议
当浏览器向服务器端发送请求后,服务器端会维护两个对象用来封装和处理请求数据包的数据,及其响应数据。
分别是HttpServletRequest和HttpServletResponse对象
1、HttpServletRequest对象
封装和处理请求数据包的数据
提供了以下方法
String getParameter(String name)
String[] getParameterValues(String name)
String getHeader(String str)
Enumration<E> getHeaders();
RequestDispatcher getRequestDispatcher(String url)
.......
2、HttpServletResponse对象
封装和处理服务端要响应给浏览器的数据
提供了以下方法
void setContentType(String str)
void sendRedirect(String url)
.......
十一、Servlet的工作过程
1、Servlet的运行原理
(1)浏览器依据IP和PORT与服务器建立连接
(2)发送请求数据包到服务器
(3)服务器创建Servlet组件对象
(4)使用request处理请求数据包
(5)使用response封装响应数据
(6)服务器发送响应数据包
(7)浏览器进行解析,生成页面
2、Servlet处理参数值
处理1:1形式的参数与参数值
String getParameter(String name)
如果name不存在,返回null
处理1:M形式的参数与参数值
String[] getParameterValues(String name)
如果name不存在,返回null
3、请求方式
浏览器向服务器发送请求的种类有八种:
GET,POST,OPTIONS,HEAD,PUT,DELETE,TRACE,CONNECT
(1)常用的两种GET和POST
get:向特定资源发送请求(如返回登陆界面)
--在地址栏上直接写地址
--表单的默认提交方式
--点击链接
post:向指定资源提交数据(提交表单,上传文件)
--表单的method属性设置POST
(2)两者的区别
get:提交的数据会显示在地址栏上,数据量小,最多为4kb。不安全
post:提交的数据不会在地址栏上显示。因此我们可以提交大量的数据,相对安全
新课
三、Servlet处理中文参数值
中文会出现乱码,原因是编码与解码的字符集不一致造成
发送请求时:中文乱码解决方式
方式1: 服务端先编码再解码,适合 get/post
服务器端默认使用iso-8859-1解码
浏览器端常用的为utf-8进行编码
/*get请求下的中文参数处理
* 因为字符集不一致,造成了乱码情况,
* 服务端使用iso-8859-1
* 因此应该将字符串按照iso-8859-1再次编码字符数组,然后按照浏览器的字符集进行编码*/
address=new String(address.getBytes("iso-8859-1"),"utf-8");
city=new String(city.getBytes("iso-8859-1"),"utf-8");
gender=new String(gender.getBytes("iso-8859-1"),"utf-8");
System.out.println("address:"+address);
System.out.println("city:"+city);
System.out.println("gender:"+gender);
方式2:只适合post
request.setCharacterEncoding("utf-8")
request.setCharacterEncoding("utf-8");
位置:处理请求参数前
发送响应时:
response.setContentType("text/html;charset=utf-8")
/*响应浏览器时,处理浏览器中的中文乱码*/
/*设置消息头ContentType,响应对象,要按照指定字符集进行编码
* 浏览器查看此消息头时解析文本类型为tml,使用字符集也是utf-8*/
response.setContentType("text/html;charset=utf-8");
位置:写在获取流之前
一、重定向:
1.概念
服务器处理完业务逻辑后,向浏览器发送一个状态码302,同时发送一个消息头Location,此消息头的值是一个新地址。
当浏览器接收这些信息后,会立即向服务器发送该地址的请求
- 重定向的原理
3、如何重定向
response.sendRedirect(String url)
url:是重定向的新地址
4、重定向的特点
(1)地址栏的地址会发生改变
(2)重定向之前不能关闭流
(3)两次请求不共享request和response对象
二、Servlet如何处理请求资源路径
1、什么是请求资源路径
http://ip:port/appName/url-pattern
请求资源路径:appName/url-pattern
2、处理原理
浏览器依据ip和port确定服务器,之后依据appName确定应用程序所在的目录,servlet容器默认浏览器请求的是一个Servlet组件, 所以会校验web.xml里的url-pattern,进行匹配,执行相关的Servlet组件。
3、精确匹配
服务器在进行web.xml里的url-pattern的校验时,会严格匹配请求路径是否一致,如果匹配成功,就会执行相关资源
如: <url-pattern>/hello.html</url-pattern>严格匹配成功后,即使程序中有hello.html页面,也不会返回这个页面,而是执行相关Servlet。
4、通配符匹配
通配符:* ,配0个或多个字符,必须使用斜杠
如:<url-pattern>/*</url-pattern>
例如:
http://ip:port/appName/abc.html 匹配成功
http://ip:port/appName/service/add.html 匹配成功
http://ip:port/appName/listEmp 匹配成功
5、后缀匹配
在写web.xml里的url-pattern的值时,我们可以使用*.后缀的方式,后缀可以是1或多个字符组成的。
如:<url-pattern>*.action</url-pattern>
例如:
http://ip:port/appName/abc.html 匹配失败
http://ip:port/appName/emp/abc.action 匹配成功
http://ip:port/appName/listEmp.action 匹配成功
优先级: 精确匹配最高
假如:web.xml中有三个Servlet组件,其url-pattern如下
<url-pattern>/abc.do</url-pattern>
<url-pattern>/*</url-pattern>
<url-pattern>*.do</url-pattern
浏览器地址:http://ip:port/appName/abc.do
会执行精确匹配的Servlet组件
如果精确匹配,通配符匹配,后缀匹配都没有成功,容器会查找是否有此文件,如果有此文件,打包数据返回给浏览器。
如果没有,返回404.
6、Servlet组件的合并
一般情况下,Servlet组件充当的角色为控制角色,控制角色的作用是接收请求后进行分发到不同的资源里。因此一个Servlet就可以对请求资源路径进行分析,使用分支结构来处理不同的资源。
如何合并:
(1)采用后缀匹配进行修改web.xml
(2)获取请求资源路径进行分析,然后使用if分支进行处理
三、Servlet的生命周期
Servlet容器如何创建Servlet对象,如何初始化Servlet对象,如何调用其功能,及其Servlet对象的销毁。
生命周期分为四个阶段,分别为实例化,初始化,就绪,销毁。
阶段1:实例化
即容器调用构造器创建Servlet对象
时机1:容器收到请求后,创建Servlet对象
时机2:容器启动后,立即创建Servlet对象
web.xml中需要配置
<load-on-startup>1</load-on-startup>
阶段2:初始化
容器在创建Servlet对象后,会立即调用init方法进行对象的初始化。
一般情况下,我们不需要重写此方法,因为父类型GenericServlet里提供了init方法的实现逻辑。此方法保存了另外一个对象ServletConfig的引用
如果你想初始化一些自定义的属性,我们可以将初始化的值配置在web.xml里。
<init-param>
<param-name>company</param-name>
<param-value>华育兴业</param-value>
</init-param>
通过ServletConfig提供的
getInitParameter(String name)
来获取值
阶段3:就绪
初始化之后,容器调用Servlet对象的service方法进行资源分配。
阶段4:销毁
容器会根据自己的算法来进行Servlet对象的销毁,销毁前一定会调用destroy()方法。因此我们可以重写此方法来完成一些业务逻辑。
卸载程序时,一定会销毁Servlet对象
生命周期例题
package com.hyxy.web;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet{
private String company;
private String Manager;
public HelloServlet(){
System.out.println("----------创建HelloServlet对象-------------");
}
@Override
public void init() throws ServletException {
System.out.println("-----------初始化HelloServlet------------");
ServletConfig config=getServletConfig();//得到保存的对象
company=config.getInitParameter("company");
Manager=config.getInitParameter("Manager");
}
public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
System.out.println("--------处理业务逻辑------------");
System.out.println("company:"+company);
System.out.println("Manager:"+Manager);
}
@Override
public void destroy() {
System.out.println("程序卸载了");//卸载程序时一定会卸载Servlet对象--Servlet生命周期重点
super.destroy();
}
}