JavaWeb(五)Servlet

什么是Servlet

  1. Servlet是JavaEE规范之一,规范就是接口
  2. Servlet就是javaweb三大组件之一:Servlet、Filter过滤器、Listener监听器
  3. Servlet是运行在服务器上的一个Java小程序,它可以接收客户端发送过来的请求,并相应数据给客户端

方式一:手动实现Servlet程序(实现Servlet接口)

  1. 编写一个类实现Servlet接口
  2. 实现service方法,处理请求,并相应数据
package com.dynamicWeb.servlet;

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

/**
 * @author ningqian
 * @create -05-08 21:24
 */
public class MyServlet 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("My Servlet 被访问了:是谁在偷偷关注我");
    }

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

    @Override
    public void destroy() {

    }
}

  1. 在web.xml中配置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标签给Tomcat配置Servlet程序-->
    <servlet>
        <!--servlet-name标签给Servlet程序起一个别名(一般为类名)-->
        <servlet-name>MyServlet</servlet-name>
        <!--全类名-->
        <servlet-class>com.dynamicWeb.servlet.MyServlet</servlet-class>
    </servlet>
    <!--为Servlet程序配置访问地址-->
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <!--此时Servlet程序的访问地址为:http://ip地址:port/工程路径/hello-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
  1. 启动Tomcat服务器,浏览器地址输入Servlet地址即可
    此时IDEA的输出窗口打印出了访问信息:
    JavaWeb(五)Servlet
  2. 通过Servlet访问地址访问Servlet的流程
    JavaWeb(五)Servlet
  3. Servlet的声明周期
    (1)执行Servlet构造器<只在第一次访问执行>
    (2)执行init()初始化方法<只在第一次访问执行>
    (3)执行service()方法<每次访问都会执行>
    (4)执行destroy()销毁方法(在web工程停止的时候调用)

请求的分发处理

  1. 在webapp下创建一个html文件,点击提交,发送给Servlet程序,请求类型为get
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/dynamicWeb/hello" method="get">
    <input type="submit"/>
</form>
</body>
</html>
  1. 修改Servlet程序中的service()方法,区分不同类型的请求
@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("My Servlet 被访问了:是谁在偷偷关注我");
        //获取请求的类型(get还是post)
        //类型转换,HttpServletRequest子接口又getMethod()方法
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();
        //System.out.println(method);
        if(method.equals("GET")){
            System.out.println("一个get请求");
        }
        else if(method.equals("POST")){
            System.out.println("一个post请求");
        }
    }
  1. 启动Tomcat服务器,打开test测试页面,点击提交按钮

JavaWeb(五)Servlet
4. 改进
针对不同类型的请求get和post,分别编写对应的执行方法,doGet()和doPost(),然后再service()方法中分别调用

方式二:通过继承HTTPServlet实现Servlet程序

一般在实际项目中,都是使用继承HttpServlet类的方式去实现Servlet程序,而不是直接实现Servlet接口

  1. 编写一个类继承HttpServlet类
  2. 根据业务重写doGet()或doPost()方法
  3. 在web.xml配置Servlet的访问地址

方式三:使用IDEA创建Servlet程序

new-Servlet
不要将①勾选
JavaWeb(五)Servlet

Servlet类的继承体系

JavaWeb(五)Servlet

ServletConfig类

Servlet程序的配置信息类,Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。
Servlet程序默认第一次访问时创建,ServletConfig是每个Servlet创建时,就创建一个对应的ServletConfig对象,并传到Servlet程序的init()方法中
使用getServletConfig()方法也可以获取一个ServletConfig的一个对象
** 一个web工程可以有多个Servlet程序,自然可以对应有多个ServletConfig对象**

三大作用

  1. 可以获取Servlet程序的别名 <servlet-name>
  2. 可以获取初始化参数(在web.xml中<servlet>下配置,可以有多个) <init-param>
  3. 可以获取ServletContext对象

注意

  1. 如果重写了init()方法,必须调用父类的init()
super.init(config);

代码测试

  1. 编写一个Servlet程序(通过idea的new-servlet方式),命名为ServletConfig(我这个命名不太好,容易和ServletConfig混淆,应该命名为MyServletConfig比较合适)
public class ServletConfig extends HttpServlet {
    @Override
    public void init(javax.servlet.ServletConfig servletConfig) throws ServletException {
        //必须先调用父类的init()
        super.init(servletConfig);
        System.out.println("这是重写的init()方法");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println(request.getMethod()+"请求");
        System.out.println("ServletConfig的get处理");
        //首先获取ServletConfig类的对象
        javax.servlet.ServletConfig servletConfig = getServletConfig();
        //1. 获取Servlet程序的别名
        String servletName = servletConfig.getServletName();
        System.out.println("Servlet程序的别名:"+servletName);
        //2. 获取初始化参数
        String className = servletConfig.getInitParameter("className");
        System.out.println("初始化参数className值为:"+className);
        //3. 获取ServletContext对象
        ServletContext servletContext = servletConfig.getServletContext();
        System.out.println("ServletContext对象:"+servletContext);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println(request.getMethod()+"请求");
        System.out.println("ServletConfig的post处理");
    }
}

  1. 配置web.xml中的该类信息
    <!--servletConfig的配置-->
    <servlet>
        <servlet-name>ServletConfig</servlet-name>
        <servlet-class>com.dynamicWeb.servlet.ServletConfig</servlet-class>
        <!--初始化参数设置-->
        <init-param>
            <param-name>className</param-name>
            <param-value>ServletConfig.class</param-value>
        </init-param>
    </servlet>
      <servlet-mapping>
        <servlet-name>ServletConfig</servlet-name>
        <url-pattern>/ServletConfig</url-pattern>
    </servlet-mapping>
  1. 启动Tomcat,在浏览器地址栏输入:http://localhost:8080/dynamicWeb/ServletConfig
    IDEA打印信息:
    JavaWeb(五)Servlet

ServletContext类

  1. ServletContext是一个接口,它表示Servlet上下文对象
  2. 一个web工程只有一个ServletContext对象实例
  3. ServletContext对象是一个域对象
  4. ServletContext是在web工程部署启动的时候创建的,在web工程停止的时候销毁
  5. 域对象:可以像Map一样存取数据的对象;这里的域指的是存取数据的操作范围,整个web工程
    JavaWeb(五)Servlet

ServletContext类的四个作用

  1. 获取web.xml中配置的上下文参数context-param
  2. 获取当前的工程路径,格式:/工程路径
  3. 获取工程部署后在服务器硬盘上的绝对路径
  4. 像Map一样存取数据

演示

  1. 编写一个Servlet程序用来演示,通过IDEA的new-servlet创建
public class MyServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletConfig
        ServletConfig servletConfig = getServletConfig();
        //通过ServletConfig对象获取ServletContext对象
        ServletContext servletContext = servletConfig.getServletContext();
        //1. 获取Context的参数信息context-param
        String myContextName = servletContext.getInitParameter("myContextName");
        System.out.println("context-param参数myContextName:"+myContextName);
        //2. 获取当前的工程路径
        String contextPath = servletContext.getContextPath();
        System.out.println("当前的工程路径"+contextPath);
        //3. 获取工程部署后在服务器硬盘上的绝对路径
        //参数”/“被服务器解析地址为:http://ip:port/工程名 映射到IDEA代码的web目录
        String realPath = servletContext.getRealPath("/");
        System.out.println("工程部署后在服务器硬盘上的绝对路径"+realPath);
        //3.1 获取工程下的文件lib在服务器硬盘上的绝对路径
        String realPath1 = servletContext.getRealPath("/WEB-INF/lib");
        System.out.println("lib的绝对路径:"+realPath1);
        //4. 设置context属性
        servletContext.setAttribute("key1","value1");
        servletContext.setAttribute("key2","value2");
        //获取context属性
        Object key1 = servletContext.getAttribute("key1");
        Object key2 = servletContext.getAttribute("key2");
        System.out.println("context属性1:"+key1);
        System.out.println("context属性2:"+key2);

    }

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

    }
}

  1. 编写web.xml配置信息
 <!--上下文参数,属于整个web工程,可以有多个-->
    <context-param>
        <param-name>myContextName</param-name>
        <param-value>beauty</param-value>
    </context-param>
     <servlet>
        <servlet-name>MyServletContext</servlet-name>
        <servlet-class>com.dynamicWeb.servlet.MyServletContext</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServletContext</servlet-name>
        <url-pattern>/myServletContext</url-pattern>
    </servlet-mapping>
  1. 启动Tomcat服务器,浏览器地址栏输入:http://localhost:8080/dynamicWeb/myServletContext
    IDEA打印访问信息:
    JavaWeb(五)Servlet

HTTP协议

指客户端和服务器之间通信时,发送的数据需要遵守的规则
HTTP协议中的数据又叫报文

请求的HTTP协议格式

客户端给服务器发送的数据叫请求
服务器给客户端回传数据叫响应

GET请求

  1. 请求行
    (1) 请求的方式GET
    (2) 请求的资源路径[+?+请求参数]
    (3) 请求的协议的版本号HTTP/1.1
  2. 请求头
    key : value 组成不同的键值对,表示不同的含义。
    JavaWeb(五)Servlet

POST请求

  1. 请求行
    (1) 请求的方式POST
    (2) 请求的资源路径[+?+请求参数]
    (3) 请求的协议的版本号HTTP/1.1
  2. 请求头
  1. key : value 不同的请求头,有不同的含义
    空行
  1. 请求体===>>> 就是发送给服务器的数据
    JavaWeb(五)Servlet

常用请求头的说明

Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息
Host: 表示请求时的服务器ip 和端口号

哪些时GET请求,哪些时POST请求

GET 请求有哪些:
1、form 标签method=get
2、a 标签
3、link 标签引入css
4、Script 标签引入js 文件
5、img 标签引入图片
6、iframe 引入html 页面
7、在浏览器地址栏中输入地址后敲回车
POST 请求有哪些:
8、form 标签method=post

响应的HTTP协议格式

  1. 响应行
    (1) 响应的协议和版本号
    (2) 响应状态码
    (3) 响应状态描述符
  2. 响应头
    (1) key : value 不同的响应头,有其不同含义
    空行
  3. 响应体---->>> 就是回传给客户端的数据
    JavaWeb(五)Servlet

常用的响应码说明

200 表示请求成功
302 表示请求重定向(明天讲)
404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)

MIME类型说明

MIME 是HTTP 协议中数据类型。
MIME 的英文全称是"Multipurpose Internet Mail Extensions" 多功能Internet 邮件扩充服务。MIME 类型的格式是“大类型/小
类型”,并与某一种文件的扩展名相对应。
常见的MIME 类型:
JavaWeb(五)Servlet
JavaWeb(五)Servlet

谷歌浏览器查看HTTP协议:

JavaWeb(五)Servlet

HttpServletRequest类

作用

每次只要有请求进入Tomcat服务器,服务器就会把请求的HTTP协议信息解析封装到Request对象中,然后传递到service方法(doGet()和doPost())中以供使用。可以通过HttpServletRequest对象,获取到所有请求的信息

常用方法

i. getRequestURI() 获取请求的资源路径
ii. getRequestURL() 获取请求的统一资源定位符(绝对路径)
iii. getRemoteHost() 获取客户端的ip 地址
iv. getHeader() 获取请求头
v. getParameter() 获取请求的参数
vi. getParameterValues() 获取请求的参数(多个值的时候使用)
vii. getMethod() 获取请求的方式GET 或POST
viii. setAttribute(key, value); 设置域数据
ix. getAttribute(key); 获取域数据
x. getRequestDispatcher() 获取请求转发对象

如何获取请求参数

req.getParameter("");

设置请求体的字符集为UTF-8,从而解决post 请求的中文乱码问题

在获取参数之前设置字符集

req.setCharacterEncoding("UTF-8");

请求转发

请求转发是指,服务器收到请求后,从一个资源跳转到另一个资源的过程就叫请求转发
JavaWeb(五)Servlet
JavaWeb(五)Servlet
JavaWeb(五)Servlet

base标签

JavaWeb(五)Servlet

<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base 标签设置页面相对路径工作时参照的地址
href 属性就是参数的地址值
-->
<base href="http://localhost:8080/07_servlet/a/b/">
</head>
<body>
这是a 下的b 下的c.html 页面<br/>
<a href="../../index.html">跳回首页</a><br/>
</body>
</html>

web中的相对路径和绝对路径

在javaWeb 中,路径分为相对路径和绝对路径两种:
相对路径是:
. 表示当前目录
… 表示上一级目录
资源名表示当前目录/资源名
绝对路径:
http://ip:port/工程路径/资源路径
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
1、绝对路径
2、base+相对

web中 / 的不同意义

在web 中/ 斜杠是一种绝对路径。
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
斜杠
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
1、/servlet1
2、servletContext.getRealPath(“/”);
3、request.getRequestDispatcher(“/”);
特殊情况: response.sendRedirect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/

HttpServletReponse类

作用

HttpServletResponse 类和HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个Response 对象传
递给Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,
我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse 对象来进行设置。

两个输出流

字节流getOutputStream(); 常用于下载(传递二进制数据)
字符流getWriter(); 常用于回传字符串(常用)
两个流同时只能使用一个。

往客户端回传数据

public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 要求: 往客户端回传字符串数据。
PrintWriter writer = resp.getWriter();
writer.write("response's content!!!");
}
}

响应的乱码问题

解决响应中文乱码方案一(不推荐使用):

// 设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用UTF-8 字符集
resp.setHeader("Content-Type", "text/html; charset=UTF-8");

解决响应中文乱码方案二(推荐):

// 它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8");

请求重定向

请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求
重定向(因为之前的地址可能已经被废弃)。
JavaWeb(五)Servlet
请求重定向的第一种方案:
// 设置响应状态码302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明新的地址在哪里
resp.setHeader(“Location”, “http://localhost:8080”);
请求重定向的第二种方案(推荐使用):
resp.sendRedirect(“http://localhost:8080”);

上一篇:Tomcat系统架构分析


下一篇:java – 忽略带有Test注释的方法的PMD规则