Web基础之与Servlet的邂逅

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千万要记得配置哟;
还是自己敲一遍收获大;一起努力奋斗!
共勉!


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值