Java Web开发入门

Published: by Creative Commons Licence (Last updated: )

Web开发入门(Java Web)

gitbook版Thinking in Java (Java 编程思想)

进阶:
WEB请求处理一:浏览器请求发起处理
WEB请求处理二:Nginx请求反向代理
WEB请求处理三:Servlet容器请求处理
WEB请求处理四:Tomcat配置实践
WEB请求处理五:MVC框架请求处理
WEB请求处理六:浏览器HTTP协议漫谈

Tomcat服务器

Eclipse导入Tomcat源码 见Eclipse笔记

tomcat + jboss 整合即可构建完整支持J2EE的容器。

tomcat 支持全部JSP以及Servlet规范。

tomcat的配置见,《轻量级Java EE…》 tomcat是使用Java写成,需要java运行环境。

  • tomcat的自动部署web应用: 直接将一个Web应用复制到webapps下即可。
  • 利用控制台部署:(tomcat后台自动将文件夹复制到相关目录)
  • 利用配置文件

tomcat配置数据源的两种方式:

  • 全局数据源:
  • 局部数据源:修改自己的Web部署文件

都需要将JDBC驱动复制到tomcat的lib目录下。

一些基础知识:

http://www.sina.com/      表示url地址  
sina.com        是域名  
www.sina.com    是主机名  

tomcat服务器:Linux中的开启与关闭,可通过已经自定义的脚本tomcatStart和tomcatShut来控制。tomcat控制台用户与密码在tomcat的conf/tomcat-users.xml文件来配置。该密码非常重要,不要透露。
这里偷偷告诉你,用户和密码都是:manager

Web应用和虚拟目录的映射

  • Web应用程序:指提供浏览器访问的程序,通常也称为Web应用。
  • 一个Web应用由多个静态web资源和动态web资源组成,如:
    • HTML、CSS、js文件
    • jsp文件、java程序、支持jar包
    • 配置文件等
    • 组成web应用的这些文件通常我们会使用一个目录组织,这个目录称之为:web应用所在目录
  • Web应用开发好后,若想提供外界访问,需要把web应用所在目录交给web服务器管理,这个过程称之为虚拟目录的映射(需在配置文件中配置)。

下面是一个web应用:

news/        # web应用所在目录
  |
  ----- index.html
  ------ 2.html

更改tomcat的server.xml配置文件后需要重启tomcat服务器。

如何设置某个web应用为默认web应用(首页是属于某个web应用的)?见教程04课。

web应用的基本组成结构:

mail
 |
 |------ html、jsp、css、js等文件
 |
 |------ WEB-INF/
            |
            |--- classes/   (Java类)
            |
            |--- lib/      (jar包)
            |
            |---- web.xml   (web应用的配置文件)

配置虚拟主机:通过配置server.xml中配置 Host标签来配置主机地址和网站路径。

将web应用打包成一个war包: jar -cvf news.war news;服务器会自动解压该war包。

tomcat中的context就代表了一个web应用。配置context元素的reloadable元素,让tomcat自动加载更新后的web应用。

eclipse中的一个项目中会有一个WebContent

tomcat体系结构

enter image description here

Tomcat Server启动,再启动一个service,再启动多个连接器(不同连接器处理不同请求,比如需要使tomcat和apache集成就需要使用第三个连接器),连接器收到客户端时会启动引擎,引擎会寻找主机(多个网站),主机收到请求找web应用,再找web资源。【可以在server.xml中配置,直接看该文件也可进行理解】

理解:(此处的服务器应该是指安装了tomcat的那台主机)
http://www.sina.com:8080中的www.sina.com的作用,1.获得服务器的IP地址;2.在http请求头中告诉服务器(服务程序)我需要访问的主机是哪一台。

而如果直接使用http://192.168.1.1:8080时服务器(服务程序)不知道你需要访问我的哪一台主机,此时就会使用在配置文件中配置的默认主机(一般为localhost主机)

软件密码学基础和配置tomcat的https连接器

重新认识非对称加密:

公钥 CA 数字签名 私钥

数字证书(由CA为公钥生成的可性证书)也可自己生成证书。数字证书用于出示给用户,用户可以选择安装证书。

数据摘要(MD5算法得到数据摘要(指纹)) 使用私钥加密数据摘要 变成了数字签名

tomcat的体系结构和配置https连接器 公钥 私钥

# keytool是java自带的工具,用于生成数字证书,不受CA认证
keytool -genkey -alias tomcat -keyalg RSA
# -genkey指示产生密钥对, -alias指示别名  -keyalg加密算法
输入keystore密码:          #生成的数字证书保存于密钥库中,此密码用于加密密钥库。密钥库可以包含多个密钥,密码为第一次生成密钥库时输入的密码。
您的名字与姓氏是什么? # 必须输入
:             #输入你为那个网站生成的证书
下面出现的内容可以不填
...

密钥库文件 keystore默认位于home目录。

之后再tomcat中配置密钥库文件的路径和生成时使用的密码

然后可以使用https协议进行连接。

另可以参考《Tomcat与Java Web开发技术详解》第29章:在Tomcat中配置SSL

tomcat补充

tomcat补充来自于《Tomcat与Java Web开发技术详解》

Web服务器与Web应用是两个不同的软件系统,它们之间通过一个中介方制定的标准接口进行协作。Servlet就是其中最主要的接口。

  • Web服务器可以访问任意一个Web应用中实现Servlet接口的类
  • Web应用中用于被Web服务器动态调用的程序代码位于Servlet接口的实现类中

2017.02.15

Servlet规范把能够发布和运行JavaWeb应用的Web服务器称为Servlet容器

tomcat本身也是用Java写成的开源Servlet容器。

tomcat作为运行Servlet的容器,其基本功能是负责接收和解析来自客户的请求,同时把客户的请求传送给相应的Servlet,并把Servlet的响应结果返回给客户。

enter image description here
图:Servlet容器响应客户请求访问特定Servlet的时序图(重要

时序图中: 对象A到对象B的箭头,表示发送消息,因此也可理解为A调用B的方法。

每个Tomcat组件在server.xml文件中都对应一种配置元素。(具体情况见书)

Tomcat有三种启动方式

Tomcat的启动和关闭脚本都会执行同目录下的catalina.sh脚本;catalina.sh脚本允许输入命令行参数。比如start、run、debug、embedded、stop参数。

Servlet规范规定,JavaWeb应用必须采用固定的目录结构。

开发时可以自行添加一个src目录来存放所有Java源文件。到了Web应用的发布阶段,应该将src目录转移到其他地方。

在运行时,Servlet容器的类加载器先加载classes目录下的类,再加载lib目录下的jar文件中的类。因此如果两个目录下存在同名的类,classes目录下的类具有优先权。

另可参考《Tomcat与Java Web开发技术详解》第2篇:Tomcat配置及第三方实用软件的用法

  • Tomcat的控制平台和管理平台
  • 安全域
  • Tomcat与其他HTTP服务器集成
  • 在Tomcat中使用SSI
  • Tomcat阀
  • 在Tomcat中配置SSL
  • Velocity模板语言
  • 创建嵌入式Tomcat服务器

HTTP协议

通过telnet发生http请求,来获得服务器的http响应。并通过其测试http 1.0和http 1.1的区别。

对于请求下面的这样一个html页面,浏览器需要向服务器发送5次请求。第一次请求得到整个html页面,后面三次请求获得三个图片和一个js文件。

<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
<script src="1.js">

上面的页面设计的不好,请求多次会加大服务器的压力;优化方法…

IE 浏览器插件httpwatch

Chrome开发者工具的简单使用:
直接在Chrome浏览器中打开开发者工具,切换到"Network"选项卡,然后按F5刷新页面,在该选项卡中就会列出 此次刷新请求的具体资源的详细信息,并会统计进行了多少次请求(在Name栏的底部)。"Name"栏中列出了所有请求资源的名称,点击具体资源会出现几个标签页,点击"Headers"可查看其对应的请求头,点击"Preview"可预览资源…

http请求

请求行、请求头、空行、请求数据(如表单提交数据)

Post /hello.jsp HTTP/1.1
Accept: image/gif,image/jpeg, */*
Referer: http://localhost/login.html
...
Cache-Control: no-cache

username=Tom&password=1234&sublmit=submit   # Post方式的请求正文

用户如果没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输入地址访问,点击超链接等。 如果想使用post请求方式,方法是在表单form标签中指定使用post。

(可以这样理解吗? 首先在浏览器输入网址使用get请求一个页面包含表单的网页,然后我填写好表单后点击提交按钮,并且该表单的源代码中指定了使用post,那么就会使用post提交表单请求)

这样理解最好:
在浏览器中输入一个网址,回车后,此时浏览器向发送了一个Get请求(用于获取页面的源代码??),而浏览器为了加载页面中的脚本和图片等(解析源代码??)又会自行发起请求。比如打开一个Github上的仓库,共发起了100次请求。

发现老师讲的很好。有些东西如果自己摸索会话费很多时间,而且不一定能达到那种程度的理解。要自己快速的动手去实施…来提高速度。可能前提是自己对这方面已经有了些理解。 今天发现多与人交流是可以锻炼自己的思维的。

get 提交的数据有长度限制(数据在请求头的第一行)
post 无限制(在请求头空行下方)

如果要在用户点击超链接时提交数据给服务器,则可直接在超链接的地址后添加?usernaem=fan的这种get方式。

请求行: GET ...  
请求头:    

Accept: */*             -- 可接收的文件类型  
Referer: http://localhost:8080/myhome/index.html       -- 从哪个网址进入此页面;可用于设置防盗链  
User-Aget: ...                                          -- 客户机软件环境(比如系统,浏览器版本)  
Range: 头指示服务器只传输部分Web资源。这个头可以用来实现断点续传功能。  


Range:字段可以通过3种格式设置要传输的字节范围  
Range: bytes=1000-2000      #  
Range: bytes=1000-          #1000以后的所有内容  
Range: bytes=1000           #传输最后1000个字节  

get请求示例:

一般不包含请求正文,因为没有意义。见此处的讨论HTTP GET with request body

GET /hello.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

post请求示例:
包含请求正文

POST /cgi-bin/process.cgi HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

licenseID=string&content=string&/paramsXML=string

HTTP响应

HTTP /1.1 200 OK                        -- 状态行
Server: Microsoft-IIS/5.0               -- 多个响应头(服务器通过这些数据的描述信息,可以通知客户端如何处理它返回的数据)
Date: Thu, 13 Jul 2000 05:46:53 GMT     
Content-Type: text/html
Content-Length: 2291
Cache-control: private
                                    -- 一个空行
<HTML>                              -- 响应正文(实体内容)
<head>
    <title>helloapp</title>
</head>
<BODY>
....
</body>
</html>

状态行:

格式:HTTP版本号,状态码
状态码用于表示服务器对请求的处理结果,它是一个三位的十进制数。响应状态码分为5类:

状态码 含义
100~199 表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200~299 表示成功接收请求并已经完成整个处理过程,常用200
300~399 为完成请求,客户端需进一步细化请求。例如,请求的资源已经移动一个新地址,常用302(页面不位于此处,请访问别处,重定向),307和304(要求浏览器使用缓存)
400~499 客户端的请求有错误,常用404(无此资源) 403(无权限)
500~599 服务器端出现错误,常用500

响应头:

Location: 配合302状态码使用,用于告诉客户端去找谁(实现重定向,通过地址的改变判断是否进行了重定向)。  
Content-Encoding: 服务器通过这个头,指示数据的压缩格式  
Content-Length:   
Content-Type:  
Last-Modified: 当前资源的缓存时间。  
Refresh: 告诉浏览器隔多长时间刷新一次。(重要,聊天时获取最新数据,刷新实时图表)  
Content-Disposition: 告诉浏览器以下载方式打开数据  
Expires: 缓存的保存时间,-1和0表示不缓存。  
Cache-Control: no-cache     -- 控制浏览器不要缓存  
Pragma: no-cache        -- 控制浏览器不要缓存。  3个都设置缓存(适用不同浏览器)  

压缩数据:

  1. 提高浏览
  2. 节省费用;对于网络公司,SIP通过出口的流量向其收费。

压缩API:
GZIPOutputSeream流的Write(byte[] buf, int off,int len)方法将字节数组写入压缩输出流,只要将数据给它就可以进行自动压缩。
GZIPOutputSeream为包装流,包装流一般都有缓冲,在缓冲区没有满时是不会将数据写入底层流的,所以才会有下面的gout.close()语句,或使用gout.flush()进行刷新。

ByteArrayOutputStream bout = new ByteArrayOutputStream();

GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(data.getBytes());
gout.close();

byte gzip[] = bout.toByteArray();  //得到压缩后的数据
//通知浏览器返回数据采用压缩格式
response.setHeader("Content-Encoding","gzip");
response.setHeader("Content-Length",gzip.length+"");
response.getOutputStream().write(gzip);

刷新数据间隔:

    response.setHeader("refresh","3");//每隔3秒刷新一次
    response.setHeader("refresh","3;url='http://www.sina.com'"); //每隔3秒刷新到新浪网

缓存介绍:服务器针对Web中的每个资源都会根据其内容生成一个随机Tag,当客户端第二次访问服务器的同一资源时,会带上这之前获得的tag给服务器,服务器根据该tag来判断是让客户端使用缓存还是重新发送新数据给客户端。

其它缓存相关的头,只能做到秒一级的控制。当服务器端数据已经更新但第二次访问与前一次访问时间差小于1秒,如果没有设置ETag缓存头,则服务器会让浏览器使用缓存数据。

ETag:可以进行实时更新。不常用。

HTTP使用头字段

Range可以自行写程序来从服务器进行断点下载,而不使用IE,但需要服务器支持Range。

请求头:
Range: 头指示服务器只传输部分Web资源。这个头可以用来实现断点续传功能。

Range:字段可以通过3种格式设置要传输的字节范围  
Range: bytes=1000-2000      #  
Range: bytes=1000-          #1000以后的所有内容  
Range: bytes=1000           #传输最后1000个字节  

响应头:
Accept-Ranges: 说明Web服务器是否支持Range
Content-Ranges: 指定了返回的Web资源的字节范围。


以下内容来自《Tomcat与Java Web开发技术详解》

正文部分的MIME类型

HTTP请求及响应的正文部分可以是任意格式的数据,如何保证接收方能看懂发送方发送的正文数据?HTTP协议采用MIME协议来规范正文的数据格式。

MIME(Multipurpose Internet Mail Extension)是指多用在网络上传输的数据。因此,HTTP协议中的请求正文和响应正文也可以看做是邮件。MIME规定了邮件的标准数据格式,从而是的接收方能看得懂发送方发送的邮件。

遵守MIME协议的数据类型统称为MIME类型。在HTTP请求头和HTTP响应头中都有一个Content-type项,用来指定MIME类型。

文件扩展名 MIME类型
未知的数据类型或不可识别的扩展名 content/unknown
.bin、.exe、.o、.a、.z application/octet-stream
.pdf application/pdf
.zip application/zip
.tar application/x-tar
.gif image/gif
.jpg、.jpeg image/jpeg
.htm、.html text/html
.text、.c、.h、.txt、.java text/plain
.mpg、.mpeg video/mpeg
.xml application/xml

用Java套接字创建HTTP客户与服务器程序

见书籍《Tomcat与Java Web开发技术详解》孙卫琴

Web发展历程

Web按功能分,其发展历程分为如下阶段:

  • 发布静态HTML文档
  • 发布静态多媒体信息
  • 提供浏览器端与用户的动态交互功能:Java Applet、JavaScript和VBScript
  • 提供服务器端与用户的动态交互功能:PHP、ASP、JSP、Servlet、CGI
  • 发布基于Web的应用程序,即Web应用:Web应用,只需要通过编程来创建的Web站点,Web应用通过Web服务器来发布。
  • 发布Web服务:Web分为可以看做是被客户端远程调用的各种方法,这些方法能处理特定业务逻辑,或者进行复杂运算等。(它采用SOAP作为通信协议,使用XML语言进行通信)
  • 推出Web 2.0:Web 2.0并不是现有Web 1.0的纯技术升级版本;它只是针对如何提供、组织及展示Web上的信息而提出的新概念。在Web 1.0中,广大用户主要是Web提供的信息的消费者。而Web 2.0强调全民织网,发动广大民众来共同为Web提供信息来源(同时成为Web信息的制造者)。Web 2.0的范畴如下:Blog、RSS(站点摘要)、Wiki(百科全书)、SNS(社交网络软件)、IM(即时通讯)。

Web服务

Web服务:Web分为可以看做是被客户端远程调用的各种方法,这些方法能处理特定业务逻辑,或者进行复杂运算等。(它采用SOAP作为通信协议,使用XML语言进行通信)

                1.请求访问特定Web服务
___________         ------------->      ________      2.调用Web服务
| 客户程序 |                            | 服务器 |      ------>   Web服务
-----------         <-------------      --------
                3.返回Web服务的响应结果 

Web服务架构采用SOAP(Simple Object Access Protocol,简单对象访问协议)作为通信协议。SOAP协议规定客户与服务器之间一律采用XML语言进行通信。
SOAP协议规定了客户端向服务器端发送的Web服务请求的具体数据格式,以及服务器端向客户端发送的Web服务响应结果的具体数据格式。

要实现Web服务架构,就意味着必须创建基于SOAP协议,负责发布和调用Web服务,以及负责发送Web服务响应结果的服务器,还要创建基于SOAP协议的负责请求访问Web服务的客户程序
如果Web服务能够坐上Web这辆顺风车,就能轻易在网络上流传起来。

假定Web服务(对应getTime()方法)能返回当前的系统时间,客户端请求访问这个Web服务:
2017.02.14

Web服务实际上是借助Web服务器来发布到网络上的。这样就不必创建专门的基于SOAP协议的服务器程序了。

原始请求(请求时间) ----包装为----> SOAP请求  ---包装为---> HTTP请求 (其中SOAP请求变成了HTTP请求的正文部分) ----> 发送给服务器

SOAP响应 ----包装为----> HTTP响应  ----发送给客户端----> 客户端从HTTP响应中的正文中得到SOAP响应结果 -----协议解析器----->解析SOAP响应得打Web服务的**原始响应**(当前时间)

Web的基本功能:提供客户程序与服务器之间的数据传输。
Web服务的基本功能:是客户程序远程调用服务器端的方法。
由于在进行远程方法调用时,客户端与服务器之间也涉及到数据的交换,因此Web服务可以借助Web来传输双方的通信数据。

客户端协议解析器、客户端协议连接器组件,以及服务器端的协议解析器组件可以由第三方软件厂商提供。AXIS就是一个实现了这些组件的开放源代码软件,它相当于为发布和访问Web服务提供了基本的框架。

客户端向服务器端上传文件

在HTML表单中,<form>标记的enctype属性的值为默认的"application/x-www-form-urlencoded"。enctype属性用于指定表单数据的MIME类型,默认值表示表单数据会采用"名字=值"的形式,只有在这种情况下,HTML表单数据才可作为请求参数来处理。对于MIME类型为"multipart/form-data"的HTML表单,这种类型的表单的数据格式化较复杂,无法简单的采用"名字=值"的形式。

HTTP请求和响应的正文部分可以是任意类型的数据

示例:

    ...
    <!-- 请求正文 -->
	<form action="servlet/UploadServlet" name="uploadForm" method="POST" enctype="MULTIPART/FORM-DATA">
		<table>
			<tr> <!-- 文件部分 -->
				<td><div align="right">File Path:</div></td>
				<td><input type="file" name="filedata" size="30"></td>
			</tr>
			<tr>  <!-- 提交按钮部分 -->
				<td><input type="submit" name="submit" value="upload"></td>
				<td><input type="reset" name="reset" value="reset"></td>
			</tr>
		</table>
	</form>
	...

示例中HTTP请求的正文部分为复合类型,它包含两个子部分文件部分提交按钮部分。IE浏览器随机产生一个字符串形式的边界(boundary),在HTTP请求头中,以下代码设定了边界的取值:

Content-Type:multipart/form-data;boundary=-------------------------7d82d920188

其中Content-Type:multipart/form-data;boundary=用于指定 -------------------------7d82d920188为随机产生的边界值

注意:
HTTP请求的正文部分的各个子部分之间用边界来进行分隔。每个子部分由头和正文部分组成,头和正文部分之间用空行分隔

具体请求信息见书