Bootstrap

Javaweb中servlet相关知识概念

请添加图片描述
哈喽,小友们,Javaweb课程学习第二站,servlet的相关知识概念,感兴趣的宝子一起来学哦。
点赞收藏加关注,下次学习不迷路(❁´◡`❁)

2、Servlet的开发步骤

Servlet是一种Java编写的服务器端程序,用于生成动态Web内容。它运行在支持Java的应用服务器上,通过处理客户端请求和生成响应来交互式地浏览和修改数据。

1,在pom.xml文件中加入如下配置,设置项目编译采用的JDK版本和字符编码

<properties>
    <maven.compiler.source>17</maven.compiler.source>

    <maven.compiler.target>17</maven.compiler.target>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

在这里插入图片描述

2,引入Servlet依赖

<dependency>
  <groupId>javax.servlet</groupId>

  <artifactId>javax.servlet-api</artifactId>

  <version>3.1.0</version>

  <scope>provided</scope>

</dependency>

在这里插入图片描述

3,创建类,实现Servlet接口,实现接口中的方法

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
//Servlet实例化后,Servlet容器调用该方法完成初始化工作
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
        //用于获取Servlet对象的配置信息,返回Servlet的ServletConfig对象
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时就会调用此方法。
    }

    @Override
    public String getServletInfo() {
        return null;
        //返回一个字符串,其中包含关于Servlet的信息,例如,作者、版本和版权等信息
    }

    @Override
    public void destroy() {
//负责释放Servlet对象占用的资源
    }
}

请添加图片描述

4,在service方法中处理请求和响应数据

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    // TODO: 处理请求的逻辑

    // 向浏览器响应内容   Hello Servlet
    // 1.获取向浏览器写出内容的输出流
    PrintWriter writer = servletResponse.getWriter();
    // 2.写出内容
    writer.println("Hello Servlet");
}

在这里插入图片描述

5,在web.xml文件中配置Servlet访问地址

<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的名称-->
    <servlet-name>helloServlet</servlet-name>

    <!-- Servlet类的全限定名 -->
    <servlet-class>cn.jj.HelloServlet</servlet-class>//根据你的文件所在目录导入

  </servlet>

  <!-- Servlet访问地址配置 -->
  <servlet-mapping>
    <!--Servlet名称:与上面配置的名称一致-->
    <servlet-name>helloServlet</servlet-name>

    <!-- 浏览器访问地址,必须以/开头 -->
    <url-pattern>/hello</url-pattern>

  </servlet-mapping>

</web-app>

在这里插入图片描述

6,部署项目,并通过浏览器访问Servlet

在这里插入图片描述

2.1、注解方式配置Servlet

@WebServlet 注解

在这里插入图片描述

注解开发Servlet

1.编写Servlet,通过注解@WebServlet配置访问地址
@WebServlet(name = “hello2”,urlPatterns = {“/hello3”,“/hello3”})与下列web.xml文件含义相同

在这里插入图片描述

@WebServlet(name = "hello2",urlPatterns = {"/hello3","/hello3"})
public class HelloServlet2 implements Servlet {
    @Override
    public void init(ServletConfig config) throws ServletException {

    }

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

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        res.getWriter().println("Hello Servlet2");
    }

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

    @Override
    public void destroy() {

    }
}

通过浏览器访问Servlet

在这里插入图片描述

2.2,Servlet生命周期

生命周期: 从出生到死亡以及中间所经历的过程则称为一个生命周期
对象的生命周期: 创建对象–> 运行操作–>销毁操作

Servlet 对象的生命周期:Servlet 创建对象–>初始化操作–> 运行操作–>销毁操作
Web 服务器管理了 Servlet 的生命周期,Servlet 对象整个过程都是 Web 服务器来管理的。

servlet 接口中生命周期方法

生命周期方法作用运行次数
构造方法在对象实例化的时候执行 必须有公共的无参数构造方法1次
void init(ServletConfig config)在初始化的时候执行1次
void service(ServletRequest req, ServletResponse res)每次请求都会执行n次
void destroy()在服务器正常关闭的时候1次
  • 生命周期方法执行顺序图
@WebServlet("/hello3")
public class HelloServlet3 implements Servlet {
    public HelloServlet3() {
        System.out.println("构造方法被调用");
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init方法被调用");
    }

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

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("处理浏览器发送请求");
    }

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

    @Override
    public void destroy() {
        System.out.println("destory方法被调用");
    }
}

启动服务器,浏览器输入http://localhost:8080/hello3访问HelloServlet3,出现以下效果

在这里插入图片描述

刷新浏览器,多次访问HelloServlet3,控制台打印结果如下:

在这里插入图片描述

关闭服务器时,Servlet容器会调用HelloServlet3的destroy()方法,在IDEA控制台打印出“destroy 方法被调用”

在这里插入图片描述

2.3,loadOnStartup 属性

1,作用

让 Servlet容器启动的时候创建并初始化 Servlet。

2,用法:

数字小的优先执行

  • web.xml配置用法

    在这里插入图片描述

注解配置用法

在这里插入图片描述

2.4,Servlet 的继承体系

1,GenericServlet类

GenericServlet默认实现了 ServletServletConfig 这两个接口,它的子类是 HttpServlet,如果我们写的Servlet
使用的是 Http 协议,建议继承于 HttpServlet

2, HttpServlet类

@WebServlet("/hello5")
public class HelloServlet5 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("Hello HttpServlet");
    }
}

在这里插入图片描述

2.5,ServletAPI

HttpServletRequest 对象

​ HttpServletRequest 是一个接口,该接口的实现类对象称为请求对象,请求对象封装了所有的请求信息(请求行,请求头,请求体(请求参数))。
​ HttpServletRequest 接口包含了大量的方法。由 Tomcat 去实现这个对象,并且在 servlet 启动的时候调用service() 将请求对象传递进来了。我们在 service 方法中直接使用即可。

request获取请求行相关方法功能描述
String getMethod()该方法用于获取请求行中的请求方式(如GET、POST等)
String getRequestURI()该方法用于获取请求行中资源名称部分Uniform Resource Identifier统一资源标识符,代表一个资源名字
StringBuffer getRequestURL()该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,<br但不包括后面的查询参数部分。
Uniform Resource Locator 统一资源定位符,代表一个可以访问地址
String getProtocol()该方法用于获取请求行中的协议名和版本
String getContextPath()该方法用于获取请求URL中属于Web应用程序的路径,这个路径以“/”开头,表示相对于整个Web站点的根目录,路径结尾不含“/”。
如果请求URL属于Web站点的根目录,那么返回结果为空字符串(“”)
String getScheme()该方法用于获取请求的协议名
package cn.jj;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/requestLine")
public class RequestLineServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("请求方式:" + req.getMethod());
        System.out.println("请求资源名称:" + req.getRequestURI());
        System.out.println("请求资源URL:" + req.getRequestURL());
        System.out.println("请求协议和版本:" + req.getProtocol());
        System.out.println("请求Web应用程序名称:" + req.getContextPath());
        System.out.println("请求协议名:" + req.getScheme());
    }
}

请添加图片描述

request获取请求头相关方法功能描述
String getHeader(String headName)得到指定的请求头的值
参数:键的名字
返回:相应请求头的值
Enumeration getHeaderNames()该方法用于获取一个包含所有请求头字段的Enumeration对象

请添加图片描述

request与请求参数相关方法功能描述
String getParameter(String name)该方法用于获取某个指定名称的参数值
如果请求消息中没有包含指定名称的参数,getParameter()方法返回null;
如果指定名称的参数存在但没有设置值,则返回一个空串;
如果请求消息中包含有多个该指定名称的参数
getParameter()方法返回第一个出现的参数值
String[] getParameterValues(String name)根据参数名得到一组同名的值
复选框,下拉列表多选
Enumeration getParameterNames()获得所有的参数名
Map getParameterMap()获取所有的参数键和值,封装成Map对象

请求对象获取请求参数

页面文件放在webapp文件夹中

method提交方式,action表单提交位置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>

</head>

<body>
<h2>用户注册</h2>

<form action="/register" method="post">
    用户名: <input type="text" name="name"><br/>&nbsp;码:&nbsp; &nbsp;<input type="password" name="password"><br/>
    性别: <input type="radio" name="gender" value="" checked="checked"/><input type="radio" name="gender" value=""/><br/>
    <select name="city">
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
    </select>
    爱好:
    <input type="checkbox" name="hobby" value="java"/>java
    <input type="checkbox" name="hobby" value="python"/>python
    <input type="checkbox" name="hobby" value="C++"/>C++
    <input type="checkbox" name="hobby" value="rap"/>rap<br>
<!--    隐藏域:<input type="hidden" name="token" value="{{token}}"/>-->
    <br/>
    <input type="submit" value="注册"/>
    <input type="reset" value="重置"/>
</form>

</body>

</html>

package cn.jj;

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("/register")
public  class RegisterServlet extends HttpServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         req.setCharacterEncoding("UTF-8");//解决请求参数乱码问题
        // 根据参数名获取参数值
        String name = req.getParameter("name");
        String gender = req.getParameter("gender");
        String city = req.getParameter("city");
        System.out.println("用户名:" + name);
        System.out.println("性别:" + gender);
        System.out.println("城市:" + city);

        // 获取参数名为 hobby 的值,由于hobby参数值是复选框,可能会存在多个,故使用 getParameterValues获取
        String[] hobbies = req.getParameterValues("hobby");
        System.out.print("爱好:");
        for (String hobby : hobbies) {
            System.out.print(hobby + ",");
        }
    }
}

注册用户出现404解决方法

在这里插入图片描述

请添加图片描述

在这里插入图片描述

请求参数乱码问题

在浏览器发送数据给服务器的时候,使用 utf-8 编码,但服务器解码默认使用 ISO-8859-1 解码:欧洲码,不支持汉字。编码不匹配

解决请求参数中文乱码

  • 解决方法: 设置请求参数的编码为UTF-8

  • 代码位置:设置请求编码这条语句一定放在获取请求参数之前

 req.setCharacterEncoding("UTF-8");

请添加图片描述

2.6,响应对象

HttpServletResponse 是一个接口,该接口的实现类对象称为响应对象,用于响应数据(响应行,响
应头,响应体)给浏览器。HttpServletResponse 接口包含了大量的方法。由 Tomcat 去实现这个对象,
并且在 servlet 启动的时候调用 service() 将请求对象和响应对象传递进来。我们在 service 方法中直
接使用即可。即服务器收到请求命令,做出的回应,通过浏览器展示

响应信息给浏览器

响应信息相关方法

设置响应头相关方法功能描述
void addHeader(String name, String value)该方法用来设置响应头字段,其中
参数name用于指定响应头字段的名称
参数value用于指定响应头字段的值
该方法可以增加同名的响应头字段
void setHeader(String name, String value)功能同上,不同的是,该方法会覆盖同名的响应头字段
void setContentType(String type)该方法用于设置输出内容的MIME类型, 对于HTTP协议来说,就是设置Content-Type响应头字段的值。 如:如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。 需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8
void setCharacterEncoding(String charset)该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。如果没有设置Content-Type头字段,setCharacterEncoding方法设置的字符集编码不会出现在HTTP消息的响应头中
设置响应体相关方法功能描述
ServletOutputStream getOutputStream()如果服务器端返回的是二进制数据则使用这个方法,比如图片
PrintWriter getWriter()如果服务器端返回的是字符的文本数据,使用这个方法

在这里插入图片描述

resp.setContentType("text/html; charset=utf-8");

2.7,Web组件跳转

Servlet之间可以相互跳转,利用Servlet的跳转可以很容易地把一项任务按模块分开,例如,使用一个Servlet实现用户登录,然后跳转到另外一个Servlet响应结果给浏览器。

请求转发and页面跳转

request对象与转发相关方法request.getRequestDispatcher(“/要跳转的地址”).forward(request,response);

简单的登录系统(登录页面,请求----->响应)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>

</head>

<body>
<form action="login" method="post">
    账号:<input type="text" name="name"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>

</body>

</html>

package cn.jj;

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("/login")
public class Login extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");//解决请求乱码
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        req.setAttribute("name",name);
        req.getRequestDispatcher("/result").forward(req,resp);//将网页数据从页面跳转到响应页面
    }
}

package cn.jj;

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("/result")
public class result extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");//解决响应中乱码
        String name=(String)req.getAttribute("name");//获取请求页面中的数据
        resp.getWriter().print("欢迎:"+name+"登录本系统");
    }
}

作为域对象使用

作用域对象

​ 用于 Servlet 之间数据共享的服务器内存区域,作用域结构是一个Map<String, Object>。

在这里插入图片描述

作用域对象方法

与作用域有关的方法作用
void setAttribute(String key, Object value)向作用域中存储键值对数据
Object getAttribute(String key)从作用域中根据key获取对应value
void removeAttribute(String name)删除作用域中的键值对数据

重定向方法

response对象与重定向相关方法response.sendRedirect(“要跳转的地址”)

在这里插入图片描述

请求转发和重定向的区别

请添加图片描述

练习:简单的登陆页面

要求:登陆一个账号:马小信,密码:123456 登录成功显示欢迎+name+登录本系统,失败显示 账号或密码错误

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>

</head>

<body>
<form action="login" method="post">
    账号:<input type="text" name="name"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>

</body>

</html>

package cn.jj;

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("/login")
public class Login extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        req.setAttribute("name",name);
        req.setAttribute("password",password);
        String uname="马***";
        String upassword="123456";
        boolean flag;
        if (name.equals(uname)&&password.equals(upassword)) {//判断密码是否相等时,不能直接用==,需要用equals
            flag=true;

        }else {
            flag=false;
        }
        req.setAttribute("flag",flag);
        req.getRequestDispatcher("/result").forward(req,resp);
    }
}

package cn.jj;

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("/result")
public class result extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        String name=(String)req.getAttribute("name");
        boolean flag=(boolean)req.getAttribute("flag");
        if(flag){
            resp.getWriter().print("欢迎,"+name+"少爷,登录本系统");
        }else{
            resp.getWriter().print("账号或密码错误");
        }
        }

    }


在这里插入图片描述

输入你给定的账号密码

在这里插入图片描述

简单的注册页面

显示账号密码,并在注册成功页面展示账号密码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户注册</h1><br>

<form action="/registerServlet" method="get">
    账号:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    <input type="submit" value="注册">
</form>

</body>
</html>
package cn.jj;

public class User {
    private String username;
    private String password;
     User(){

     }
     User(String username,String password){
         this.username =username;
         this.password=password;
     }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

package cn.jj;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    protected void service( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取表单数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 将数据封装到User对象中
        User user = new User(username, password);

        // 将User对象添加到请求属性中
        request.setAttribute("user", user);
        // 请求转发到ResultServlet
        request.getRequestDispatcher("/resultServlet").forward(request, response);
    }

}
package cn.jj;

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

@WebServlet("/resultServlet")
public class ResultServlet extends HttpServlet {
    protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 从请求属性中获取User对象
        response.setContentType("text/html;charset=UTF-8");
        User user = (User) request.getAttribute("user");

        // 设置响应内容类型

        // 输出结果
        response.getWriter().println("<h2>恭喜你注册成功</h2>");
        response.getWriter().println("<br>");
        response.getWriter().println("<p>账号: " + user.getUsername()+"</p>");
        response.getWriter().println("<br>");
        response.getWriter().println("<p>密码: " + user.getPassword() + "</p>");
        response.getWriter().println("<br>");
        response.getWriter().println("<p>请牢记账号密码!!!</p>");
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.jj</groupId>
    <artifactId>zhangjunjie</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>23</maven.compiler.source>
        <maven.compiler.target>23</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <!--设置项目的属性信息-->
    <!--设置项目的属性信息-->
<!--    <properties>-->
<!--        <maven.compiler.source>11</maven.compiler.source>-->
<!--        <maven.compiler.target>11</maven.compiler.target>-->
<!--        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!--    </properties>-->
    <!--依赖信息-->
    <dependencies>
        <!--Servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>
<?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">
</web-app>

请添加图片描述

;