Java后台之路(08)-Servlet

终于开始触摸servlet了,刚开始心里还有些小激动,但是看了一堆资料之后整个人是懵逼的,云里雾里,在请教了Java同事之后再加上自己的理解,我可能大致搞清了servlet是个什么东东,好吧,可能我比较愚钝吧。

servlet包参照


servlet简介

servlet是由sun公司研发的运行Web服务器中的小型java程序。

它是干什么的呢?它是个中间层,它一头用来接收客户端(浏览器/移动端)的Http请求,另一头连接服务器的数据。

这里写图片描述

  • 读取客户端发送来的数据;
  • 处理客户端发送来的数据并对数据进行处理,这个过程可能会访问数据库;
  • 将处理结果发送给客户端。

我们来举个有意思的例子,Servlet就是数据的大管家,当吃瓜群众(客户端)想了解一些事情时,就会将问题提给Servlet,比如小明说我想看某某类型的片片,他将想法告诉了Servlet,Servlet听到后会意一笑立马就去茫茫数据库帮小明找片片去了,不一会Servlet从数据库中拿到了片片,然后Servlet把片片给了等候已久的小明,小明迫不及待打开了片片然后兴致勃勃地看起了喜洋洋。

那么下面来先来了解一下Servlet的生命周期。


servlet生命周期

Servlet从创建到销毁是这样的:

  • init(),进行初始化;
  • service(),处理客户端的请求;
  • destroy(),终止;
  • Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

下面来详细地讨论一下生命周期的各个方法吧。

1. init()方法

一次性方法,它只有在Servlet被创建的时候被调用一次,往后再有请求来临时不会再被调用。

public void init() throws ServletException {
  // 初始化代码...
}

2. service()方法

是请求来临执行的主要方法,Web服务器会调用service()来处理客户端的请求,并把响应返回给客户端。

每次服务器接收到一个Servlet请求时,服务器会产生一个新的线程并调用服务,service()检查HTTP请求的类型(get,post,put,delete等),并在适当的时候调用对应的doGet(),doPost(),doPut(),doDelete()方法。

serive()由Web服务调用,所以我们不需要对service()进行任何处理,只需要根据需要重写doGet(),doPost()等方法即可。

public void service(ServletRequest request, 
                    ServletResponse response) 
      throws ServletException, IOException{
}

3. doGet()方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,
                  HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

4. doPost()方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,
                   HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

5. destory()方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

public void destroy() {
    // 终止化代码...
  }

servlet简单实例

通过上面的了解,我们对Servlet有了一定的认识,那么,接下来就来创建一个简单Servlet,这个HelloServlet类的作用就是将客户端传递的参数打印出来。

Servlet的步骤:

  • 新建Servlet类;
  • 修改web.xml配置;
  • 将该类部署到Tomcat上。

1. 新建HelloServlet

public class HelloServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("init()");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        super.service(req, resp);
        System.out.println("service()");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doGet()");
        System.out.println(req.getParameter("name"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
            System.out.println("doPost()");
    }

    @Override
    public void destroy() {
        System.out.println("destroy()");
    }

}

2. 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">
  <display-name></display-name>

  <!-- 用来声明servlet -->    
  <!-- servlet-name声明一个别名 -->
  <!-- servlset-class对应的servlet类路径 -->
  <servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.servlet.HelloServlet</servlet-class>
  </servlet>

  <!-- 声明servlet的url地址 -->
  <!-- servlet-name别名,就是servlet声明中的别名 -->
  <!-- url-pattern如何通过url访问 -->
  <!-- url: ip:端口号/项目名称/url-pattern -->
  <!-- url: localhost:8080/MyServlet/servlet/HelloServlet -->
  <servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <url-pattern>/servlet/HelloServlet</url-pattern>
  </servlet-mapping>    

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

web是用来干嘛的?其实我们可以将其理解为一个注册文件,将我们所创建的servlet在此处声明。具体如何声明去看上面的代码注释。

3. Tomcat

如何配置自行百度,重启成功后,我们在浏览器

localhost:8080/MyServlet/servlet/HelloServlet?name=戚继光

此时在控制台输出:戚继光。

我在这中间遇到了中文乱码的问题,该如何解决呢?参照一下步骤吧。

1.在web.xml中增设全局设置。

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

2.在tomcat的安装目录下找到”/conf/server.xml”修改。

// 修改前
<Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />

// 修改后
<Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" 
    URIEncoding="UTF-8" />

重启tomcat就发现中文不在乱码了。


Servlet的实现方式

常见的三种方式:

  • 实现Servlet接口;
  • 继承GenericServlet类;
  • 继承HttpServlet类;

1. 实现Servlet接口

该方式下,需要根据业务实现Servlet接口提供的方法,尤其是service( )方法。

2. 继承GenericServlet

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

3. 继承HttpServlet

HttpServlet继承自GenericServlet且实现了Servlet接口和ServletConfig接口。HttpServlet在实现Servlet接口时,覆写了service()方法,该方法会自动判断用户的请求方式,若为GET请求则调用HttpServlet的doGet()方法,若为Post请求则调用doPost()方法,诸如此类。

因此,开发人员在编写Servlet时,通常只需要覆写doGet()或doPost()方法而不用覆写service方法()。故,在实际开发中编写Servlet时,通常情况下,应继承HttpServlet而避免直接去实现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中设置了encoding属性。

<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.servlet.HelloServlet</servlet-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</servlet>

在HelloServlet.class中获取属性

public void init(ServletConfig servletConfig) throws ServletException {
    String encoding=servletConfig.getInitParameter("encoding");
    System.out.println("---> encoding="+encoding);
}

ServletContext

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

1. 不同Servlet间共享数据

// 保存数据
public void setAttribute(String name, Object object);

// 获取数据
public Object getAttribute(String name);

// 删除数据
public void removeAttribute(String name);

2. 获取全局配置信息

我们在web.xml中设置全局的编码格式。

// 配置属性
<context-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
</context-param>

// 获取属性
ServletContext servletContext=mServletConfig.getServletContext();
String encoding=servletContext.getInitParameter("encoding");

3. ServletContext获取资源路径

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

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

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

import java.util.Properties;

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文件夹中。

4. 实现Servlet的转发

简单的例子,后续会继续探讨。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值