Servlet笔记

2020-04-28  本文已影响0人  憨憨二师兄

Tomcat 与 Servelet概述

软件结构发展史

桌面应用时代

桌面应用俗称单机应用,软件以及所有数据都保存在电脑本地硬盘中;优点为易于使用,结构简单;缺点为数据难以共享,安全性差,更新不及时

联机时代

C/S架构,指的是客户端和服务器架构;数据保存在服务器上,不需要保存在本机电脑;优点是数据方便共享并且安全性高;缺点是必须要安装客户端,升级与维护比较困难。C/S结构的典型应用例如:QQ。

互联网时代

B/S架构,即:浏览器和服务器的架构模式。通过浏览器加载服务端上面的内容,以网页的形式显示给用户,B/S架构的优点为:开发简单,无需安装客户端,数据易于共享;缺点为:相较于C/S模式,B/S模式的执行速度与用户体验较弱。B/S的典型应用有很多,浏览器能浏览到的各个网站都是B/S模式应用。

B/S模式执行流程


关于B/S模式执行流程,可以看我的文章 浅谈HTTP

请求与响应

客户端即是访问者,服务器即是被访问的对象。
或者可以简单地理解为,一个是浏览网页的,一个是提供网页服务给浏览者浏览的。
那么客户端从输入URL 到 页面的呈现 到底发生了什么呢?
这个问题在本文不会给出详细的解答。但是我们可以知道客户端和服务器之间一定存在着某种"沟通"。
这种沟通就是请求(Request)和 响应(Response)
在我们输入了URL之后,浏览器给服务器发送了一个request,web服务器接收到request后进行处理,然后返回给浏览器一个response,浏览器通过解析response中的HTML,我们就看到网页了。关于请求与相应的具体部分,依然可以参照我的文章 浅谈HTTP

Servlet

Apache Tomcat

安装 Apache Tomcat

下载链接
进入官网,下载自己电脑系统匹配的版本即可,要确保安装了匹配的jdk,下载完毕后,进入下载目录的bin目录下,运行startup命令,如果出现

The CATALINA_HOME environment variable is not defined correctly

这样的报错信息,说明没有设置好JAVA_HOME
如果出现

command is not defined

那么就要看你的startup命令是否是在bin目录下运行的,在没有设置好CATALINA_HOME之前,startup命令只能在bin目录下运行。
命令运行成功后,会弹出一个黑色窗口,最后显示:


在浏览器上输入http://localhost:8080/ 会显示Apache Tomcat的页面。

如果需要关闭服务器,只需要敲入CTRL + C 即可退出

IntelliJ IDEA 整合Tomcat

关于怎样使用idea整合Tomcat的教程在网上一大堆
例如:
Kudō Shin-ichi 这位同学的文章 IntelliJ IDEA整合Tomcat服务器
这里就不再赘述。

Servlet创建与生命周期

第一个Servlet程序

在idea整合好Tomcat,创建一个web项目后,开始写第一个Servlet程序:

FirstServlet 类

package servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class FirstServlet extends HttpServlet {

    // idea 快捷键 快速生成 ctrl + O
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String name = req.getParameter("name");
        String html = "<h1 style='color:red'>hi, " + name + "</h1><hr/>";
        PrintWriter out = resp.getWriter();
        out.println(html);
    }
}

在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的别名 -->
        <servlet-name>firstServlet</servlet-name>
        <servlet-class>servlet.FirstServlet</servlet-class>
    </servlet>

    <!--servlet的映射-->
    <servlet-mapping>
        <servlet-name>firstServlet</servlet-name>
        <url-pattern>/hi</url-pattern>
    </servlet-mapping>
</web-app>

运行程序,输入URL:http://localhost:8080/first_servlet/hi?name=dobbykim
页面显示如下:


该程序的执行流程如下:
当我们输入url:http://localhost:8080/first_servlet/hi?name=dobbykim的时候,浏览器向Tomcat服务器发起了"请求"。在Servlet程序内部,首先会在配置文件web.xml中去找servlet-mapping,找到了对应的跳转地址,通过servlet-name找到了对应的servlet-class。通过servlet-class,服务器找到了FirstServlet类;在FirstServlet类中,一个请求获取到的参数,也就是本示例中的name=dobbykim会被写好的页面一同由PrintWriter对象响应回浏览器,返还给客户,呈现出页面。

Java Web标准工程结构

组织结构 描述
tocat 安装目录/webapps/ Tomcat应用根目录
/web应用目录/ Java Web应用目录
/web应用目录/index.html or .jsp 默认首页
/WEB-INF WEB应用的安全目录,用于存放配置文件
/WEB-INF/web.xml web.xml是"部署描述符文件",是该web项目核心配置文件
/WEB-INF/classes 存放编译后的classes文件
/WEB-INF/lib 用于存放web应用依赖的jar文件
/META-INF/MANIFEST.MF 包含Web应用的版本等信息

Servlet开发与基本配置

Servlet开发步骤

示例:使用Servlet计算n以内自然数的累加和,并输出,参数n通过url地址进行传递,示例程序如下:
ComputerServlet类

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ComputerServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String nString = req.getParameter("n");
        int n = Integer.parseInt(nString);
        int sum = ((n + 1) * n) / 2;
        String html = "<p>" + sum + "</p>";
        PrintWriter out = resp.getWriter();
        out.println(html);
    }
}

web.xml中的配置如下:

    <servlet>
        <servlet-name>ComputerServlet</servlet-name>
        <servlet-class>ComputerServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ComputerServlet</servlet-name>
        <url-pattern>/ComputerServlet</url-pattern>
    </servlet-mapping>

通过在URL中传参即可动态改变网页中显示的内容:


请求参数的发送与接收

请求参数
Servlet接收请求参数

示例如下:
在web目录下,student.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学员信息登记表</title>
</head>
<body>
    <h1>学员信息登记表</h1>
    <form action="/FirstServlet/sample" method="get" >
        姓名:<input name="name"/>
        <br/>
        电话:<input name="mobile"/>
        <br/>
        性别:
        <select name="sex" style="width:100px;padding:5px;">
            <option value="male" >男</option>
            <option value="female">女</option>
        </select>
        <br/>
        特长:
        <input type="checkbox" name="spec" value="English"/>英语
        <input type="checkbox" name="spec" value="Program"/>编程
        <input type="checkbox" name="spec" value="Speech"/>演讲
        <input type="checkbox" name="spec" value="Swimming"/>游泳
        <br/>
        <input type="submit" value="提交">
        <br/>
    </form>
</body>
</html>

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>sample</servlet-name>
        <servlet-class>SampleServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sample</servlet-name>
        <url-pattern>/sample</url-pattern>
    </servlet-mapping>
</web-app>

SampleServlet 类:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class SampleServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String mobile = req.getParameter("mobile");
        String sex = req.getParameter("sex");
        String[] specs = req.getParameterValues("spec");

        PrintWriter out = resp.getWriter();
        out.println("<h1>name:" + name + "</h1>");
        out.println("<h1>mobile:" + mobile + "</h1>");
        out.println("<h1>sex:" + sex + "</h1>");
        for (int i = 0; i < specs.length; i++) {
            out.println("<h2>spec:" + specs[i] + "</h2>");
        }
    }
}

表单填写如下:



submit后,跳转页面如下:


Get与Post请求

Get与Post处理方式
Get与Post应用场景

Get与Post示例程序:
RequestMethodServlet类:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestMethodServlet extends HttpServlet {

    // 处理 get 请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        resp.getWriter().println("<h1 style='color:green'>" + name + "</h1>");
    }

    // 处理 post 请求

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        resp.getWriter().println("<h1 style='color:red'>" + name + "</h1>");
    }
}

使用get方式提交表单时:



使用post方式提交表单:



并且可以看到提交的请求体中有用户的信息:

Servlet的生命周期

示例程序如下:

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class FirstServlet extends HttpServlet {

    public FirstServlet() {
        System.out.println("正在创建FirstServlet对象");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("正在初始化FirstServlet对象");
    }



    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String html = "<h1 style='color:red'>" + name + "</h1>";
        PrintWriter out = resp.getWriter();
        System.out.println("service提供服务");
        out.println(html);
    }

    @Override
    public void destroy() {
        System.out.println("正在销毁FirstServlet对象");
    }
}

输入URL:



可以看到输出发生了变化:



改变URL中的Parameter:

控制台输出为:



可以看到,并没有重新创建Servlet对象,而是一直由一个Servlet对象提供service服务;当我们重启Servlet时候,Servlet销毁:

使用注解配置Servlet

注解简化配置

示例程序如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/annotation")
public class AnnotationServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("I'am AnnotationServlet");
    }
}

在Servlet类前面添加@WebServlet注解,括号里面是映射地址,这样就可以通过注解简化在web.xml里面的配置

启动时加载Servlet

对于启动时加载Servlet同样可以使用两种方式

示例程序:
Process1:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class Process1 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("执行process1");
    }
}

Process1在web.xml中配置:

    <servlet>
        <servlet-name>process1</servlet-name>
        <servlet-class>Process1</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>process1</servlet-name>
        <url-pattern>/process1</url-pattern>
    </servlet-mapping>

Process2:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

@WebServlet(urlPatterns = "/process2",loadOnStartup = 1)
public class Process2 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("执行process2");
    }
}

在控制台输出结果如下:



通过在web.xml中设置load-on-startup或者通过注解进行配置可以在启动时加载在工作中常用于系统的预处理,例如示例程序中,process1和process2是预处理需要执行的程序,我们可以在启动Tomcat时,加载Servlet类。

上一篇下一篇

猜你喜欢

热点阅读