您的位置:首页 > 其它

Web基础之与Servlet的邂逅

2017-04-21 17:40 417 查看
Web基础之与Servlet的邂逅

一、Servlet简介:
Servlet全名为Server applet,即服务端小应用。
Setvlet的API文档描述:(看不懂的直接略过)



二、如何创建Servlet以及Servlet的生命周期

通过文档描述,我们可以三种方式创建Servlet
实现Servlet接口
继承GenericServlet抽象类
继承HttpServlet普通类

API中提到Servlet生命周期的三个阶段,刚好对应三个接口方法:
init   :构造Servlet时调用的方法;
service:处理request时调用的方法;

destroy:销毁Servlet时调用的方法



三、创建我们的第一个Servlet

1、打开JavaEE,新建一个Dynamic项目;取名为Servlet01;在src目录下新建一个名为FirstServlet.java类;

整个项目结构如下图:



编辑我们的第一个Servlet
package com.hx.serverlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

//通过实现Servlet接口创建我们的第一个Servlet,注意不要导错包 import javax.servlet.Servlet;
public class FirstServlet implements Servlet{

//初始化参数
private String str=null;
//构造函数
public FirstServlet() {
System.out.println("do my constucter......");
}
//	初始化方法
public void init(ServletConfig config) throws ServletException {
str=config.getInitParameter("str");
System.out.println("do my init .......");
}
//service方法
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
//		设置响应输出的文本类型;这里设置为html文本输出;字符编码为UTF-8
res.setContentType("text/html;charset=UTF-8");
//		输出响应正文
res.getWriter().print(""
+ "<!DOCTYPE html><head><body><p>"+str+"</p></body></head>");
}
//销毁方法,一般太快,捕捉不到
public void destroy() {
System.out.println("do my destory......");
}
//后面这两个方法放到后面讲
public ServletConfig getServletConfig() {
return null;
}

public String getServletInfo() {
return null;
}

}


编辑好以后,打开web.xml配置文件,加入如下配置信息



关于web.xml配置文件的解释:



<servlet>
<servlet-name>firstServlet</servlet-name>
<servlet-class>com.hx.serverlet.FirstServlet</servlet-class>
<init-param>
<param-name>str</param-name>
<param-value>Hello World!</param-value>
</init-param>
</servlet>


这里相当于用FirstServlet 创建了一个名为firstServlet对象;等价于FirstServlet  firstServlet = new FirstServlet ();
并且初始化了一个名为str的变量,变量中的内容为Hello World!

<servlet-mapping>
<servlet-name>firstServlet</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>

这里的配置代表当访问/first路径时,要交给firstServlet对象处理;也就是执行上面我们写的Java代码;根据Servlet的生命周期,会一次调用init()方法,service()方法;当关闭程序是,执行destory()方法;

好了,保存我们上面写的代码和配置文件,将该工程发布到Tomcat服务器下并启动Tomcat服务器(不知道发布的请看我前面的博客)

启动后,在浏览器中输入http://localhost:8080/Seervlet01/first访问,会看到如下界面;



如上,我们的第一Servlet就创建好了;

看下控制台的打印信息:(destory没有抓取到,可以再次理解下Servlet生命周期)



Servlet中的其他方法:
public String getServletInfo()
获取Servlet信息,用处不大,可以返回当前Servlet的作者,版本号等。

public ServletConfig getServletConfig()
在init方法中有一个ServletConfig入参,我们将其保存到一个Field中,当使用 getServletConfig方法时,可以返回该ServletConfig 对象。



四、设计我们自己的Servlet抽象类和HttpServlet类

现在,我们可以思考这样一个问题,基本所有的Servlet都会调用init()方法和destory()方法,还有getServletInfo()方法,getServletConfig()方法,但我们真正处理业务逻辑的方法是service()方法;所以,我们可以设计一个抽象类,让这个抽象类实现Servlet接口以及除service()方法外的四个方法的具体实现;而service()则交给真正需要处理业务逻辑的类实现该方法;由于Servlet中获取ServletConfig的各种信息需要通过getServletConfig().getXX()间接获取,为了让Servlet中直接有getServletName(),所以我们这里也实现了ServletConfig接口,就相当于进一步包装;

我们自己的抽象Servlet类
package com.hx.serverlet;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

//让我们自己的抽象类是实现Servlet接口和ServletConfig接口
public abstract class RzGenericServlet implements Servlet,ServletConfig{

//	保存init(ServletConfig config)的config参数
private ServletConfig config;
//	构造方法
public RzGenericServlet() {
System.out.println("do my super constructer once......");
}
//具体实现init()方法
public void init(ServletConfig config) throws ServletException {
this.config=config;
System.out.println("do my super init......");
//		这里为什么还要写一个init()方法呢?这是Java中的一种叫Hook(钩子)的设计方法
//		方便真正的类做初始化,比如获取参数等
this.init();
}
//	如果该子类没有重写init()方法,则会调到父类的Init()方法
public void init(){

}
//getServletName()的具体实现
public String getServletName() {
return config.getServletName();
}
//getServletContext()的具体实现
public ServletContext getServletContext() {
return config.getServletContext();
}
//
public String getInitParameter(String name) {
return config.getInitParameter(name);
}

public Enumeration<String> getInitParameterNames() {
return this.config.getInitParameterNames();
}

public ServletConfig getServletConfig() {
return this.config;
}

//	子类可以重写该方法
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

}

public String getServletInfo() {
return null;
}

public void destroy() {

}
}


接下来,我们创建Servlet就不要像前面那样该复杂了,只要继承上面的抽象类,并重写service()方法就可以了;

package com.hx.serverlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

//继承RzGenericServlet抽象类
public class FirstRzServlet extends RzGenericServlet{

//	保存参数
private String info=null;
//	这个init()方法已经不是Servlet生命中的init()方法了,这里通过我们自己的init()方法获取web.xml中配置的参数
public void init() {
info=super.getInitParameter("str1");
System.out.println("str1:"+info);
}
//	重写servce()方法像客户端输出
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.getWriter().write("<!DOCTYPE html><html><head><body><p>"+info+"</p></body></head></html>");
}

}


不要忘记去web.xml中配置一下我们新的Servlet信息;这里就不在累赘解释了;看/my路径匹配

<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.hx.serverlet.FirstRzServlet</servlet-class>
<init-param>
<param-name>str1</param-name>
<param-value>This is my Servlet!</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/my</url-pattern>
</servlet-mapping>

打开浏览器,访问http://localhost:8080/Servlet01/my    (注意重启服务器,这里还是同一个工程下)



看下我们控制台的打印信息:



接下来我们更近一步的优化;即对service()方法进行进一步的优化;我们客户端发起的请求一般是http请求,而http请求中最常见的是GET请求和POST请求;

我们自己的HttpServlet抽象类
package com.hx.serverlet;

import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//实现系统的抽象类(当然也可以实现我们自己的抽象类)
public class MyHttpServlet extends GenericServlet{

public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
//		类型强转为HTTP请求
HttpServletRequest httpreq=(HttpServletRequest)req;
HttpServletResponse httpres=(HttpServletResponse)res;
String method=httpreq.getMethod();
//			获取请求方式(在浏览器输入地址,敲回车都是GET请求,POST请求一般是form表单的请求)
if("GET".equalsIgnoreCase(method)){
doGet(httpreq,httpres);
}
if("POST".equalsIgnoreCase(method)){
doPost(httpreq,httpres);
}

}
//	让子类重写的方法,如果子类没有重写,则抛出异常
public void doGet(HttpServletRequest httpreq,HttpServletResponse httpres)
throws ServletException, IOException {
throw new RuntimeException("不支持的请求方式");
}
//	让子类重写的方法,如果子类没有重写,则抛出异常
public void doPost(HttpServletRequest httpreq,HttpServletResponse httpres)
throws ServletException, IOException {
throw new RuntimeException("不支持的请求方式");
}

}


继承我们自己的HttpServlet类
package com.hx.serverlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyFirstHttpServlet extends MyHttpServlet{

private static final long serialVersionUID = 1L;

private String str1=null;
//	注意这是我们自己的init()方法
public void init() throws ServletException {
str1=super.getInitParameter("str2");
}
//	处理GET请求
public void doGet(HttpServletRequest httpreq,HttpServletResponse httpres)
throws ServletException, IOException {
httpres.getWriter().write("<!DOCTYPE html><html><head><body><p>"+str1+"</p></body></head></html>");
}

}


web.xml中配置我们的Servlet

<servlet>
<servlet-name>myFirstHttpServlet</servlet-name>
<servlet-class>com.hx.serverlet.MyFirstHttpServlet</servlet-class>
<init-param>
<param-name>str2</param-name>
<param-value>This is my First HttpServlet Example!</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>myFirstHttpServlet</servlet-name>
<url-pattern>/myfirst</url-pattern>
</servlet-mapping>

打开浏览器,访问http://localhost:8080/Servlet01/myfirst    (这里还是同一个工程下)



在客户端浏览器地址栏中输入地址敲回车都是GET请求,POST请求多用于form表单中;后面我们会见识到;

至此,我们自己的抽象类和HttpServlet类就实现了;其实,这里我们自己实现一遍的可以让我们更好的理解其中的原理;以后我们写Servlet,只需要继承HttpServlet类就可以 了;然后重写init()方法。doGet(),doPost()方法就可以了;

整个工程目录如下:LoginServlet请忽略;



五、总结

了解Servlet的生命周期;init,service,destory;
了解系统抽象类和HttpServlet的设计原理;
写完了Servlet千万要记得配置哟;
还是自己敲一遍收获大;一起努力奋斗!
共勉!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: