servlet

Servlet入门
基本概述
Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
PS:学习Servlet是学习JSP的基础,故很重要。

Servlet在网络中的位置

Servlet的生命周期

1、WEB服务器(Tomcat)首先会找到该Servlet并装载该Servlet
2、WEB服务器(Tomcat)会创建该Servlet的实例
3、WEB服务器(Tomcat)会调用实例对象的init()方法
4、WEB服务器(Tomcat)创建一个封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用service()方法并将请求对象和响应对象作为参数传递进去。(实现是通过多线程技术)
5、WEB服务器在某种情况,停止对该Servlet支持,Servlet引擎将卸载该Servlet,在卸载之前会调用Servlet的destroy()方法进行销毁

手工开发Servlet的方式
1、在Tomcat主目录的webapps文件夹下建立一个web应用web1
2、在web1下建立文件夹WEB-INF,在该文件夹中建立web.xml [web.xml可以从 ROOT/WEB-INF/web.xml拷贝]
3、在WEB-INF目录下建立classes目录(Servlet在该目录下开发),建立lib目录
4、在classes目录下开发Servlet
5、在web.xml中配置web.xml
6、编译Servlet文件(编译时需要将servlet-api.jar包加入环境变量classpath中,该jar包在Tomcat主目录的lib文件夹下)
7、运行Tomcat
8、访问Servlet

开发Servlet的三种方法
1、实现Servlet接口
[java] view plain copy
/**
使用实现Servlet接口的方式开发一个Servlet
要求:显示当前时间
*/
package com.pc;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Servlet2 implements Servlet{
// 该方法用于初始化Servlet,就是把该Servlet装载入内存,该方法只会被调用一次
public void init(ServletConfig config){
}

// 得到ServletConfig对象  
public ServletConfig getServletConfig(){  
    return null;  
}  

// 该方法是服务方法,业务逻辑代码写在这  
// 该方法每次都会被调用  
public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException{  
    // 在控制台输出  
    System.out.println("hello world:" + new java.util.Date().toString());  
    // 在浏览器返回  
    res.getWriter().println("hello world:" + new java.util.Date().toLocaleString());  
}  

// 该方法得到Servlet配置信息  
public java.lang.String getServletInfo(){  
    return null;  
}  

// 销毁该Servlet,从内存中清除,该方法只会被调用一次  
public void destroy(){  

}  

}

PS:不仅要写Servlet文件,还要在web.xml中添加配置信息,配置信息格式如下:
[html] view plain copy



Servlet2

com.pc.Servlet2




Servlet2

/Servlet2

PS:
1、在classes文件夹下编译(当然Servlet文件也应该在这里)
javac -encoding UTF-8 -d . Servlet文件名.java

2、不重启更新web应用
首先,在Tomcat主目录的conf文件夹中找到tomcat-users.xml文件,打开它,并在标签中添加如下语句
[html] view plain copy




然后,在localhost:8080主界面点击,进入manager界面,找到该应用,点击reload按钮即可。

2、继承GenericServlet类
[java] view plain copy
/**
使用继承GenericServlet的方式开发一个Servlet
*/

package com.pc;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class Servlet3 extends GenericServlet{
// 该方法是服务方法,业务逻辑代码写在这
// 该方法每次都会被调用
public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException{
res.getWriter().println(“hellow,world, GenericServle.”);
}
}

PS:不仅要写Servlet文件,还要在web.xml中添加配置信息,配置信息格式如下:
[html] view plain copy

Servlet3
com.pc.Servlet3


Servlet3
/Servlet3

扩展:GenericServlet抽象类源码和常见方法
[java] view plain copy
public abstract class GenericServlet implements Servlet, ServletConfig,java.io.Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config;
public GenericServlet() {}
@Override
public void destroy() {}
@Override
public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
}
@Override
public Enumeration getInitParameterNames() {
return getServletConfig().getInitParameterNames();
}
@Override
public ServletConfig getServletConfig() {
return config;
}
@Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}
@Override
public String getServletInfo() {
return “”;
}
@Override
//实现了Servlet的init(ServletConfig)方法,把参数config赋给了本类的成员config,然后再调用本类自己的无参的init()方法。
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
//这个方法是GenericServlet自己的方法,而不是从Servlet继承下来的。
//当我们自定义Servlet时,如果想完成初始化作用就不要再重写init(ServletConfig)方法了,而是应该去重写init()方法。
//因为在GenericServlet中的init(ServletConfig)方法中保存了ServletConfig对象,如果覆盖了保存ServletConfig的代码,那么就不能再使用ServletConfig了。
public void init() throws ServletException {}
public void log(String msg) {
getServletContext().log(getServletName() + “: ” + msg);
}
public void log(String message, Throwable t) {
getServletContext().log(getServletName() + “: ” + message, t);
}
@Override
public abstract void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
@Override
public String getServletName() {
return config.getServletName();
}
}

GenericServlet的init()方法
在GenericServlet中,定义了一个ServletConfig config实例变量,并在init(ServletConfig)方法中把参数ServletConfig赋给了实例变量。然后在该类的很多方法中使用了实例变量config。
如果子类覆盖了GenericServlet的init(StringConfig)方法,那么this.config=config这一条语句就会被覆盖了,也就是说GenericServlet的实例变量config的值为null,那么所有依赖config的方法都不能使用了。如果真的希望完成一些初始化操作,那么去覆盖GenericServlet提供的init()方法,它是没有参数的init()方法,它会在init(ServletConfig)方法中被调用。

实现了ServletConfig接口
GenericServlet还实现了ServletConfig接口,所以可以直接调用getInitParameter()、getServletContext()等ServletConfig的方法。

3、继承HttpServlet类
[java] view plain copy
/**
使用继承HttpServlet的方式开发一个Servlet
要求:显示当前时间
*/

package com.pc;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class Servlet4 extends HttpServlet{
// 在HttpServlet中,设计者分别提供了对Post提交和Get提交的处理,默认是get提交
// doGet().doPost()底层也是调用service方法

// 处理Get请求  
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{  

    resp.getWriter().println("doGet()");  
}  
// 处理Post请求  
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{  
    resp.getWriter().println("doPost()");  
}  

}

PS:不仅要写Servlet文件,还要在web.xml中添加配置信息,配置信息格式如下:

[html] view plain copy

Servlet4
com.pc.Servlet4


Servlet4
/Servlet4

扩展:HttpServlet抽象类
HttpServlet覆盖了service()方法
HttpServlet类中提供了service(HttpServletRequest,HttpServletResponse)方法,这个方法是HttpServlet自己的方法,不是从Servlet继承来的。在HttpServlet的service(ServletRequest,ServletResponse)方法中会把ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse,然后调用service(HttpServletRequest,HttpServletResponse)方法,这说明子类可以去覆盖service(HttpServletRequest,HttpServletResponse)方法即可,这就不用自己去强转请求和响应对象了。
其实子类也不用去覆盖service(HttpServletRequest,HttpServletResponse)方法,因为HttpServlet还要做另一步简化操作。
[java] view plain copy
public abstract class HttpServlet extends GenericServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
……
}
@Override
public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;

    try {  
        //强转  
        request = (HttpServletRequest) req;  
        response = (HttpServletResponse) res;  
    } catch (ClassCastException e) {  
        throw new ServletException("non-HTTP request or response");  
    }  
    //调用上面的service方法  
    service(request, response);  
}  
……  

}

使用MyEclipse集成开发环境IDE来开发Web应用
PS:具体的配置步骤可以参考搜索引擎。
MyEclipse的开发目录结构

Servlet细节问题
1、一个已经注册的Servlet可以被多次映射
[html] view plain copy

This is the description of my J2EE component
This is the display name of my J2EE component

MyServlet1

com.web1.servlet.MyServlet1




MyServlet1

/MyServlet1


MyServlet1
/abc

2、当映射一个Servlet时,可以多层映射
[html] view plain copy
/servlet/index.html

3、在Servlet使用通配符映射到URL
有两种格式:
第一种格式 .扩展名 比如 .do *.ss
第二种格式 以 / 开头 同时以 /* 结尾 比如 /* /news/*

通配符案例:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
问题:
1、当请求URL为“/abc/a.html”,“/abc/”和“/”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
2、当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
Servlet引擎将调用Servlet3。
3、当请求URL为“/abc/a.do”时,“/abc/”和“.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
4、当请求URL为“/a.do”时,“/”和“.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
5、当请求URL为“/xxx/yyy/a.do”时,“/”和“.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。

在匹配的时候,要参考的标准:
1、看谁的匹配度高,谁就被选择
2、*.do 的优先级最低

url-pattert匹配规则

案例

4、servlet中的配置
当需要在网站启动时,初始化一些资源时可以配置
[html] view plain copy

1

PS:在servlet中如此配置就行,中间的数是整数,越小优先级越高。
配置好了之后,在网站启动时就会调用该Servlet的init()方法,所以可以在该方法中进行需要的初始化步骤,比如定时刷新,建立内存表之类的等等。

ServletConfig对象
该对象主要用于读取 servlet的配置信息.
案例:
[html] view plain copy

ServletConfigTest
com.web1.servlet.ServletConfigTest


encoding
utf-8

如何使用:在Servlet使用如下语句
[java] view plain copy
String encoding = this.getServletConfig().getInitParameter(“encoding”);

补充说明:这种配置参数的方式,只能被某个Servlet独立使用.如希望让所有的Servlet都去读取某个参数,这样配置:
[html] view plain copy




读取所有的参数,可以使用如下方法:
[java] view plain copy
Enumeration names=this.getServletConfig().getInitParameterNames();
while(names.hasMoreElements()){
String name=names.nextElement();
System.out.println(name);
System.out.println(this.getServletConfig().getInitParameter(name));
}

注意事项:
1、Servlet类是单例、多线程的,所以要注意线程同步情况,也就是线程不安全的。
2、Servlet的service()方法,在每次响应时都会调用一次。
3、Servlet的init()初始化方法,destroy()销毁方法只会被调用一次。
4、Servlet的service()方法,会根据客户端的请求方法来决定调用对应的doXXX()方法。
5、不要重写构造方法,因为所继承的HttpServlet及其父类都已经对构造方法进行了某些初始化,当不了解这些系统自带的初始化,然后盲目使用构造方法,可能导致Servlet无法创建实例。
6、不要重写service方法(在继承HttpServlet的情况下),因为其内部有判别客户端请求方法的逻辑和一些其他逻辑。
7、必须重写doPost()或者是doGet()方法中的一个。
8、当想用一种逻辑去处理Get和Post请求,可以采用委托机制,在doPost方法内加入this.doGet(request, response); 或者在doGet方法中加入this.doPost(request, response);
9、继承HttpServlet开发Servlet是最常用的方法。
10、get提交和post提交的区别
10.1、从安全的角度看,get < post,因为get会把提交的信息显示到地址栏。
10.2、从提交内容大小看, get < post, get一般不要大于2k,post理论无限制,但是在实际开发中,建议不要大于64k
10.3、从速度看,get > post,因为get仅仅只是获取数据而已
11、Servlet的映射的后缀名不一定代表它就真的是那格式的文件。

Servlet的多线程处理
servlet多线程工作原理

servlet域的线程安全情况

servlet并发注意事项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值