1 简介
Servlet,(Server+Applet,一个运行在服务器端的小程序)。与前面的JDBC一样,都是JavaEE中的基本技术。
一种独立于平台和协议的服务器端的Java应用程序,运行于Web服务器内部(服务器端)。与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机,可以生成动态的Web页面。它担当Web浏览器或其他HTTP客户程序发出请求,与HTTP服务器上的数据库或应用程序之间的中间层。
服务器上需要一些程序,常常是根据用户输入访问数据库的程序。这些通常是使用公共网关接口(CGI)应用程序完成的。然而,在服务器上运行Java,这种程序可使用Java编程语言实现。在通信量大的服务器上,Java servlet的优点在于它们的执行速度更快于CGI程序。各个用户请求被激活成单个程序中的一个线程,而创建单独的程序,这意味着各个请求的系统开销比较小。
首先理解,电脑可以作为服务器,云服务器ECS也是服务器,其中可以安装Web服务器,使用Http协议与客户端通信。
Web服务器与Web应用层属于互不相容的两个范畴。为了使服务器和应用层可以协作,首先应用中介方制定Web应用层与Web服务器进行协作的标准接口,Servlet就是其中一个主要的协议、接口,使得服务器端可以使用Java来动态生成网页。
Web应用层与Web服务器进行协作的一系列标准Java接口,统称Java Servlet API。另外还有一些Servlet规范。Servlet规范把能够与发布和运行Java Web应用容器的Web服务器称为Servlet容器。
1.1 JavaEE的十三种基本技术(了解)
1.JDBC(Java Database Connectivity)
JDBC API为访问不同的数据库提供了一种统一的途径,就像ODBC一样,JDBC对开发者屏蔽了一些细节问题,同时,JDBC对数据库的访问也具有平台无关性。
2.JNDI(Java Name and Directory Interface)
JNDI API 被用于执行名字和目录服务。它提供了一致的模型用来存取和操作企业级的资源如DNS和LDAP,本地文件系统,或应用服务器中的对象。
3.EJB(Enterprise JavaBean)
JavaEE技术之所以赢得全体广泛重视的原因之一就是EJB,他们提供了一个框架开发和实施分布式商务逻辑,由此很显著简化了具有可伸缩性和高度复杂的企业级应用开发。EJB规范定义了EJB组件何时如何与他们的容器继续拧交互作用。容器负责提供公用的服务,例如目录服务、事务管理、安全性、资源缓冲池以及容错性。但是注意的是,EJB并不是J2EE的唯一途径。正是由于EJB的开放性,使得有的厂商能够以一种和EJB平行的方式来达到同样的目的。
4.RMI(RemoteMethod Invoke) remote(遥远的)、invoke(调用)
正如其名字所表示的那样,RMI协议调用远程对象上方法。它使用了序列化方式在客户端和服务器端传递数据。RMI是一种被EJB使用的更底层的协议。
5.Java IDL(接口定义语言)/CORBA:公共对象请求代理结构(Common Object Request Breaker Architecture)
在Java IDL的支持下,开发人员可以将Java和CORBA集成在一起。他们可以创建Java对象并使之可以在CORBA ORB中展开,或者他们还可以创建Java类并做为和其他ORB一起展开的CORBA对象客户。后一种方法提供了另外一种途径,通过它可以被用于你的新的应用和旧系统相集成。
6.JSP(Java Server Pages)
Jsp页面由html代码和嵌入其中的Java新代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理,然后将生成的HTML页面返回给客户端的浏览器。
7.Java Servlet
Servlet是一种小型的Java程序,它扩展了Web服务器的功能。作为一种服务器端的应用,当被请求时开始执行,这和CGI Perl脚本很相似。Servlet提供的功能大多和JSP类似,不过实现方式不同。JSP通过大多数的html代码中嵌入少量的java代码,而Servlet全部由Java写成并生成相应的HTML。
8.XML(Extensible Markup Language)
XML是一种可以用来定义其他标记语言的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是互相独立的,但是,它和Java具有相同目标正是平台独立。通过Java和XML的组合,我们可以得到一个完美的具有平台独立性的解决方案。
9.JMS(Java Message Service)
MS是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有支持发布/订阅类型的域,并且提供对下列类型的支持:经认可的消息传递,事务性消息传递,一致性消息和具有持久性的订阅者的支持。JMS还提供了另一种方式对您的应用与旧的后台系统相集成。
10.JTA(Java Transaction Architecture)
JTA定义了一种标准API,应用系统由此可以访问各种事务监控。
11.JTS(Java Transaction Service)
JTS是CORBA OTS事务监控的基本实现。JTS规定了事务管理器的实现方式。该事务管理器是在高层支持Java Transaction API(JTA)规范,并且在较底层实现OMG OTS specification的Java映像。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。
12.JavaMail
JavaMail是用于存取邮件服务的API,它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器,也支持IMAP服务器。
13.JAF(JavaBeans Activation Framework):
JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF
1.2 两种开发模式
1.2.1 C/S开发架构(Client/Server)模式
优点:
1.客户端独立设计,可以实现个性化
2.客户端需要安装,不需要重复安装和加载
3.客户端独立开发,有能力对客户端进行安全设计
缺点:
1.客户端不需要重复安装,用户可以选择不进行更新升级,增加了维护成本
2.需要开发客户端和服务器两套程序,所以开发成本会增加
3.遇到不同的操作系统,需要为不同的操作系统各开发一套客户端
1.2.2 B/S架构(Browser/Server)开发模式
优点:
1.B/S架构具备通用性,开发成本较低
2.无需安装客户端,所以客户端不需进行升级,只需更新后台代码即可更新所有客户端
3.B/S架构多用Web网页进行开发,所以增删功能也非常容易,只需要修改网页即可完成
缺点:
1.耗流量,每次都要加载全部的内容(缓存可以降低流量损耗)
2.没有独立的客户端,所以无法实现个性化(通过账号体系可以实现)
3.没有独立设计客户端,所以客户端难以实现安全控制(使用Https、控件)
4.难以实现特殊操作(比如删本地文件),所以所有的杀毒软件都是C/S架构的。B/S架构更多的时候是使用了Http协议、而C/S架构更多的时候使用的WinSocket协议(TCP、UDP)
1.3 什么是Tomcat
Tomcat是一个Web服务器。而Web容器是一种技术规范,是一个可以部署多个Web应用程序的环境,很多公司对它进行了技术实现,Tomcat是其中一种。
作为Web容器,它可以管理和部署Web应用;工作模式默认为独立的Servlet容器,管理Web应用中众多Servlet的生命周期,它实现了对JSP和Servlet的支持,可容纳许多独立的Web应用,并管理这些应用与Web服务器的交互。
服务器上安装了操作系统,操作系统中安装着各种Web服务器作为容器。真正起作用的项目是从本地上传部署到容器中的项目,而不是在本地编写的项目。
Web服务器
也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。
(1)应用层使用HTTP协议。 (2)HTML文档格式。 (3)浏览器统一资源定位器(URL)。
使用最多的Web服务器软件有两个:微软的信息服务器(iis)和Apache。
通俗的讲,Web服务器传送(serves)页面使浏览器可以浏览,然而应用程序服务器提供的是客户端应用程序可以调用(call)的方法(methods)。确切一点,你可以说:Web服务器专门处理HTTP请求(request),但是应用程序服务器是通过很多协议来为应用程序提供(serves)商业逻辑(business logic)。
Web服务器可以解析(handles)HTTP协议。当Web服务器接收到一个HTTP请求(request),会返回一个HTTP响应(response),例如送回一个HTML页面。为了处理一个请求(request),Web服务器可以响应(response)一个静态页面或图片,进行页面跳转(redirect),或者把动态响应(dynamic response)的产生委托(delegate)给一些其它的程序例如CGI脚本,JSP(JavaServer Pages)脚本,servlets,ASP(Active Server Pages)脚本,服务器端(server-side)JavaScript,或者一些其它的服务器端(server-side)技术。无论它们(译者注:脚本)的目的如何,这些服务器端(server-side)的程序通常产生一个HTML的响应(response)来让浏览器可以浏览。
要知道,Web服务器的代理模型(delegation model)非常简单。当一个请求(request)被送到Web服务器里来时,它只单纯的把请求(request)传递给可以很好的处理请求(request)的程序(译者注:服务器端脚本)。Web服务器仅仅提供一个可以执行服务器端(server-side)程序和返回(程序所产生的)响应(response)的环境,而不会超出职能范围。服务器端(server-side)程序通常具有事务处理(transaction processing),数据库连接(database connectivity)和消息(messaging)等功能。
虽然Web服务器不支持事务处理或数据库连接池,但它可以配置(employ)各种策略(strategies)来实现容错性(fault tolerance)和可扩展性(scalability),例如负载平衡(load balancing),缓冲(caching)。集群特征(clustering—features)经常被误认为仅仅是应用程序服务器专有的特征。
Web容器
充当中间件的角色(所谓容器就是指符合一定的规范能提供一系列服务的管理器,方便别人使用它来完成一系列的功能)。
给处于其中的应用程序组件(JSP,Servlet)提供一个环境,使JSP、Servlet直接与容器中的环境变量接口交互,不必关注其它系统问题。主要由Web服务器来实现。例如:Tomcat,Weblogic,Websphere等。该容器提供的接口严格遵守JavaEE规范中的Web Application标准。我们把遵守以上标准的WEB服务器就叫做JavaEE中的WEB容器。
例如Tomcat,使用Tomcat可以为我们提供Servlet、JSP等服务,我们也俗称作Servlet服务器,在服务器中会有相关的容器,Servlet容器可以调用Servlet和JSP动态的为我们生成HTML。
对于刚刚接触的人来说,把服务器就理解成一个容器也可以,不过两者的确不是一回事,是服务器为我们提供一个容器使我们的程序能够在容器里运行,使用服务器提供的一系列功能。
1.4 静态页面和动态页面
- 静态页面
S1.客户端向Web服务器端发送一个请求
S2.Web服务器接收到请求,并根据此查找页面
S3.Web服务器查找到资源,响应请求
S4.Web服务器端向客户端返回一个响应,返回可以让客户端看到的网页
此时,页面的数据都是写死的,Web服务器只是根据不同的请求调用静态页面,但是据客户的请求并不会对页面做任何处理。
- 动态页面
S1.客户端向Web服务器端发送一个请求
S2.Tomcat容器解析Http请求数据包,把请求和参数解析出来给Servlet使用
S3.Tomcat容器把Servlet处理结果封装到Http响应数据包
S4.返回服务器端的处理结果
Servlet的页面是动态的,原因在于Servlet会动态处理客户端的请求。并根据请求的不同返回不同的响应,从而客户端可以看到动态、不同的结果。
2 初步编写
在【第41天】、【第42、43天】编写的关系表、实体类、工厂类、dao层的基础上继续编写。
这里转而使用MyEclipse编写代码,但这并不重要。主要注意Eclipse系不同于Intellij的地方在于多了一个workplace(自己设置的一个目录),工程、IDE的偏好设置都放置在其中;在src目录之外多了一个WebRoot目录,这个目录可以直接使用浏览器访问,是资源文件(网页相关、jar包、SQL脚本)存放的位置。jar包由Intellij工程下的lib包转为Webroot→WEB-INF→lib下。
2.1 编写一个表单
WebRoot/index.html
<!DOCTYPE html>
<html>
<head>
<title>用户登录</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div id="container">
<h3>用户登录</h3>
<hr />
<!--
action表示提交到的目的地
如果是静态网页则直接书写一个静态页面
这里使用的是动态页面的写法:servlet/类名
对于初学者来说请使用这种书写方式
表单无论post/get皆可自由设置,默认为get,表单是高级的链接
链接只能是get,浏览器自发跳转也只能使用get跳转
-->
<form action="servlet/Login" method="post">
<label for="nameid">用户姓名:</label>
<input type="text" name="name" id="nameid"
style="width:138px" required placeholder="请输入用户名" />
<br />
<label for="passid">用户密码:</label>
<input type="password" name="passwd" id="passid"
style="width:138px" required placeholder="请输入用户密码" />
<br />
<input type="submit" value="提交" />
<input type="reset" value="取消" />
</form>
</div>
</body>
</html>
WebRoot/css/style.css
div#container{
margin:0 auto;
width:600px;
height:800px;
border-radius:28px;
background-color:silver;
border:solid 1px silver;
text-align:center;
}
h3{
margin-top:70px;
}
- 表单提交时GET与POST的区别
- GET:速度快,但安全性低下,通过浏览器地址栏传递值,传递的格式是:“地址?key1=value1&key2=value2&keyN=valueN”,最多传递256个字符,不支持中文(会乱码)。只能传递字符,可以由浏览器直接访问这个链接。注意如果使用链接传递值时肯定是GET方式,也可以这么用:
<a href=“地址?key=value&keyN=valueN”>我是一个链接 - POST:速度慢,安全性高,不通过浏览器地址栏传递值。通过Http数据报的消息体传递值,传值格式与get完全一致,但我们无法查看。由浏览器访问POST请求的链接时,会报405错误。不支持中文(会乱码),没有大小限制,所以上传等操作,必须使用POST。
- GET:速度快,但安全性低下,通过浏览器地址栏传递值,传递的格式是:“地址?key1=value1&key2=value2&keyN=valueN”,最多传递256个字符,不支持中文(会乱码)。只能传递字符,可以由浏览器直接访问这个链接。注意如果使用链接传递值时肯定是GET方式,也可以这么用:
2.2 编写Servlet类
若Servlet类中只继承了doGet()/doPost()而没有继承service(),Http请求先在被继承的父类中service()被接收到然后判断请求类型,执行被子类覆盖的doGet()/doPost()。若覆盖了service(),类中doGet()/doPost()失效。
- doPost()先定义软连接的意义:
这里前面HTML文件中表单提交后要跳转到一个使用Servlet画的一个网页(服务端返回到客户端的响应文件)。要使用字符流画网页,相当于字符流写入一个文本文件,要让浏览器以HTML格式读取这个文本文件,需要在写入response响应文件(字符流写入文本文件)前,定义setContentType让浏览器收到响应文件时以html文件格式和utf-8字符集解析。而要让服务端可识别发来请求的含义,也需要request请求时定义setCharacterEncoding让服务端使用utf-8字符集解析。
字符流定义为response.getWriter()一定要在设定字符集response.setContentType()之后。
package com.test.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.test.dao.StudentDaoImpl;
import com.test.po.Student;
/*
* 一个普通的Java类,只要继承了HttpServlet则
* 这个类就可以称之为Servlet类
*
* */
public class Login extends HttpServlet{
/*
* HttpServletRequest:接口,封装了所有提交过来的请求
* HttpServletResponse:接口,封装了所有要发送走的响应
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//定义软编码
/*
* 此编码用来设置Servlet的中文支持,否则接受过来的信息和要发送走的信息都不支持中文
*
* text/html:MIME类型之一,用来提示浏览器按照什么格式来进行解析。这里定义为html格式的解析类型。
* MIME(Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务)
* 设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,
* 浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
* MIME共有数百种写法,常见的有text/css、text/javascript、text/plain、applicatio/json、image/jpeg等等
* 如果此处书写错误,则在浏览器打开这个页面时,会提示下载
*/
//定义编码方式的位置要在第一次使用request、response之前
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 接受页面提交过来的值
// 此处括号中的值对应 <input type="text" name="对应这里" />
String name = request.getParameter("name");
String passwd = request.getParameter("passwd");
// 使用多态引入dao层
StudentDaoIf sdi = new StudentDaoImpl();
// 根据用户名和密码查询
Student stu = sdi.queryStudentByNameAndPass(name, passwd);
// 拿取字符输出流
PrintWriter out = response.getWriter();
out.print("<html>");
out.print("<head><title>");
if(stu != null) {
out.print("登陆成功</title></head>");
out.print("<body>");
out.print("欢迎您回来" + stu.getName() + "<hr />");
out.print("</body>");
out.print("</html>");
out.close();
return;
}
out.print("登录失败</title></head>");
out.print("<body>");
out.print("数据库中查无此人请您先注册<hr />");
out.print("</body>");
out.print("</html>");
out.close();
}
}
2.3 编写web.xml
此文件是整个工程中最重要的配置文件,也是整个工程的核心。当tomcat开启时,要首先校检本文件与启动相关的配置是否正确,如果出现错误,则会造成tomcat开启失败或跳转出现错误码等异常情况,本文件部署了所有Servlet实例的地址、跳转路径、私有参数、公有参数等等。
这个文件在这里的作用是依据HTML代码,当客户端发送请求时,服务器会根据web.xml中父标签为servlet-mapping的配置,先对应请求的href/action地址找到符合的url-pattern标签,依据这个地址对应的servlet-name,找到servlet为父标签的servlet-class标签中的类地址。完成服务器依据请求地址找到对应Servlet类的动作,就像按照花名册找学生一样,这里的servlet标签和servlet-mapping标签的内容需要一一对应。使用Servlet,防止让访问者直接看到类路径,提高安全性。初学时还是要看到类的,之后这里写法会有更新。
注意,tomcat显示开启时间并不代表它正常启动了,要看控制台有没有抛异常,像这里的第二步第三步如果不对应,就会出现显示开启时间但是服务器没有正常开启的情况。
WebRoot/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>servletDay1_base</display-name>
<servlet>
<!--
S3.此处对应servlet-mapping节点下的servlet-name节点值
-->
<servlet-name>Login</servlet-name>
<!--
S4.此处为servlet实例的确切地址,
可以长按Ctrl键点击链接名来测试此处路径是否有效(是否可以跳转到这个类)
如果此处路径书写错误,则服务器能开启,但是在这个Servlet跳转时,
会报500错误---ClassNotFoundException
(web.xml找不到这个servlet类,报500)
-->
<servlet-class>com.test.servlet.Login</servlet-class>
</servlet>
<servlet-mapping>
<!--
S2.拦截成功找到此处书写的假名,
此处节点值随意书写(不写中文),但是必须对应servlet标签中servlet-name节点值
如果不对应,则tomcat开启失败
-->
<servlet-name>Login</servlet-name>
<!--
S1.此处对应链接的href属性或表单的action属性,用来拦截发送过来的请求提交的路径
注意这里比href或者action书写的基本路径写法多了一个“/”
当提交时,被此处拦截,如果拦截失败(与HTML中地址不一致),则404错误,但服务器可以正常开启
(客户端发出请求但web.xml接不到,报404)
-->
<url-pattern>/servlet/Login</url-pattern>
</servlet-mapping>
<!--
从上而下检查页面是否存在,哪个先找到就跳转到哪个作为首页,
如果都没有找到,服务器可以正常开启,但若访问时链接后面不指明访问哪个文件,
就会报404,此时无法跳转到欢迎页
-->
<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>
</web-app>
2.4 常见错误分析
如果是页面出错,则tomcat不需要关闭,刷新页面即可;如果是Java类或者配置文件出错,则必须首先关闭tomcat,修改结束后重新开启。
-
404
case1.后面跟随一个路径:表示根据这个路径没有找到资源
case2.后面没有跟随路径:表示tomcat根本没有开启,先查看服务器启动时的控制台,看是否有异常出现
未开启的原因:a:tomcat已经开启了一个了不能开启第二个 b:tomcat文件缺失 c:web.xml文件解析错误
-
405 检查HTML的请求类型与servlet类接收请求的方法是否一致,由浏览器直接访问post请求方式的链接时也会报这个错误。
须严格对应get---doPost post---doGet
-
500 编译失败,报异常,多为服务器内部错误,此时需要查看错误信息是否是Java文件编写错误或出现异常。