目录

一、什么是Servlet

二、使用IDEA创建一个servlet程序全过程图解:

关于映射路径:

三、servlet的执行流程:

3.1 引入概念  容器

什么是容器:

容器可以用来干嘛:

3.2 Servlet的执行流程:

四、http协议:

4.1 常见的请求头:

4.2常见的响应头:

4.3 通过servlet获取http请求信息:

4.3.1 获取请求行的信息

4.3.2 获取请求头基本信息

4.3.3 获取表单参数的值

4.3.4  非法链接

4.4 通过servlet获取http响应信息

4.4.1 重定向 

4.4.2  定时刷新

4.4.3  设置响应类型

4.4.4  以下载的格式打开


一、什么是Servlet

Servlet是Java Servlet的简称。Java Servlet 是运行在web服务器上的应用程序,简单来说,其实它就是一个类,能够被web服务器解析的一类。

总的来说,servlet的功能主要就是干两件事:

  • 接收客户端的请求;
  • 响应服务器的响应

servlet遵循的是网络协议中的 http协议 ;

刚开始可以这么理解servlet的作用 :

二、使用IDEA创建一个servlet程序全过程图解:

首先,在官网下载一个Tomcat:

解压后,进入里面的bin目录,找到对应的启动文件:

windows下的启动文件是startup.bat

linux下的启动文件为startup.sh:

启动一下,保证可以运行(不会闪退):

 

如果闪退的话,可能是你没有配JAVA_HOME环境变量(网上有步骤),或者下的Tomcat的版本有问题也可能导致闪退。

然后就可以在IDEA下手动创建一个Servlet程序:

首先,创建一个空的maven项目

然后步骤就是正常创建项目的步骤...

然后在pom文件中将打包设置为war包

接下来补全目录结构:web项目的目录结构为:在main下面创建一个webapp,在webapp下面创建目录WEB-INF,在WEB-INF中创建一个web.xml文件:

在补一下web.xml文件中的内容(直接在Tomcat安装目录里的WEB-INF里面的web.xml文件中将下面部分的内容复制过来在最后补一个</webapp>就行了,如下图):

或者直接复制这个:

<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"
         metadata-complete="true">
    <!--配置网站信息-->
    
</web-app>

web.xml是servlet的配置文件,Servlate里面的全局参数,监听器,过滤器都是在这里面,所以非常重要,怎么用后面再说!!!

然后再pom文件中导入Servlet需要的jar包:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

然后在:Run -> Edit Configurations--> 点左上角的 + -->然后在下拉框找到Tomcat server  --> 选择Local(表示本地) --> 然后name里面自己填一个名字,在Application server里面找到自己下载的Tomcat,这时右下角如果有一个红色感叹号的警告,点fix,选择 xxxWar,然后点击应用,并确定,这样我们的Tomcat就算是配好了,具体过程如下图:

 

确定之后:

然后点apply 然后OK。到这里我们就可以创建Servlet项目了。

这时候在我们自己的包下创建一个servlet:

这个时候如果 左下角那个对号点不了,就重新导一下maven项目,如下图:

创建好了之后,web.xml中会报错,如下:

现在,要在web.xml中写上:

关于映射路径:

作用:在运行servlet的时候,首先它就会来web.xml文件中找对应的映射路径,找到了才可以运行

写法:

  • 精确匹配:/xxx
  1. /hello  ——> http://localhost:8080/hello
  2. /fei/hello  ——> http://localhost:8080/fei/hello
  • 模糊匹配 
  1. /* 任意路径
  2. *,html 前面必须是任意路径,但是后面必须以指定后缀名结束
  • 最后:要注意不能即出现精确匹配又出现模糊匹配(例如:/hello/* 就是一种错误写法【前面是精确匹配,后面是模糊匹配】)
  • 也不能只写一个 / ,因为在Tomcat的web.xml中的缺省路径就是一个 / ,如果在当前的wen.xml中找不到对应的动态资源文件,就会使Tomcat中的缺省路径介入程序。

优先级比较:

  • 精确匹配的优先级高于模糊匹配,在模糊匹配中,任意路径的优先级高于以指定后缀结尾的路径

再来看看新建的这个servlet的类,里面默认覆写两个方法:

  • doGet(requset, response)   表示 以get方式提交信息
  • doPost(requset, response)   表示已post方式提交信息

一般情况下,我们常用doGet(), 在doPost中直接调用doGet就可以了。

简单的使用案例:第一个servlet

点击运行之后,由于我们这里没有配主页,进来之后再浏览器会报错(404 ),不过对于练习使用案例来说并不影响什么。

这时候在地址栏输入刚刚在web.xml中配置的:

回车之后就有东西了:

那么要在浏览器输入中文,要先设置编码为utf-8:

其实上面的setContentType中的ContentType就是http协议请求头中的东西,我们可以在刚刚那个界面按F12(我用的浏览器是按F12,别的不清楚)就可以看到http 请求头 / 响应头 中的详细信息:

从上面的方法我们可以看出,servlet好像和我们之前写的程序不太一样,它里面main方法,但是也可以执行,那么servlet到底是怎么执行的呢???

三、servlet的执行流程:

3.1 引入概念  容器

什么是容器:

从上面的步骤来看,我们会发现servlet和我们平时写的程序不太一样,因为它没有main方法,也可以执行,但是在以前不是说main方法是程序执行的入口吗,那为啥servlet就可以例外了呢;因为servlet程序受控于另外一个java应用,这个应用就是容器,servlet程序就是在这个叫容器的东西里面运行的。在刚开始我们说的要下载的Tomcat,就是常见的容器中的一种,常见的还有 Jetty。

容器可以用来干嘛:

容器是用来管理和运行servlet的

  • 通信支持:利用容器提供的方法,能够轻松让servlet与web服务器对话,无需自己建立ServerSocket,监听接口,吃昂见流等操作。容器知道自己与web服务器之间的协议,所有Servlet不必担心Web服务器Web服务器(如 Apache,Nginx)与自己的Web之间的API,只需要考虑实现业务即可。
  • 生命周期管理:容器控制着Servlet的生死。它会负责加载类,实例化,和初始化Servlet,调用Servlet的方法,并使Servlet实例能够被垃圾回收。有了容器的控制,开发者就不需要考虑过多的资源管理。
  • 多线程支持:容器会自动的为它接收到的每一个Servlet请求创建一个新的java线程。针对客户端请求,如果Servlet已经运行了完全相应的HTTP服务方法,该线程就会结束。这些并不意味着开发者不用考虑线程安全问题,它同样会遇到同步问题。不过,由于服务器来创建和管理多线程来处理多个请求,开发者同样会省去不少的工作。
  • 声明方式实现安全:利用容器,可以使用XML部署描述文件来配置安全性(Servlet3,0开始可以使用注解方式来描述),而不必将其硬编码写到Servlet或其他类中。
  • JSP支持:容器可以将JSP代码翻译成Java代码。

3.2 Servlet的执行流程:

  1. 在浏览器地址栏输入:http://localhost:8080/hello ( 以 /hello 为例 ),接下来,它会在网站配置web.xml中找到是否存在一个映射 url-pattern:/hello
  2. 如果找到,找对应的Servlet名称:HelloServlet,在配置信息中找是否存在一个同名的Servlet
  3. 通过反射获取到HelloServlet.class类对象
  4. 反射机制获取到里面的无参构造/成员方法/ ---->由Tomcat解析里面的内容
  5. 使用HTTPServletResponse响应给用户内容
  6. 如果第二步中在web.xml中没有找到对应的映射路径,就在webapp下寻找静态资源,如果还没有找到,就报404错误。

四、http协议:

4.1 常见的请求头:

 

Accept浏览器接受的数据类型
Accept-Charset浏览器接受数据编码格式
Accept-Encoding浏览器接受的数据压缩格式
Accept-Language浏览器接受的语言  
Host请求发出的主机和端口(必须)
If-Modified-Since浏览器缓存的最后修改时间
Referer当前请求来自于哪里 (防止非法链接)
User-Agent当前用户的浏览器类型
Cookie浏览器保存的cookie数据(会话管理)
Connection

浏览器和服务器的连接状态。

close:关闭。keep-alive:保持连接

Date请求发出的时间

 

 

 

 

 

 

 

 

 

 

 

 

4.2常见的响应头:

Location重定向的地址。结合302状态使用完成重定向的效果
Server服务器的类型
Content-Encoding服务器发送给浏览器的数据压缩格式
Content-Length服务器发送给浏览器的数据长度
Content-Language服务器支持的语言
Content-Type服务器发送给浏览器的数据类型和数据编码格式
Last-Modified服务器资源的最后修改时间
Refresh定时刷新或者每隔n秒天真资源
Content-Disposition以下载方式打开资源
Set-Cookie服务器发送给浏览器的cookie数据
Expires(-1)

通知浏览器不使用缓存

Connection

(close/Keep-Alive)

连接状态
Date响应发出时间

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4.3 通过servlet获取http请求信息:

4.3.1 获取请求行的信息

请求行:请求行由3部分组成

  • 请求方法:get/post/...
  • 资源的uri
    • uri 和 url不一样 ,url 是 uri 的子集
    • uri是映射路径  :/myFirstServlet
    • url是统一资源定位符:http://localhost:8080/myFirstServlet
  • 协议及版本
    • http的版本:
    • http1.0 只能请求一次
    • http1.1 可以反复请求

代码获取:

运行结果:

4.3.2 获取请求头基本信息

运行结果:

4.3.3 获取表单参数的值

首先,写一个简单的html的form表单如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
<h5>get提交方式</h5>
<form action="/RequsetDemo" method="get">
    用户名:<input type="text" name="userName"> <br/>
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"> <br/>

    性别:
    <input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女 <br>
    爱好:
    <input type="checkbox" name="hobby" value="zuqiu">zuqiu
    <input type="checkbox" name="hobby" value="piqiu">piqiu
    <input type="checkbox" name="hobby" value="pingpang">pingpang
    <input type="checkbox" name="hobby" value="paobu">paobu
    <input type="checkbox" name="hobby" value="papo">papo <br>

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
</form>
<hr/>
<h5>post提交方式</h5>
<form action="/RequsetDemo" method="post">
    用户名:<input type="text" name="userName"> <br/>
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"> <br/>

    性别:
    <input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女 <br>
    爱好:
    <input type="checkbox" name="hobby" value="zuqiu">zuqiu
    <input type="checkbox" name="hobby" value="piqiu">piqiu
    <input type="checkbox" name="hobby" value="pingpang">pingpang
    <input type="checkbox" name="hobby" value="paobu">paobu
    <input type="checkbox" name="hobby" value="papo">papo <br>

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
</form>
</body>
</html>

运行结果为:

get 和 post 方式提交的数据,其获取方法完全不一样,获取参数的方式如下:

  • 获取通过get方式提交的参数:
    • 调用 getQueryString()方法获取(Tomcat8.0以上的版本不用解决乱码问题,在内部已经对编码问题解决了)
  • 获取通过post方式提交的参数:
    • 通过InputStream流读取参数(post方式需要解决乱码问题)

也有一种通用的获取参数的方式:

  • requset.getParameter(String name)    返回 String value
  •  requset getParameterNames()        返回 Enurmation / Iterator 迭代器

使用案例:

get方式:

运行结果:

post方式:

运行结果:

通用方式获取:

运行结果:

 

4.3.4  非法链接

非法链接指的是

  1. 直接访问下载地址的情况 referer = null;
  2. referer 请求头中不包含广告页面 : referer.contains("adv.html");  其中adv.html是广告页面

运行结果:

现在在webapp目录下用HTML写一个简单的广告页面adv.html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>adv</title>
</head>
<body>
广告链接...
<a href="/GetReferer">跳转到资源地址</a>
</body>
</html>

然后再来试试获取referer

运行结果:

4.4 通过servlet获取http响应信息

4.4.1 重定向 

实现方式1:

  1. 设置响应状态码:response.setStatus(302);
  2. 设置响应头:response.setHeader("location"," * .html");

实现方式2:

  1. response.sendRedirect("/ *. html") ;

运行结果:

4.4.2  定时刷新

  • response.setHeader("refresh", “1”) ; // 表示每隔一秒刷新一次
  • response.setHeader("refresh", “3;*.html”) ; // 表示格3秒跳转到指定html页面

4.4.3  设置响应类型

这个在上面已经用过了,比如:来在浏览器输出中文的时候不会乱码

   response.setHeader("content-type", "text/html;charset=utf-8");
   ==》简写方式:
   response.setContentType("text/html;charset=utf-8");

运行结果:

 

4.4.4  以下载的格式打开

response.setHeader("Content-Disposition", "attachment;filename="+file.getName());
public class DownLoadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
//        1、创建一个File对象
        File file = new File("D:\\图片\\1.jpg"); //这个是要下载的文件
//        2、设置响应头
        response.setHeader("Content-disposition", "attachment;filename="+file.getName());
//        3、创建一个字节流输入对象
        InputStream in = new FileInputStream(file);
//        4、获取字节输出流对象
        OutputStream out = response.getOutputStream();
//        5、定义一个缓冲数组
        byte[] buff = new byte[1024];
//        6、边读边写
        int len = 0;
        while ((len=in.read(buff)) != -1)
        {
            out.write(buff, 0, len);
        }
//        7、关闭资源
        in.close();
        out.close();
    }
}

 

运行结果: 下载文件

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐