day04
01-web开发入门
WEB开发的相关知识
WEB服务器
学习web开发,需要先安装一台web服务器,然后再在web服务器中开发相应的web资源,供用户使用浏览器访问
这里要求写一个web服务器
常见WEB服务器



Tomcat服务器

02-tomcat常见启动故障
Tomcat常见启动问题






03-虚拟目录的映射和web应用组织结构
Tomcat目录结构

bin中存入的是tomcat的启动和关闭文件
conf中存放的是配置文件,其中最重要的文件就是server.xml
lib中存放的是服务器支持的jar包
logs中存放的是日志文件,我们可以通过日志文件查看服务器的运行情况
temp这个目录存放的是临时文件,这个用的不多
webapps这个包存放的是web应用资源,这个文件我们用的最多
work这个是tomcat的工作目录
其它的文件就是一些许可,授权,注意事项什么的
WEB应用程序

虚似目录的映射方式
第一种、在server.xml文件的host元素中配置,例如:

Context英文中的意思是上下文,这里就翻译成web应用,docBase就是指定你web应用所在目录,path就是指定对外访问的虚拟路径
这里我们给出Contexte元素常用属性


第二种、在Tomcat6中,不再建议在server.xml文件中配置context元素,细节查看tomcat服务器关于context元素的说明。
在Tomcat的帮助文档中就说明了这样的话,在这个地方中,而且给出了五种建议,最后一种就是我们上面用的那种在Host中配置
Tomcat Documentation——>Configuration——>Context——>Defining a context

第1个建议是说我们可以在conf文件中的context.xml中配置一个Context,这个Context的信息可以被所有的web应用加载,这个方式说明Context不仅仅代表一个web应用,也代表一些资源,这些资源一点被配置在context.xml中就会被web应用加载

这点我们也可以从context.xml中的配置也可以看出来,只要服务器一启动,所有的web应用都会去检测WEB-INF/web.xml文件的变化

这个建议并不是说的教我们如何配置一个web应用,只是告诉我们在context.xml中配置的文件将会被所有的web资源加载
比如这里的<WatchedResource>WEB-INF/web.xml</WatchedResource>中的web.xml在web应用启动的时候就会去
加载它
第2个建议也不是在教我们如何配置一个web应用

第3个建议就是在教我们如何有效的配置一个web应用的虚拟目录

它这句话中说的是在tomcat文件中的conf/Catalina(也就是它说的enginename目录)/localhost(也就是它说的hostname)文件中配置一个xml文件
这个文件的名字将会被用作虚拟目录路径,多级虚拟目录必须用#隔开,例如:foo#bar.xml就代表/foo/bar这个虚拟目录。如果xml文件的名称设置成
ROOT.xml则主机名就是默认的虚拟目录,这个配置可以在不用重启服务器就有效


不同重启服务器我们就可以在浏览器中输入http://localhost:8080/ysfox/dir/index.html访问d:\myweb中的web资源了
如果这里我们将xml的名字改为ROOT.xml则只输入http://localhost:8080/index.html就可以访问d:\myweb中的web资源了
另外这里还说了一种建议

这个建议将在稍后讲解,这个建议里面说到在MATE-INF中配置一个context.xml文件,我们可以在这个xml文件中配置
当然最后一种建议就是我们开始使用的那种在在server.xml中配置一个Context,这种是不建议使用的,因为要重启服务器

第三种、让tomcat自动映射: tomcat服务器会自动管理webapps目录下的所有web应用,并把它映射成虚似目录。换句话说,tomcat服务器webapps目录中的web应用,外界可以直接访问。
WEB应用的组成结构

web.xml文件
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <welcome-file-list> <welcome-file>ysfox.html</welcome-file> <!--这里是欢迎列表-> </welcome-file-list> </web-app>
当我们重启服务器之后,在浏览器中输入http://localhost:8080/myweb,然后直接回车就可以访问ysfox.html
04-回顾
分清几个概念:web应用所在目录,web应用,虚拟目录映射三种方式,缺省的web应用
如果我要某个网站设置成缺省的web应用,则必须在conf\Catalina\localhost目录下创建ROOT.xml指向这个web应用的目录
并且还要在web应用的WEB-INF中的web.xml中配置默认的首页
05-配置虚拟主机
<Host name=”site1” appBase=”c:\app”></Host>
现在我们有一个网站ysfox,对外提供新闻服务,也可以对外提供写blog服务 ,那么我这个网站就有两个web应用
这里的ysfox就是网站跟目录,里面的blog和news叫做web应用所在目录,这里的ysfox就对应我的网站,我希望
别人输入www.ysfox.com就可以访问我这两个网站


这里我们就必须到C:\Tomcat 6.0\conf下的server.xml去配置一个Host
我们可以从这个文件中看见默认的配置就是localhost

现在我们要在后面添加一个Host,然后在Host中添加Context(也就是对应web应用的虚拟映射)

配置好之后我们要重启服务器,还是不能访问,理由是电脑在网络上找不到名为www.ysfox.com这样一台主机
这里要注意,当服务器启动的时候,其实启动了两个网站,一个是localhost,一个是我们配置的ysfox
当我们在浏览器中输入http://www.ysfox.com的时候,其实就是访问www.ysfox.com这个主机,而这个主机在实际上没有,所以这里叫做配置虚拟主机
当我们在浏览器中输入http://www.ysfox.com的时候,浏览器会将www.ysfox.com解析成对应的ip,然后根据ip去找这个主机。这里浏览器会通过去找
DNS(域名解析器)去查找对应的域名的ip,不过在这之前它会先去本地的hosts文件中去查找一些有是否域名对应的ip

这里我们既然没有在在DNS中注册www.ysfox.com这个域名,我们只有在hosts文件中去写一个
在hosts文件张我们可以注册多台主机,我们在这里注册一台www.ysfox.com的主机

这个时候我们就可以在浏览器中访问http://www.ysfox.com:8080这个网站下的web应用news下的1.html
问题:如果将来我们要在网络上配置一个网站,用户只需输入www.ysfox.com就可以访问我这个网站,那么我部署这个网站需要那些步骤
1.首先我们先将这个www.ysfox.com这个域名买下来
2.在我们的服务器上配置一台www.ysfox.com这样一台主机(也就是在conf下的server.xml中配置一个Host),并且指定web应用

3.登陆DNS管理页面设置域名(也就是所以的将域名和ip绑定,将你存放网站的固定ip和这个域名绑定)
以上就是教大家如何去部署一个网站
我们再来配置一个google的网站

这里Context中的path什么都没有写,表示将mail设置为缺省的web应用
然后我们将端口改为80端口

然后我们在hosts中配置一个ip和域名

然后我们重启服务器
这个时候我们就可以直接访问http://www.google.com/1.html了,这里我们不需要指定端口和web应用
如果我们这里想直接访问http://www.google.com就可以直接访问mail中的1.html,则我们可以在mail这个web
应用中建立一个WEB-INF,然后在WEB-INF这个文件中建立一个web.xml,然后在这个web.xml文件中抄一个Tomcat
的头和尾,然后在添加一个欢迎首页
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <welcome-file-list> <welcome-file>1.html</welcome-file> </welcome-file-list> </web-app>
配置缺省的虚拟主机
在server.xml中Host标签是配置一太主机的,我们知道可以配置多个虚拟主机(也就是多个Host),而Host又是Engine的子标签,在Engine这个标签中
就可以指定缺省的虚拟主机,如图,下面这段xml代码表示当tomcat服务器启动的时候会去启动一个名称为Catalina的引擎,这个引擎会处理客户端的请求,
当用户没有指定访问那台主机,引擎就会默认访问localhost这个台主机,所以我们要配置一个缺省的虚拟主机,就可以给defaultHost配置一个主机名就可以了

这里我们要明白,当我们在浏览器中输入www.sina.com的时候其实这个www.sina.com起了两个作用,
1.浏览器拿到这个域名之后回去查找DNS中的对应的ip
2.在通过ip访问服务器的时候会将这个域名拿给服务器,表示我要访问服务器中的这台主机
如果我们在浏览器中没有输入域名而是直接输入ip地址,则浏览器就会跳过DNS直接去访问服务器中缺省的虚拟主机
当服务器中有多个网站,其它非虚拟主机的网站则访问不了了,所以一般在服务器中只配置一个网站
到这里我们就必须搞清楚几个概念
什么是web应用所在目录:web应用所在目录就是装web的各种应用的目录,比如一个网站中有多个web应用,有news,mail,blog等web应用
什么是网站跟目录:所谓网站跟目录就是装web的各种应用的目录
什么是虚拟目录的映射:所谓虚拟主机的映射就是在server.xml中配置的Context,这个Context中配置path是指向web应用的目录(也就是配置的虚拟目录映射到web应用)
什么是虚拟主机:所谓虚拟主机就是在server.xml中配置的Host,这个Host配置的虚拟目录name指向的是网站的根目录
什么是缺省虚拟主机:所谓缺省虚拟主机就是在server.xml中Engine标签中deautHost指定的默认主机
画图演示web资源的访问过程
下面我们通过Rose来画一个web资源访问的过程

总结:这节课主要讲解虚拟主机的配置,缺省虚拟主机的配置,web访问的过程图
___________________________________________________________________________________________________________
06-web服务器的一些小细节
其它问题



然后我们将这个war包直接扔到tomcat服务器中的webapps文件下,当服务器一启动就可以直接将这个
war包解压
我们已经知道在server.xml中配置的Context代表web应用

当我们在Context中加上reloadable="true"则表示当我们修改web应用后可以自动加载classes中跟新的内容





















07-作业
08-http协议简介和请求行

1.什么是HTTP协议



2.HTTP协议简介
3.HTTP1.0和HTTP1.1的区别
这里我们就来做个实验,验证http1.0和http1.1的区别
首先我们在记事本中写好请求消息

然后链接localhost主机

我们回车之后发现telnet默认是不能回显的,这是为了安全问题,如果想回显,我们可以按快捷键Ctrl+],然后再回车就可以回显示了

之后我们粘贴请求消息就可以看见请求的数据了,这里要注意请求消息头后面要有两个回车

这里我们用的是http1.1,http1.1的特点是拿到web资源的之后不会断开与web资源的链接
我们可以在上一次链接的基础上继续下一个web资源的链接

然后我们退出与服务器的链接,也就是输入一个quit

退出之后我们来测试http1.0

首先链接主机

回车之后按Ctrl+],在回车,回显

然后我们粘贴http1.0的请求协议,这里要搞快点,否则就会与服务器断开连接

输入了请求协议,两次回车之后,得到服务器的响应以后,我们返现与服务器之间的链接断开了
然后第二个问题,在一个web资源中,一个img标签就是一个资源,当浏览器访问这个img时就是一个请求
所以如下图的一个web应用就有3个img标签

那么在访问这个资源的时候就会有4个请求,第一个请求是访问这个1.html这个资源,其它三个是访问img的,所以有四个

所以在开发页面的时候一点要减少页面的请求数量
比如这里的页面资源,有三个图片我们就应该将其合成一个图片

在比如,页面中的css和javascript尽量将多个css和javascirpt合并到一个css和javascript中减少请求数
这些都是网站访问性能的细节
4.HTTP请求
一个请求行、若干消息头、以及实体内容,如下所示 :

5.HTTP请求的细节——请求行


6.HTTP请求的细节——消息头
以上是HTTP协议里面常用的请求头

这个里面的UA-CPU: x86表示当前系统的环境为
7.HTTP响应

8.HTTP响应的细节——状态行
格式: HTTP版本号 状态码 原因叙述<CRLF>
举例:HTTP/1.1 200 OK

300~399表示当客户端请求服务器某个资源时,服务器要求客户端去请求其它资源,这个好像别人找我借钱,我没有,我叫他向其它人借
这个就是302状态码的含义,这个302状态码在网站上用的特别多,比如登陆,当我在登陆页面提交数据的时候服务器就会转到其它首页上面去
这里的304和307是相同的含义,表示当客户端访问服务器,服务器却说我这个数据没有更新,叫客户机去自己的缓存中找资源
404表示客户端找的资源不存在
500表示服务器端出现错误
9.HTTP响应细节——常用响应头
以上就是常用的http响应头
下面我们写一个servlet来演示HTTP响应头
Location这个消息头通常和302状态码一起使用,当客户端访问服务器时,服务器会给客户端浏览器响应这个消息头,叫客户端浏览器访问其它资源
/day04/src/cn/itcast/servlet/ServletDemo1.java
package cn.itcast.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo1 extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置状态码为302,表示通知浏览器访问其它资源 resp.setStatus(302); //这里通知浏览器访问day04下的1.jsp这个资源 resp.setHeader("Location", "/day04/1.jsp"); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
/day04/WebRoot/1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP '1.jsp' starting page</title> </head> <body> This is my JSP page </body> </html>
Content-Ecoding和Content-length经常一起使用用来压缩数据,然后再将压缩后的数据回送给服务器
/day04/src/cn/itcast/servlet/ServletDemo2.java
package cn.itcast.servlet; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo2 extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //这里有一段数据 String data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //比较一下压缩前后数据的大小 System.out.println("压缩前数据的大小:"+data.getBytes().length); //我们现在需要将这段数据压缩后回送给浏览器 //既然要压缩我们就得找压缩的工具,在java中提供了一个压缩流GZIPOutputStream //我们可以将这段数据压缩之后写入到底层流中,这里的底层流其实就是一个字节数组流 //byteArrayOutputStream ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(out); //将数据写入到底层数组流中 gzip.write(data.getBytes()); //这里一定要注意关闭流,这样才能将数据刷新到底层流中,因为这个压缩流是一个包换流 //包装流都是缓冲的,如果数据没有写满缓存是不会自动刷新的,所以这里必须关闭,这样 //才能将数据写入到底层流中 gzip.close(); //获取到底层流中压缩的数据 byte[] b = out.toByteArray(); //比较一下压缩前后数据的大小 System.out.println("压缩后数据的大小:"+b.length); //再将数据写给浏览器之前需要通知浏览器我采用的是什么方式的压缩格式以及压缩数据的长度 resp.setHeader("Content-Encoding", "gzip"); resp.setHeader("Content-length", b.length+""); //将底层流中的数据回显给浏览器 resp.getOutputStream().write(b); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
在浏览器中我们访问ServletDemo2
http://localhost:8080/day04/servlet/ServletDemo2
然后在MyEclipse中就看见数据压缩前后的压缩大小

但是这个要注意,这个必须要求压缩的字符串数据,这个数据要求要大一些,才能更好的压缩,不然数据小了压缩则反而更大
然后我们来测试一下Content-Type,这个响应头表示服务器告诉浏览器我这回送的数据是什么类型,在写Content-Type(大小无所谓),我们可以在Tomcat中的web.xml中查看各种类型的具体值
由于这里的类型实在很多,我们这里只列举小部分

/day04/src/cn/itcast/servlet/ServletDemo3.java
package cn.itcast.servlet; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo3 extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //首先设置响应消息头,这里响应头可以在web.xml中查找 //这里是jpg图片的格式就就是image/jpeg,如果此处我们将类型改成text/plain,则浏览器会以文本来打开数据,但是大部分的浏览器比较智能可以识别 resp.setHeader("Content-Type", "image/jpeg"); //通过servletContext将图片读取到流中,注意此处图片的位置 InputStream in = this.getServletContext().getResourceAsStream("/1.jpg"); //将流中的数据写入到response输入流中,这样就将数据回送给客户端 OutputStream out = resp.getOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len=in.read(buffer))>0){ out.write(buffer, 0, len); } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
接下来我们测试refresh这个响应头,这个响应头表示服务器告诉浏览器多少时间刷新一次,这个响应主要用于聊天室或者股票
/day04/src/cn/itcast/servlet/ServletDemo4.java
package cn.itcast.servlet; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo4 extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //这个响应表示服务器告诉浏览器,每隔3秒就访问这个servelet一次 //resp.setHeader("Refresh", "3"); //我们也可以在时间后面添加一个url表示每隔多少时间访问一次指定的网站 resp.setHeader("Refresh", "3;'http://www.baidu.com'"); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
然后我们来演示Content-Disposition这个消息头,这个消息头表示服务器告诉浏览器用下载的方式打开回送的数据
/day04/src/cn/itcast/servlet/ServletDemo5.java
package cn.itcast.servlet; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo5 extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //这里设置的头表示服务器告诉浏览器用下载的方式处理回送数据,并且给出了下载书记的名称 resp.setHeader("Content-Disposition", "attachment;filename=a.jpg"); //将图片读取到流中 InputStream in = this.getServletContext().getResourceAsStream("/1.jpg"); //将流中的数据回送给浏览器 OutputStream out = resp.getOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len=in.read(buffer))!=-1){ out.write(buffer,0,len); } //记得要关闭流 in.close(); out.close(); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
以上演示了常用的响应头
——————————————————————————————————————————————————————————————————————
10-http响应与断定续传
9.HTTP实用头字段
传输范围从1000到2000字节。
传输Web资源中第1000个字节以后的所有内容。
传输最后1000个字节。
package cn.itcast.servlet; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; //我们这里要模拟浏览器向服务器发送http请求,实现断点续传,我们这里就需要用到URLConnection这个类 //这个类就代表浏览器,其实这里的断点续传相当于下载,当断网时只下载一部分内容,当联网时又可以继续下载 public class Demo1 { public static void main(String[] args) throws IOException { //表示浏览器要访问这个资源 URL url = new URL("http://localhost:8080/day04/1.txt"); //得到一个URLConnection,这里就相当于连接上了web服务器 //URLConnection conn = url.openConnection(); //由于这里访问的资源是http开头的,所以我们这里获取的连接是一个HttpURLConnecion HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //然后我们向服务器发送断点续传的请求头,这里表示传送10个字节以后的所有内容 conn.addRequestProperty("Range", "bytes=10-"); //通过HttpURLConnextion将资源读取到流中 InputStream in = conn.getInputStream(); int len = 0; byte[] buffer = new byte[1024]; //这里是以追加的方式写入到1.txt中 FileOutputStream out = new FileOutputStream("c:\\1.txt",true); while((len=in.read(buffer))>0){ out.write(buffer,0,len); } //记得关流 in.close(); out.close(); } }

浙公网安备 33010602011771号