Servlet(一)

2020-02-11 23:02:00
java - servlet - web

server applet,简称servlet,是java web中的一个核心基础;tomcat是一个应用服务器,tomcat支持servlet,因此通常结合二者来使用。

servlet是一个接口,我们在使用时需要实现该接口以便我们所写的app可以被服务器识别。

最近学习了一下其基础知识,写个笔记记录一下,下一步将一边学习一边将我的博客使用servlet写一遍,看看对比起django有什么优势与劣势。

目录结构

通常的,一个servlet应该具有一下目录结构:

一个简单的示例

首先在src创建一个类包,然后再在其内创建一个ServletDemo01.java,其内放置如下代码:

package redmango;

import javax.servlet.*;
import java.io.IOException;

public class ServletDemo01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello World!!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

该类需要实现Servlet接口,并重写其对应的代码,这就是一个简单的例子,而当我们运行tomcat时仍然无法访问到该实例,是因为还缺少了web.xml的配置,因此,对应的,需要在其内添加如下代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!---新增--->
    <servlet>
        <servlet-name>demo01</servlet-name>
        <servlet-class>redmango.ServletDemo01</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>demo01</servlet-name>
        <url-pattern>/demo01</url-pattern>
    </servlet-mapping>
<!---新增--->    
</web-app>

在第一个<servlet-name>标签对内的值类似于编写js代码时的id,用于前后的识别,将<servlet>标签对和<servlet-mapping>标签对进行匹配,而<servlet>标签对内的<servlet-class>的值是我们类的路径,用于反射时的Class.forName(path)。而<url-pattern>则是我们的url路径了,这点从标签名亦能看出来。

当服务器接受到客户端的请求时,会解析请求的url,然后从我们的url获取对应的Servlet实现类,然后调用其对应的方法。

5个重写的方法

1.init,初始化方法,即在servlet被创建时会执行,仅执行一次。

2.service,服务方法,每当servlet被访问时会执行,在上例中我们访问时即打印Hello World!!。

3.destroy,销毁方法,在servlet被销毁时执行,即服务器关闭时执行,仅一次。

4.getServletConfig,获取servlet设置。

5.getServletInfo,获取servlet的信息。

而通常的,称前三个方法为servlet的生命周期。而在web.xml中可以配置servlet的创建时机。

<servlet>
    <servlet-name>demo01</servlet-name>
    <servlet-class>redmango.ServletDemo01</servlet-class>
    <!---1.其内为0或正数时,其会在服务器启动时创建;
         2.其内为负数时,其会在被访问时创建;
         3.默认为负数。--->
    <load-on-startup>-1</load-on-startup>
</servlet>

servlet3.0新特性

在3.0之后的版本都不需要配置web.xml了,因此节省了很多配置的精力,其引入注解来替代先前的xml配置。

我们需要给servlet实现类加上一个@WebServlet注解,具体内容可以查看@WebServlet该注解的内容:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
    String name() default "";

    String[] value() default {};

    String[] urlPatterns() default {};

    int loadOnStartup() default -1;

    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";
}

那么只需要以如下写法即可生效:

@WebServlet(urlPatterns = "/demo01")
//urlPatterns = 亦可以省略
public class Servlet01 implements Servlet {
    //省略代码
}

servlet提供的抽象子类

  1. HttpServlet
  2. GenericServlet

首先是GenericServlet,该类我们继承之后只需要重写service方法即可,然后是HttpServlet,该类继承了GenericServlet类,该类才是常用的抽象类,其多了doGET和doPOST两个实用的方法。

继承HttpServlet的实例如下:

@WebServlet(urlPatterns = "/demo02")
public class Servlet02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("每当有POST请求则触发该方法");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("每当有GET请求则触发该方法");
    }
}

有一点需要注意的是,当我们重写service方法时,doGET和doPOST方法即不会再生效,通过观察源码可知,在我们调用doGET或doPOST方法前,都会先调用service方法,通过service方法来获取客户端的请求方法,然后根据请求的方式调用get或post方法。

doGET、doPOST

在index.jsp同级目录下新建一个html文件,放入两个测试的表单:

<div>
    <form action="/ServletDemo01_war_exploded/demo02" method="get">
        <input type="text" placeholder="username" name="username">
        <input type="password" placeholder="password" name="password">
        <button type="submit">提交</button>
    </form>
</div>
<br>
<div>
    <form action="/ServletDemo01_war_exploded/demo02" method="post">
        <input type="text" placeholder="username" name="username">
        <input type="password" placeholder="password" name="password">
        <button type="submit">提交</button>
    </form>
</div>

然后访问对应页面即可测试我们的get和post方法是否管用。

而我们要获取请求参数的方式有四:

  1. String getParameter(String name)

  2. String[] getParameterValues(String name)

  3. Enumeration<String> getParameterNames()

  4. Map<String, String[]> getParameterMap()

在获取post的数据时,遇到中文会出现乱码,此时需要在获取参数前先设置编码为utf-8之后再获取数据,示例如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("每当有POST请求则触发该方法");
    request.setCharacterEncoding("gbk");
    System.out.println(request.getParameter("username"));
}


本文原创于HhhM的博客,转载请标明出处。



CopyRight © 2019-2020 HhhM
Power By Django & Bootstrap
已运行
粤ICP备19064649号