1、Servlet

 一、了解Servlet的概念

 Servlet定义

 Servlet是基于Java技术的Web组件,由容器管理并产生动态的内容。Servlet引擎作为WEB服务器的扩展提供支持Servlet的功能。Servlet与客户端通过Servlet容器实现的请求/响应模型进行交互。

注意:Servlet不是从命令行启动的,而是由包含Java虚拟机的Web服务器进行加载

Servlet是按照Servlet规范编写的Java类。

Servlet应用请求/响应模型,扩展了服务器的功能。

Servlet是WEB应用程序中的一个组件。

Servlet是在JSP之前就存在的运行在服务端的一种Java技术,它是用Java语言编写的服务器端程序在JSP技术出现之前,Servlet被广泛地应用来开发动态的Web应用程序.如今在J2EE项目的开发中,Servlet仍然被广泛的使用。

Servlet是一种独立于平台和协议的服务器端的Java技术,可以用来生成动态的Web页面与传统的CGI(公共网关接口)和许多其他类似CGI技术相比,Servlet具有更好的可移植性、更强大的功能,更少的投资,更高的效率,更好的安全性等特点。

二、Servlet技术功能

 

Servlet通过创建一个框架来扩展服务器的能力,以提供在Web上进行请求和响应的服务。当客户机发送请求至服务器时,服务器可以将请求信息发送给Servlet,并让Servlet建立起服务器返回给客户机的响应当启动Web服务器或

客户机第一次请求服务时,可以自动装入Servlet,之后,Servlet继续运行直到其他客户机发出请求。

Servlet的功能涉及范围很广:

创建并返回一个包含基于客户请求性质的动态内容的完整的HTML页面;

创建可嵌入到现有HTML页面中的一部分HTML页面(HTML片段);

与其他服务器资源(包括数据库和基于Java的应用程序)进行通信;

用多个客户机处理连接,接收多个客户机的输入,并将结果传递到多个客户机上,例如,Servlet可以是多参与者的游戏服务器;

当允许在单连接方式下传送数据的情况下,在浏览器上打开服务器至applet的新连接,并将该连接保持在打开状态;当允许客户机和服务器简单、高效地执行会话的情况下,applet也可以启动客户浏览器和服务器之间的连接,可

以通过定制协议进行通信;

将订制的处理提供给所有服务器的标准程序。

三、 Servlet技术特点

Servlet技术带给程序员最大的优势是它可以处理客户端传来的HTTP请求,并返回一个响应Servlet是一个Java类,Java语言能够实现的功能,Servlet基本上都可以实现(图形界面除外)。

总的来说,Servlet技术具有以下特点:

1.高效。在服务器上仅有一个Java虚拟机在运行,它的优势在于当多个来自客户端的请求进行访问时,Servlet为每个请求分配一个线程而不是进程。

2.方便。Servlet提供了大量的实用工具例程,例如处理很难完成的HTML表单数据、读取和设置HTTP头、处理Cookie和跟踪会话等。

 

3.跨平台。Servlet是用Java类编写的,它可以在不同的操作系统平台和不同的应用服务器平台下运行。

4.灵活性和可扩展性。采用Servlet开发的Web应用程序,由于Java类的继承性、构造函数等特点,使得其应用灵活,可随意扩展。

6.共享数据。Servlet之间通过共享数据可以很容易地实现数据库连接池。它能方便地实现管理用户请求,简化Session和获取前一页面信息的操作。而在CGI之间通信则很差。由于每个CGI程序的调用都开始一个新的进程,调用间通

信通常要通过文件进行,因而相当缓慢。同一台服务器上的不同CGI程序之间的通信也相当麻烦。

7.安全。有些CGI版本有明显的安全弱点。即使是使用最新的标准和PERL等语言,系统也没有基本安全框架。而Java定义有完整的安全机制,包括SSL\CA认证、安全政策等规范。

四、 Servlet生命周期

跟客户端的Applet相似,Servlet(这里Servlet的概念又回到了最原始的含义)也遵循严格的生命周期。在每个Servlet实例的生命中有三种类型的事件,这三种事件分别对应于由Servlet引擎所唤醒的三个方法:

1.init()。当Servlet第一次被装载时,Servlet引擎调用这个Servlet的init()方法,只调用一次。如果某个Sevlet需要特殊的初始化需要。那么Servlet编写人员可以重写该方法来执行初始化任务。这是一个可选的方法。如果某个

Servlet不需要初始化,那么默认情况下将调用它父类的init方法。系统保证,在init方法成功完成以前,是不会调用Servlet去处理任何请求的。

2.service()。这是Servlet最重要的方法,是真正处理请求的地方。对于每个请求,Servlet引擎将调用Servlet的service方法,并把Servlet请求对象和Servlet响应对象最为参数传递给它。

3.destroy()。这是相对于init的可选方法,当Servlet即将被卸载时由Servlet引擎来调用,这个方法用来清除并释放在init方法中所分配的资源。

 Servlet的生命周期可以被归纳为以下几步:

(1) 装载Servlet,这一项操作一般是动态执行的。然而,Servlet通常会提供一个管理的选项,用于在Servlet启动时强制装载和初始化特定的Servlet

(2) Server创建一个Servlet实例

(3) Server调用Servlet的init方法

(4) 一个客户端请求到达Server

(5) Server创建一个请求对象

(6) Server创建一个响应对象

(7) Server激活Servlet的service方法,传递请求和响应对象作为参数

(8) service方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息

(9) service方法使用响应对象的方法。将响应传回Server,最终到达客户端。Service方法可能激活其他方法以处理请求。如doGet,doPost或其他程序员自己开发的方法

(10) 对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此servlet的service方法,将这两个对象作为参数传递给它,如此重复以上的循环,但无需再次调用init方法,Servlet一般只初始化一次

(11) 当Server不再需要Servlet时,比如当Server要关闭时,Server调用Servlet的destroy

五、servlet工作过程

Web服务器在与客户端交互时.Servlet的工作过程是:

在客户端对web服务器发出请求

web服务器接收到请求后将其发送给Servlet

Servlet容器为此产生一个实例对象并调用ServletAPI中相应的方法来对客户端HTTP请求进行处理,然后将处理的响应结果返回给WEB服务器.

web服务器将从Servlet实例对象中收到的响应结构发送回客户端.

六 、Servlet与JSP区别

简单的说,SUN首先发展出SERVLET,其功能比较强劲,体系设计也很先进,只是,它输出HTML语句还是采用了老的CGI方式,是一句一句输出,所以,编写和修改HTML非常不方便。 后来SUN推出了类似于ASP的镶嵌型的

JSP,把JSP TAG镶嵌到HTML语句中,这样,就大大简化和方便了网页的设计和修改。新型的网络语言如ASP,PHP,JSP都是镶嵌型的SCRIPT语言。

JSP在本质上就是SERVLET,但是两者的创建方式不一样.

Servlet完全是JAVA程序代码构成,擅长于流程控制和事务处理,通过Servlet来生成动态网页很不直观.

JSP由HTML代码和JSP标签构成,可以方便地编写动态网页.

因此在实际应用中采用Servlet来控制业务流程,而采用JSP来生成动态网页.在struts框架中,JSP位于MVC设计模式的视图层,而Servlet位于控制层.

JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。

JSP编译后是“类servlet”。

Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP是Java和HTML组合成一个扩展名为.jsp的文件。

JSP侧重于视图,Servlet主要用于控制逻辑。

七、Servlet代码结构

该Servlet处理的是get请求,如果读者不理解HTTP,可以把它看成是当用户在浏览器地址栏输入URL、单击Web页面中的链接、提交没有指定method的表单时浏览器所发出的请求

Servlet也可以很方便地处理post请求。post请求是提交那些指定了method=“post”的表单时所发出的请求。若要创建一个Servlet,则应使创建的类继承HttpServlet类,并覆盖doGet()、doPost()方法之一或全部。doGet()和doPost

()方法都有两个参数,分别为HttpServletRequest类型和HttpServletResponse类型。

HttpServletRequest提供访问有关请求的信息的方法,例如表单数据、HTTP请求头等。HttpServletResponse除了提供用于指定HTTP应答状态(200,404等)、应答头(Content-Type,Set-Cookie等)的方法之外,最重要的是它提供

了一个用于向客户端发送数据的PrintWriter。

对于简单的Servlet来说,它的大部分工作是通过println()方法生成向客户端发送的页面

注意:doGet()方法和doPost()方法抛出两个异常,因此必须在声明中包含它们。另外还必须导入java.io包(要用到PrintWriter等类)、javax.servlet包(要用到HttpServlet等类)以及javax.servlet.http包要用到(HttpServlet Request类和

HttpServletResponse类)。doGet()和doPost()这两个方法是由service()方法调用的,有时可能需要直接覆盖service()方法,比如Servlet要处理Get和Post两种请求时

如果要开发一个可以处理HTTP请求的Servlet程序,则肯定要继承HttpServlet类,而且在自定义的Servlet类中还要重写HttpServlet类中提供的doGet()方法。Servlet程序本身也是按照请求和应答的方式进行的,所以在doGet()方法

中定义了两个参数,即HttpServletRequest和HttpServletResponse,用来接收和回应用户的请求。

八、 Servlet第一个程序

新建一个工程,注意选择的类型

好一后,一直next,或者直接finish

新建后的工程目录

鼠标放在src上,右建proporty,新建一个servlet,记得是web下的servlet

输入包名和类名

选择生成的一些方法,不般都不用修改,一直next

生成后的代码结构

 

现在我们要来输入个helloworld,在上面代码加上:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("HelloWorld I am Servlet");
}

主目录下必须要有WEB-INF目录,WEB-INF目录下一定有一个符合j2ee标准的web.xml文件,eclipse默认没有生成,myeclipse默认是有生成 的,我们自己新建一个就行了。

选择到它,然后右键,选择proproty

新建一个XML,命名为web.xml

然后打开新建好的web.xml,内容改成如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    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">
  <servlet>
     <!-- 类名 -->
    <servlet-name>HelloWorld</servlet-name>
    <!-- 所在的包 -->
    <servlet-class>com.mucfc.chapter0.HelloWorld</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <!-- 访问的网址 -->
    <url-pattern>/servlet/HelloWorld</url-pattern>
    </servlet-mapping>
</web-app>


其中初始化阶段包括:Servlet启动,读取配置文件的信息,构造制定的Servlet对象,创建Servletconfig对象,将Servletconfig作为参数来调用init()方法。

2、String测试练习

public class testString {
/**
 * @param ycy
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
String x = "fmn";     //"fmn"在常数池里的不可变对象
x.toUpperCase();       //x.toUpperCase();在堆里new一个“FMN”对象,但是无引用指向他
String y = x.replace('f', 'F');  //在堆里new一个“Fmn”对象,y指向他
y = y + "wxy";
System.out.print(y);   //在堆里new一个“Fmnwxy”对象,y指向他
}
}

1)String 对象不可变;

2)x.toUpperCase();没有对原来的x进行覆盖。如果是x=x.toUpperCase();则对原来的x进行覆盖。

x.toUpperCase();首先判断是否有需要转换的大写字符,如果没有返回this,如果有新生成一个字符串。

3、基本类型默认值

 

默认值

存储字节

取值范围

大小/位

byte

0

1

-2^7-2^7-1

8

char

‘\u0000’

2

0-2^16-1

16

short

0

2

-2^15-2^15-1

16

int

0

4

-2^31-2^31-1

32

long

0

8

-2^63-2^63-1

64

float

0.0f

4

-2^31-2^31-1

32

double

0.0d

8

-2^63-2^63-1

64

boolean

false

1

False/true

8

 

“==”可以用于基本类型和引用类型,当时对比基本类型的时候是比较值是否相等,引用类型的时候比较对象是否相同,“!=”也是这样。

4、关键字和保留字

1.保留字(reserved words):是语言已经定义过的字,一些保留字可能没有相对应的语法,考虑到扩展性,为了向后兼容不能再将其作为变量名。const和goto是java的保留字。 所有的关键字都是小写。

2、final类型的变量一定要进行初始化,因为不能更改,否则不能执行,出现编译错误。

3、js中三种定义变量的方式const, var, let的区别。

1)const定义的变量不可以修改,而且必须初始化。

2)var定义的变量可以修改,如果不初始化会输出undefined,不会报错。

3)let是块级作用域,函数内部使用let定义后,对函数外部无影响。

4、关键字-关键字分为:访问控制、类方法和变量修饰符、程序控制语句、错误处理、包相关、基本类型、变量引用

abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float for goto if implements import instanceof int interface long native new package private protected public

return strictfp short static super switch synchronized this throw throws transient try void volatile while

访问控制修饰符的关键字:

1)private:可以应用于类、方法或字段(类中声明的变量),只能在声明的类内部中引用这些类、方法或字段,在外部或者对于子类而言是不可见的,类的默认访问范围是package访问,除非存在特殊的访问控制修饰符。可以从一个包中的任何类访问类成员。

2)protected:应用于类、方法或字段(类中声明的变量),可以在声明 protected 类、方法或字段的类、同一个包中的其他任何类以及任何子类(无论子类是在哪个包中声明的)中引用这些类、方法或字段。所有类成员的默认访问范围都是 package 访问,也就是说,除非存在特定的访问控制修饰符,否则可以从同一个包中的任何类访问类成员。当前类、同包、非同包的子类。

3)public:应用于类、方法或字段(在类中声明的变量)的访问控制修饰符。 可能只会在其他任何类或包中引用 public 类、方法或字段。所有类成员的默认访问范围都是 package 访问,也就是说,除非存在特定的访问控制修饰符,否则,可以从同一个包中的任何类访问类成员。所有类均可访问。

4、赋值符号

1)“=” 简单的赋值运算符,将右操作数的值赋给左侧操作数

2)“+ =”  加和赋值操作符,把左操作数和右操作数相加赋值给左操作数

3)“- =”  减和赋值操作符,把左操作数和右操作数相减赋值给左操作数

4)“* =”  乘和赋值操作符,把左操作数和右操作数相乘赋值给左操作数

5)“/ = ” 除和赋值操作符,把左操作数和右操作数相除赋值给左操作数

6)“(%)= ” 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数

7)“<< =”  左移位赋值运算符 C << = 2等价于C = C << 2

8)“>> = ” 右移位赋值运算符 C >> = 2等价于C = C >> 2

9)“&=”  按位与赋值运算符 C&= 2等价于C = C&2

10)“^ = ” 按位异或赋值操作符 C ^ = 2等价于C = C ^ 2

11)“| = ” 按位或赋值操作符 C | = 2等价于C = C | 2

12)“>>>=”右移赋值,左边空出来的位填充0;

13)没有“<<<=”