首页 > 学院 > 开发设计 > 正文

谷哥的小弟学后台(09)——Servlet(1)

2019-11-09 18:11:56
字体:
来源:转载
供稿:网友

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南


自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理


版权声明

本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl

Servlet简介

Servlet由Sun公司研发,它是一种运行在Web服务器中的小型java程序。 Servlet通常通过HTTP接收和响应来自Web客户端的请求。简单地说:Servlet是服务器端的小应用程序。其实,关于Servlet的作用,我们只看它的名字也能知晓一些端倪—let后缀表示”小”的含义;比如:booklet表示小册子,townlet表示小镇,lakelet表示小湖……server表示服务器;所以把-let后缀与server融合在一起就是Servlet表示服务端的小程序。嗯哼,这么说是不是就更形象和便于理解呢?


Servlet之Hello World

开发一个Servlet非常的简单,只需三个步骤:

编写一个Java类实现servlet接口修改web.xml配置文件将开发好的Java类部署至web服务器

嗯哼,我们就按照这个步骤来写个简单的示例。

package cn.com;import java.io.IOException;import javax.servlet.Servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;/** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */public class TestServlet implements Servlet { @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.PRintln("Hello Servlet"); } @Override public void destroy() { } @Override public ServletConfig getServletConfig() { return null; } @Override public String getServletInfo() { return null; } @Override public void init(ServletConfig arg0) throws ServletException { }}

在此,定义一个类实现了Servlet接口并重写其service( )方法。

<?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>testServlet</servlet-name> <servlet-class>cn.com.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/helloServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>

在WEB-INF目录下建立配置文件web.xml,内容如上所示。

由于客户端是通过URL地址访问服务器中的资源,若Servlet程序想被外界访问则必须把servlet程序映射到一个URL地址上,这个工作在正是在web.xml文件中配置完成的,详解如下所示:

<servlet>用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,它们分别用于配置Servlet的注册名称和Servlet的完整类名;请参见代码第9-12行

<servlet-mapping>用于映射已注册Servlet的对外访问路径,它包含两个子元素:<servlet-name>和<url-pattern>,它们分别用于指定Servlet的注册名称和Servlet的对外访问路径;请参见代码第15-18行

在完成这些工作,我们就可以将应用部署到Tomcat了。待程序启动,在浏览器中输入:

http://localhost:8081/TestServlet01/helloServlet

此时,控制台输出Hello Servlet。嗯哼,部署Servlet到服务端并可被外界访问的小示例就完成了。


Servlet的生命周期

Servlet不能独立运行,它的运行完全由Servlet引擎来控制和调度。

通常情况下,针对客户端的多次Servlet请求,服务器只会创建一个Servlet实例对象且将其驻留在内存中为后续的其它请求服务,直至web容器退出Servlet实例对象才会被销毁。

所以,可将Servlet的生命周期概括为这么几个阶段:实例化,初始化,服务,销毁这几个阶段。

请看如下代码:

package cn.com;import java.io.IOException;import javax.servlet.Servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;/** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */public class TestServlet implements Servlet { public TestServlet( ) { System.out.println("TestServlet( )"); } @Override public void init(ServletConfig arg0) throws ServletException { System.out.println("init( )"); } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("service( )"); } @Override public void destroy() { System.out.println("destroy( )"); } @Override public ServletConfig getServletConfig() { return null; } @Override public String getServletInfo() { return null; }}

现在,结合这个示例一起分析Servlet的生命周期: 所以,可将Servlet的生命周期概括为这么几个阶段:实例化,初始化,服务,销毁这几个阶段。 代码解析如下:

Servlet的实例化,请参照代码第15-17行 在该过程中调用Servlet的构造方法Servlet的初始化,请参照代码第19-22行 在该过程中会调用Servlet的init( )方法Servlet的服务,请参照代码第25-28行 在该过程中会调用Servlet的service( )方法Servlet的销毁,请参照代码第30-33行 在该过程中会调用Servlet的destroy( )方法

在Servlet的整个生命周期内,Servlet的构造方法和init()方法只会被调用一次;同理Servlet的destroy()也只执行一次。但对于客户端的每次访问都会导致Servlet引擎调用一次servlet的service()方法。


Servlet的实现方式

常见的Servlet实现方式有三种:实现Servlet接口、继承GenericServlet、继承HttpServlet。现在分别介绍如下所示:

Servlet的第一种实现方式:实现Servlet接口

在该方式下,需要根据业务实现Servlet接口提供的方法,尤其是service( )方法。详情请参照刚才的示例,不再赘述。

Servlet的第二种实现方式:继承GenericServlet

GenericServlet实现了Servlet接口和ServletConfig接口。GenericServlet提供了生命周期方法init()和destroy()以及ServletConfig接口中的方法的简单版本,所以它使编写 Servlet变得更容易。故,若继承GenericServlet一般情况下我们只需重写service()方法即可。

Servlet的第三种实现方式:继承HttpServlet

HttpServlet继承自GenericServlet且实现了Servlet接口和ServletConfig接口。HttpServlet在实现Servlet接口时,覆写了service()方法,该方法会自动判断用户的请求方式,若为GET请求则调用HttpServlet的doGet()方法,若为Post请求则调用doPost()方法,诸如此类。因此,开发人员在编写Servlet时,通常只需要覆写doGet()或doPost()方法而不用覆写service方法()。故,在实际开发中编写Servlet时,通常情况下,应继承HttpServlet而避免直接去实现Servlet接口。

请看如下示例:

package cn.com;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */public class TestHttpServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("---> doGet()"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("---> doPost()"); }}

在该示例中TestHttpServlet继承自HttpServlet,且覆写了doGet()和doPost()方法。当有Get或者Post的请求到达时就会调用doGet()或者doPost()。

当然,这三种方式都需要都需要我们在web.xml里面配置Servlet。在之前我们已经介绍了Servlet简单的配置,在此再补充一些细节。

同一个Servlet可以被映射到多个路径上,即多个<servlet-mapping>元素的<servlet-name>的设置值可以是同一个Servlet的注册名。可用*.扩展名的形式配置url-pattern,其中*表示任意字符串;比如配置<url-pattern>*.do</url-pattern>时可用任意字符串.do组成的url访问该Servlet可用/*配置url-pattern,其中*表示任意字符串;比如配置<url-pattern>/*</url-pattern>时可用/任意字符串组成的url访问该Servlet。

ServletConfig

在Servlet的配置文件web.xml中可使用<init-param>为Servlet配置初始化参数。当servlet配置了初始化参数后Web容器在创建Servlet实例对象时会自动将这些初始化参数封装到ServletConfig对象中并在调用servlet的init()方法时将ServletConfig对象传递给servlet。所以,可通过ServletConfig对象得到当前Servlet的初始化参数信息。

请看如下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>testServlet</servlet-name> <servlet-class>cn.com.TestServlet</servlet-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/helloServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>

在此web.xml配置了编码方式(encoding)为UTF-8

/** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */public class TestServlet implements Servlet { private ServletConfig mServletConfig; public TestServlet( ) { } @Override public void init(ServletConfig servletConfig) throws ServletException { mServletConfig=servletConfig; String encoding=mServletConfig.getInitParameter("encoding"); System.out.println("---> encoding="+encoding); }}

在该Servlet中可从init()方法的输入参数中获取到ServletConfig再利用其getInitParameter()方法获取配置信息即可。

GenericServlet实现了Servlet接口和ServletConfig接口,所以在GenericServlet中利用:

this.getServletConfig().getInitParameter(“encoding”);

或者

this.getInitParameter(“encoding”);

这两种方式获取配置信息。


ServletContext

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。在此介绍ServletContext几种常用的应用。

利用ServletContext实现多个Servlet共享数据

public void setAttribute(String name, Object object)

利用setAttribute()方法保存数据

public Object getAttribute(String name)

利用getAttribute()方法获取数据

public void removeAttribute(String name)

利用removeAttribute()方法移除数据

利用ServletContext获取全局配置信息

<context-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value></context-param>

在web.xml中配置如上全局信息

ServletContext servletContext=mServletConfig.getServletContext();String encoding=servletContext.getInitParameter("encoding");

在Servlet可通过ServletContext获取全局配置信息

利用ServletContext获取获取资源路径

public String getRealPath(String path)

可使用ServletContext的getRealPath(path)方法获取到当前应用任何位置的任何资源,其中参数path路径一般以/WEB-INF开头,斜杠/就表示了当前应用。为什么斜杠/后就是WEB-INF呢?其实之前我们也提到了:应用部署后所有的东西都在WEB-INF路径下。我们也可以打开……tomcat/webapps/应用名/WEB-INF/即可看到与应用有关的所有资源。

现在我们在src的根目录下建立test.properties文件,在该文件中只写入一行简单的测试数据:

username=xiaozemaliya

现在,我们在Servlet中获取该username,如下所示:

mServletConfig=servletConfig;ServletContext servletContext=mServletConfig.getServletContext();String path=servletContext.getRealPath("/WEB-INF/classes/test.properties");Properties properties=new Properties();properties.load(new FileInputStream(path));String name=(String) properties.getProperty("username");

在此,再次提醒:src中的代码编译后的class文件存放于……tomcat/webapps/应用名/WEB-INF/classes文件夹中。

利用ServletContext实现Servlet的转发

mServletConfig=servletConfig;ServletContext servletContext=mServletConfig.getServletContext();RequestDispatcher requestDispatcher=servletContext.getRequestDispatcher(path);requestDispatcher.forward(request, response);

关于Servlet的转发,在此仅仅作一个非常简单的引入,我们会在后续的学习中进一步介绍。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表