JavaWeb--快速入门Servlet

67 阅读10分钟

Servlet

一、Servlet

运行在服务器端的小程序,他可以接受客户端发送来的请求,并响应数据给客户端

Servlet是JavaEE规范之一。规范自然就是接口

Servlet就是JavaWeb三大组件之一。三大组件分别是:Servlet、Filter、Listerner监听器

1.什么是JavaEE?

Java EE,Java 平台企业版(Java Platform Enterprise Edition),之前称为Java 2 Platform, Enterprise Edition (J2EE)

是 Sun 公司为企业级应用推出的标准平台,用来开发B/S架构软件。Java EE 可以说是一个框架,也可以说是一种规范。

2.如何手动实现 Servlet程序

1、编写一个类去实现servlet接口

2、实现service方法,处理请求,并响应数据

3、到web.xml中去配置servlet程序的访问地址

实例

package com.caq.study;

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

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init初始化方法");

//          1.可以去获取Servlet程序的别名servlet-name的值
        System.out.println("HelloServlet的别名是:"+servletConfig.getServletName());
//          2.获取初始化参数init-param
//          3.获取ServletContext对象
    }

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


    /**
     * service方法专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//        System.out.println("hello servlet!");

        //ServletRequest是HttpServletRequest的父接口,我们通过强转为一个子接口类型
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;


        String method = httpServletRequest.getMethod();
        if("GET".equals(method)){
            doGet();
        }else if ("POST".equals(method)){
            doPost();
        }
    }

//    get请求的操作
    public void doGet(){
        System.out.println("get请求");
        System.out.println("get请求");
    }

//    post的请求
    public void  doPost(){
        System.out.println("post请求");
        System.out.println("post请求");
    }

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

    @Override
    public void destroy() {

    }
}

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标签给Tomcat配置Servlet程序-->
    <servlet>
        <!--        给servlet起一个别名,一般是类名-->
        <servlet-name>HelloServlet</servlet-name>

        <!--        servlet-class是Servlet类的全类名-->
        <servlet-class>com.caq.study.HelloServlet</servlet-class>

    </servlet>

    <!--    servlet-mapping标签给servlet配置访问地址-->
    <servlet-mapping>
        <!--        servlet标签作用是告诉服务器,当前配置的地址给那个servlet程序使用-->
        <servlet-name>HelloServlet</servlet-name>

        <!--        url-pattern标签配置访问地址-->

        <url-pattern>/hello</url-pattern>
    </servlet-mapping>


    <servlet>
        <servlet-name>HelloServlet2</servlet-name>
        <servlet-class>com.caq.study.HelloServlet2</servlet-class>
    </servlet>

    <!--    <url-pattern标签配置访问地址
            /   斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
            /hello  表示地址为:http://ip:port/工程路径/hello
    -->
    <servlet-mapping>
        <servlet-name>HelloServlet2</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>HelloServlet3</servlet-name>
        <servlet-class>com.caq.study.HelloServlet3</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet3</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ContextServlet1</servlet-name>
        <servlet-class>com.caq.study.ContextServlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ContextServlet1</servlet-name>
        <url-pattern>/context1</url-pattern>
    </servlet-mapping>
</web-app>

image-20211224183426450

image-20211224183344579

3.url 地址到 Servlet机制

里面写的很详细了,不需要怎么补充了

image-20211224183830083

4.Servlet 的生命周期

1、执行Servlet构造器方法

2、执行init初始化方法

第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。

3、执行 service 方法

第三步,每次访问都会调用。

4、执行 destroy 销毁方法

第四步,在 web工程停止的时候调用

5.GET 和 POST 请求的分发处理

实例和标题2代码一致,我都写在一块了

下面补充一点知识

Get请求和Post请求的区别?

GET请求一般用去请求获取数据

POST一般作为发送数据到后台时使用

GET请求也可传参到后台,但是其参数在浏览器的地址栏的url中可见,所以隐私性安全性较差,且参数长度也是有限制的

POST请求传递参数放在Request body中,不会在url中显示,比GET要安全,且参数长度无限制

GET请求比较常见的方式是通过url地址栏请求

POST最常见是通过form表单发送数据请求

6.通过继承 HttpServlet 实现 Servlet

一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。

1、编写一个类去继承 HttpServlet 类

2、根据业务需要重写 doGet 或 doPost 方法

3、到 web.xml 中的配置 Servlet 程序的访问地址

package com.caq.study;

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 HelloServlet2 extends HttpServlet {
    /**
     * doGet方法在get请求时调用
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */


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

    /**
     * 在post请求的时候调用
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet2的doPost方法");
    }
}

xml文件在第一个实例中

image-20211224185430889

7.如何使用idea创建Servlet程序

image-20211224190002979

8.Servlet类的继承体系

image-20211224190032839

二、ServletConfig类

ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。

Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。

Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的ServletConfig 对 象。

ServletConfig 类的三大作用

1、可以获取 Servlet 程序的别名 servlet-name 的值

2、获取初始化参数 init-param

3、获取 ServletContext 对象

三、ServletContext 类

什么是 ServletContext?

1、ServletContext 是一个接口,它表示 Servlet 上下文对象

2、一个 web 工程,只有一个 ServletContext 对象实例。

3、ServletContext 对象是一个域对象。

4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。

什么是域对象?

域对象,是可以像 Map 一样存取数据的对象,叫域对象。

这里的域指的是存取数据的操作范围,整个 web 工程

image-20211224190703434

package com.caq.study;

import javax.servlet.ServletContext;
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 ContextServlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取context对象
        ServletContext contest = getServletContext();

        contest.setAttribute("key1","value1");

        System.out.println("Context1中获取域数据key1的值是:"+contest.getAttribute("key1"));
        System.out.println("Context1中获取域数据key1的值是:"+contest.getAttribute("key"));
        System.out.println("Context1中获取域数据key1的值是:"+contest.getAttribute("key"));
        System.out.println("Context1中获取域数据key1的值是:"+contest.getAttribute("key"));
    }
}

image-20211224190858723

四、HTTP协议

什么是HTTP协议?

协议就是指双方或多方规定好的,大家都需要遵守的规则,就叫协议

HTTP协议就是客户端和服务器通信时,发送数据要遵守的规则!

Http协议中的数据又叫报文

请求的 HTTP 协议格式

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

Get请求

请求又分为 GET 请求,和 POST 请求两种

放一个Get请求的HTTP协议内容

image-20211224191736902

image-20211224193309144

Post请求

image-20211224193422636

常用请求头的说明

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 协议格式

image-20211224193632889

常用的响应码说明

200 表示请求成功

302 表示请求重定向

404 表示请求服务器已经收到了,但是你要的数据不存在**(请求地址错误)**

image-20211224193755581

500 表示服务器已经收到请求,但是服务器内部错误**(代码错误)**

因为我的代码里出现了除0的操作所以会报500

image-20211224193938695

五、HttpServletRequest类

HttpServletRequest 类有什么作用

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

HttpServletRequest 类的常用方法

getRequestURI() 获取请求的资源路径

getRequestURL() 获取请求的统一资源定位符(绝对路径)

注意区分两者

getRemoteHost() 获取客户端的ip 地址

getHeader() 获取请求头

getParameter() 获取请求的参数

getParameterValues() 获取请求的参数(多个值的时候使用)

getMethod() 获取请求的方式GET 或POST

setAttribute(key, value) ; 设置域数据

getAttribute( key); 获取域数据

getRequestDispatcher() 获取请求转发对象

实例

package com.caq.study;

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 RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的资源路径
        System.out.println("URI=>"+req.getRequestURI());
        //获取请求的统一资源定位符(绝对路径)
        System.out.println("URI=>"+req.getRequestURL());
        System.out.println("客户端地址==>"+req.getRemoteHost());
        System.out.println("请求投User-Agent==》"+req.getHeader("User-Agent"));
        System.out.println("请求的方式==》"+req.getMethod());


    }
}

image-20211224194842154

如何获取请求参数

实例

package com.caq.study;

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.util.Arrays;

public class ParameterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String username = req.getParameter("username");
        String password = req.getParameter("password");
//        String hobby = req.getParameter("hobby");

        String[] hobbies = req.getParameterValues("hobby");


        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("兴趣爱好:"+ Arrays.asList(hobbies));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//        String hobby = req.getParameter("hobby");

        String[] hobbies = req.getParameterValues("hobby");


        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("兴趣爱好:"+ Arrays.asList(hobbies));
    }
}

image-20211224200952119

请求的转发

image-20211224201115254

实例

package com.caq.study;

import javax.servlet.RequestDispatcher;
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 Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println("在Servlet1中查看参数"+username);

        //域数据(盖章并传递给s2)
        req.setAttribute("key1","s1的章");

        //问路:S2怎么走?
        /**
         * 请求转发必须以斜杠打头,斜杠表示地址http:ip:port/工程名,映射到web目录
         */
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");

        //走向servlet2
        requestDispatcher.forward(req,resp);//向前走

    }
}
package com.caq.study;

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 Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数
        String username = req.getParameter("username");
        System.out.println("查看材料"+username);

        Object key1 = req.getAttribute("key1");
        System.out.println("s2是否有章"+key1);

        //处理自己的业务
        System.out.println("s2处理自己的业务");
    }
}

image-20211224201527483

base标签的作用

base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转.

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

在 javaWeb 中,路径分为相对路径和绝对路径两种:

相对路径是:

. 表示当前目录

… 表示上一级目录

资源名 表示当前目录/资源名

绝对路径: http://ip:port/工程路径/资源路径

在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。

​ 1、绝对路径

​ 2、base+相对

web 中 / 斜杠的不同意

在web 中/斜杠是一种绝对路径。

/斜杠如果被浏览器解析,得到的地址是:http://ip:port/

/斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径

六、HttpServletResponse类

​ HttpServletResponse类和 HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse表示所有响应的信息

​ 我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse对象来进行设置

两个输出流的说明

​ 字节流 getOutputStream(); 常用于下载(传递二进制数据)

​ 字符流 getWriter(); 常用于回传字符串(常用)

两个流同时只能使用一个。

使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

如何往客户端回传数据

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

通过代码我们也看出了是通过流的方式进行传数据的

请求重定向

请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)。

image-20211224203031617

请求重定向的第一种方案:

​ //设置响应状态码302,表示重定向,(已搬迁)

​ resp.setStatus(302);

​ //设置响应头,说明新的地址在哪里
​ resp.setHeader(“Location”, “http:// localhost:8080”);

请求重定向的第二种方案(推荐使用):
resp. sendRedirect( “http: / / localhost:8080” );