Web基础之与Servlet的邂逅

来源:互联网 发布:云计算企业投融资政策 编辑:程序博客网 时间:2024/05/16 05:48
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-8res.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千万要记得配置哟;
还是自己敲一遍收获大;一起努力奋斗!
共勉!


0 0
原创粉丝点击