【Servlet03】Servlet简单使用

1 创建Web工程

Idea创建Web工程的方式很多,采用先创建一个空项目,再往项目中添加web模块的方法创建。

选择创建空项目:

弹出的框可以选择ok,也可以选择cancel,此处选择cancel:

创建模块:

配置正确的环境,包括jdk、Tomcat:

写入模块名:

点击Finish完成创建,对项目结构作简单介绍:

  • src:Java源代码路径;

  • web:前端页面代码;

    • WEB-INF:安全文件夹(目前不使用,后期使用);

      • web.xml文件:是整个模块的配置文件,核心配置文件;

    • index.jsp:动态页面、

观察External Libraries,发现比JavaSE项目多了一个库,这个库来自Tomcat的lib文件夹:

2 编写Servlet程序

Serlvet是一种特殊的java类,全称是Server Applet是一种运行在服务器端的Java程序。

2.1 自定义类并继承HttpServlet

public class HelloServlet extends HttpServlet {
}

2.2 重写doPost/doGet

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("execute doGet......");
    }

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

重写完毕以后,Servlet会根据请求类型自动调用doPost或doGet方法来处理请求;

2.3 向Tomcat注册Servlet

有两种方法向Tomcat注册Servlet:web.xml配置文件和注解方法,此处先介绍使用web.xml方法。

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>helloServelt</servlet-name>
        <servlet-class>com.jackqiang.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServelt</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
  • <servlet>:配置servlet类

    • <servlet-name>helloServelt</servlet-name>:自定义一个名称表示一个Servlet类,该名称在整个的web.xml文件中不能重复

    • <servlet-class>com.bjpowernode.servlet_el.HelloWorldServlet</servlet-class>:填入Servlet类的位置(包名+类名),目的是通过类的全限定名反射实例化该类;

  • <servlet-mapping>:配置Servlet的映射信息

    • <servlet-name>helloServelt</servlet-name>:填入要映射的Servlet名称,和上一个<servlet-name>保持一致;

    • <url-pattern>/hello</url-patter:配置请求名称,格式:/ + 请求名称;是Servlet的执行入口;

3 执行Servlet

编写一个html页面,加入一个超链接以发送GET请求,加入表单以发送POST请求:

<a href="hello">发送一个GET请求</a><br>
<form action="hello" method="post">
    <input type="submit" value="发送一个POST请求">
</form>

浏览器地址栏访问http://localhost:8080/hello.html,分别点击发送GET和POST请求:

此外还可以配置hello.html为应用程序的第一个页面,称之为欢迎页面(工程中默认情况下是index.jsp):

web.xml:

<welcome-file-list>
    <welcome-file>/hello.html</welcome-file>
</welcome-file-list>

4 Servlet的特性

4.1 单例模式

Servlet类是单例模式的类,即Servlet类的对象最多只有一个;Servlet创建对象会调用无参构造方法,于是可以修改我们的Servlet,添加一个无参构造查看Servlet的创建过程:

public class HelloServlet extends HttpServlet {
    public HelloServlet() {
        System.out.println("调用了无参构造......");
    }

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

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

重启服务器,访问Servlet:

两次请求只调用了一次构造,因而只有一个实例。

4.2 实例化的时间

Servlet在默认情况下是该类第一次被访问时,会创建一个唯一的对象,这就导致了如果资源过多,第一次访问的执行效率会明显比后续的访问要低的多,可以通过配置调整Servlet实例化的时间为服务器启动时(懒汉式→饿汉式):

<?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>helloServelt</servlet-name>
        <servlet-class>com.jackqiang.HelloServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServelt</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
  • <load-on-startup>1</load-on-startup>:添加标签调整Serlvet实例化时间为服务器启动时,标签内需要添加一个正整数表示优先级,正整数数字越小,实例化的时间越早;

配置完毕以后重启服务器,可以看到尽管此时没有访问Servlet,但其已经被实例化了:

4.3 请求名称

一个Servlet可以拥有多个请求名称,换言之,一个<Servlet>标签可以对应多个<servlet-mapping>标签:

<?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>helloServelt</servlet-name>
        <servlet-class>com.jackqiang.HelloServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServelt</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>helloServelt</servlet-name>
        <url-pattern>/hello-new</url-pattern>
    </servlet-mapping>
</web-app>

重启服务器,浏览器分别输入url http://localhost:8080/hello-newhttp://localhost:8080/hello-new

可以看到,两个不同的请求名称均可以访问到我们的Servlet

5 基于注解的Servlet配置

前面介绍过基于web.xml的Servlet配置,但是其有两大缺点:

  • 配置繁琐;

  • 如果需要配置的类特别多,web.xml会相当臃肿,服务器每次读写增加负担;

于是需要转变Servlet的配置方法,先采用注解的方式配置。

Servlet的配置注解是@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 "";
}

Servlet注解@WebServlet定义在Servlet类名之上,有几个配置属性需要特别注意:

  • name:Servlet名称,相当于xml文件配置中的<servlet-name>标签,如果没有配置默认使用全类名(包名+类名);

  • urlPatterns:请求名称,相当于xml文件配置中的<url-pattern>标签;

  • loadOnStartup:类的实例化时间调整,相当于xml文件配置中的<load-on-startup>标签;

  • initParams:初始化参数列表,相当于xml文件配置中的<init-param>标签;

例如有以下Servlet:

@WebServlet(name = "annoServlet",
        urlPatterns = {"/anno1", "/anno2"},
        loadOnStartup = 1,
        initParams = {
                @WebInitParam(name = "key1", value = "value1"),
                @WebInitParam(name = "key2", value = "value2")
        }
)
public class AnnotationServlet extends HttpServlet {
    public AnnotationServlet() {
        System.out.println("execute constructor in AnnotationServlet");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("execute doGet in AnnotationServlet");
        String servletName = this.getServletName();
        String key1 = this.getInitParameter("key1");
        String key2 = this.getInitParameter("key2");
        System.out.println("servletName = " + servletName);
        System.out.println("key1 = " + key1);
        System.out.println("key2 = " + key2);
    }
}

不需要配置web.xml文件即可访问:

当然,由于一般nameloadOnStartupinitParams这三者一般不会做特殊要求,可以省略,并且由于urlPatterns一般只有一个,所以以上注解也可以简写为:

@WebServlet("/anno")
public class AnnotationServlet extends HttpServlet {

重启服务器,访问查看结果:

版权声明:
作者:jackqiang
链接:http://www.jackqiang.com/javaweb/server/servlet/2103/simple_servlet/
来源:JackQiang's
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录