当前位置: 首页 > article >正文

【JAVA】Servlet开发

目录

HttpServlet

HttpServletRequest

 HttpServletResponse

错误页面

设置网页自动刷新时间

构造重定向相应

js发起http请求 

服务器端对js发起的http请求进行处理

前端获取后端数据,添加到当前页面的末尾,代码示例: 

 前后端交互:引入数据库(存储数据)

1)引入数据库依赖

​编辑

​编辑2)建库建表

3)编写数据库代码

整体代码 

利用Cookie和Session实现登录逻辑

1.登录页面(html)

2.通过一个Servlet处理上述的登录请求

3.网站主页,通过另一个servlet生成的动态页面


掌握如下三个类,就可以完成Servlet的大部分开发了

  1. HttpServlet
  2. HttpServletRequest
  3. HttpServletResponse

URI:唯一资源标识符

URL:唯一资源定位/地址符

HttpServlet

HttpServlet继承这个类,重写里面的方法,目的就是为了把咱们子集定义的代码,“插入到”tomcat中,HttpServlet的常用方法如下:

方法名称
调用时机
init
HttpServlet 实例化之后被调用一次,初始化
destory
HttpServlet 实例不再使用的时候调用一次,释放资源
service
收到 HTTP 请求的时候调用
doGet
收到 GET 请求的时候调用 ( service 方法调用 )
doPost
收到 POST 请求的时候调用 ( service 方法调用 )
doPut/doDelete/doOptions/...
收到其他请求的时候调用 ( service 方法调用 )
我们实际开发的时候主要重写 doXXX 方法 , 很少会重写 init / destory / service
init还是比较有用的;service一般会doGet/doPost替代;destory一般用不上,说了不算,算了不说,因为一个Servlet不用了,说明Tomcat要关闭了,而Tomcat关闭有两种方式:
  1. 直接干掉Tomcat进程,完全来不及调用destory的;
  2. 通过8005管理端口,给Tomcat发送一个“停机”指令,这个时候是能够执行destory的。

init / destory / service 这三个方法都不需要手动调用,会被tomcat在合适的时机,自动调用,咱们写好代码,让别人来帮忙调用,这种方式就叫做 “框架” ,也就是一个程序的主体部分,都已经被其他大佬们写完了,有些细节内容,允许咱们插入咱们自己写的自定义的逻辑.

HttpServletRequest

Tomcat 通过 Socket API 读取 HTTP 请求 ( 字符串 ), 并且按照 HTTP 协议的格式把字符串解析成
HttpServletRequest 对象 .
核心方法
方法
描述
String getProtocol()
返回请求协议的名称和版本。
String getMethod()
返回请求的 HTTP 方法的名称,例如, GET POST PUT
String getRequestURI()
从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该
请求的 URL 的一部分。
String getContextPath()
返回指示请求上下文的请求 URI 部分。
String getQueryString()
返回包含在路径后的请求 URL 中的查询字符串。
InputStream
getInputStream()
用于读取请求的 body 内容 . 返回一个 InputStream 对象 .
Enumeration
getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名
称。
String getParameter(String
name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回
null
String[]
getParameterValues(String
name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,
如果参数不存在则返回 null
Enumeration
getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)
以字符串形式返回指定的请求头的值。
String
getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
String getContentType()
返回请求主体的 MIME 类型,如果不知道类型则返回 null
int getContentLength()
以字节为单位返回请求主体的长度,并提供输入流,或者如果
长度未知则返回 -1

上述的方法都是get系列方法(都是读方法),没有set系列(没有写方法),当前拿到的HttpServletRequest,这些数据的内容已经确定下来了,程序员是不应该修改的.

前端将数据交给后端

除了query string之外,还可以通过http请求的body来传递参数(POST)。

(1)直接通过form表单

        (body的格式就是query string的格式)

        Content-Type:application/x-www-form-urlencoded

(2)直接使用json

        (body的格式就是json)

        Content-Type:application/json

这三种方式本质上是等价的,都是把键值对数据交给服务器,前两种方法servlet天然支持的,json这种方法需要引入第三方库。

在java中,json的第三方库是非常多的,这里我们使用jackson(jackson是spring官方推荐的库,也被spring集成起来了)

步骤如下:

1)下载导入jackson到项目中,通过maven

Maven Repository: Search/Browse/Explore (mvnrepository.com)

(2)使用jackson

一个类两个方法

ObjectMapper

  • 把json字符串,映射成java的一个对象(read方法)
  • 把一个java对象,映射成json字符串(write方法)
Request request = objectMapper.readValue(req.getInputStream(),Request.class);

1.核心工作就是把json字符串,映射成java 对象,参数就是json字符串(json字符串是在http的body中的,就需要通过HttpServletRequest中的getInputStream来获取到)

此处把这个流对象直接传给readValue,readValue内部就会读取InputStream中的所有数据(http请求的body,也就是json字符串),进一步尝试解析

2.按照json的格式,进行解析,把json字符串,解析成map(键值对)

3.把map转换成对象,在方法的第二个参数

如下示例:

import com.fasterxml.jackson.databind.ObjectMapper;

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;
import java.io.ObjectInputValidation;


class Request()
{
    public String username;
    public String password;
}
class Response{
    public boolean ok;
}

@WebServlet("/json")
public class JsonParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Request request = objectMapper.readValue(req.getInputStream(),Request.class);
        System.out.println("username="+request.username);
        System.out.println("password="+request.password);

        Response response=new Response();
        response.ok=true;
        //把响应对象转成json字符串
        String respJson=objectMapper.writeValueAsString(response);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respJson);
    }
}

 HttpServletResponse

        Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应 , 然后把响应的数据设置到
HttpServletResponse 对象中 . 然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式 , 转成一个字符串 , 并通过 Socket 写回给浏览器 .

核心方法

方法
描述
void setStatus(int sc)
为该响应设置状态码
void setHeader(String name, String value)
设置一个带有给定的名称和值的 header. 如果 name 已经存在 , 则覆盖旧的值
void addHeader(String
name, String value)
添加一个带有给定的名称和值的 header. 如果 name 已经存在 , 不覆盖旧的值, 并列添加新的键值对
void setContentType(String type)
设置被发送到客户端的响应的内容类型。
void setCharacterEncoding(String
charset)
设置被发送到客户端的响应的字符编码( MIME 字符集)例如,UTF-8
void sendRedirect(String location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端
PrintWriter getWriter()
用于往 body 中写入文本格式数据
OutputStream getOutputStream()
用于往 body 中写入二进制格式数据

错误页面

resp.sendError(404,"这个页面是一个错误页面")

设置网页自动刷新时间

resp.setHeader("refresh","1");

构造重定向相应

resp.setStatus(302);
resp.setHeader("Location","https://www.baidu.com");

header需要有一个Location属性,描述要跳转到哪里 ,除了这种写法外,还有如下另一种方法:

resp.sendRedirect("https://www.baidu.com");

使用ajax,需要先引入JQeury第三方库

jquery (v3.7.1) - jQuery 是一个高效、精简并且功能丰富的 JavaScript 工具库。它提供的 API 易于使用且兼容众多浏览器,这让诸如 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作更加简单。 | BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务icon-default.png?t=N7T8https://www.bootcdn.cn/jquery/

链接如上,选择如下链接

在script标签引入jquery

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

js发起http请求 

        // 把用户填写的内容,发送给服务器,让服务器来保存
        // $ 是jquery提供的全局变量,ajax是$的一个方法
        // ajax的参数是一个js对象,可以有很多属性
        let body={
            "from":from,
            "to":to,
            "message":message
        }
        //上述body是一个js对象,还需要转换成json字符串
        let jsonString = JSON.stringify(body)
        $.ajax({
            type:'post',
            url:'message',
            contentType:'application/json; charset=utf8',
            data:jsonString,
            //这里的body与上面的body不是同一个,是响应报文的正文
            success:function(body){
                // 这个回调就是收到响应之后要执行的代码了
            }

        });

此处success回调函数,不是立即执行的,而是在浏览器收到服务器返回的成功这样的响应的时候,才会执行function ,这个函数的第一个参数,是响应数据的body中的内容。

服务器端对js发起的http请求进行处理

import com.fasterxml.jackson.databind.ObjectMapper;

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;
import java.util.ArrayList;

class Message{
//    确保java代码中类的属性名字和json中的属性名字保持一致,才能够自动填充
    public String from;
    public String to;
    public String message;

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    private List<Message> messageList = new ArrayList<>();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用jackson读取前端发来的数据,把这个数据保存到服务器这边
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        System.out.println("请求中收到的message:"+ message);
        //保存数据最简单的是直接内存中存储,使用集合类
        //但是这样做一旦重启服务器,一切数据都没有了,一般存储到数据库中
        messageList.add(message);
        //返回一个响应
        resp.setStatus(200);
        resp.getWriter().write("ok");
    }
}

这里启动服务器后,不能直接访问/message,需要访问.html路径

当浏览器要向服务器获取资源, 服务器方使用List类型的数组存储历史数据,转成的json字符串就是一个json数组,jackson自动遍历List里的每个元素,把每个元素分别转成json字符串。

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("application/json;charset=utf-8");
        String respJson = objectMapper.writeValueAsString(messageList);
        resp.getWriter().write(respJson);
    }

上述代码setStatus和setContentType必须在getWriter前面,否则不会生效 

    $.ajax{

        type:'get',

        url:'message',

        success:function(body){

            //处理服务器返回的响应数据。(json格式的数组)

        }

    }

//当响应中,header带有ContentType:"application/json",JQuery就会自动把json字符串解析成js对象了,如果没有带ContentType:"application/json"就需要通过js代码JSON.parse方法手动把json字符串转成js对象

前端获取后端数据,添加到当前页面的末尾,代码示例: 

    $.ajax{
        type:'get',
        url:'message',
        success:function(body){
            //处理服务器返回的响应数据。(json格式的数组)
            //由于响应中已经有ContentType:"application/json"了,就不需要使用parse方法手动转换了
            //body = JSON.parse(body);
            
            //拿到 container这个元素
            let containerDiv = document.querySelector('.container');
            //处理服务器返回的响应数据。(json格式的数组了)
            for(let i=0;i<body.length;i++)
            {
                //body是一个数组,此时的message也就是js对象了
                //这个message对象里有三个属性:from、to、message
                let message = body[i];
                
                //根据message对象构建html片段,把这个片段给显示到网页上
                //createElement 方法就能构造一个html标签
                //此时就得到了<div></div>
                let div = document.createElement('div');
                //还需要给这个div设置一个属性
                div.className = 'row';
                //设置内容
                div.innerHTML = message.from + " 对 " + message.to + " 说:" +message.message;
                //将这个div添加到containerDiv末尾
                containerDiv.appendChild(div);
            }
        }

 前后端交互:引入数据库(存储数据)

1)引入数据库依赖

Maven仓库链接

Maven Repository: Search/Browse/Explore (mvnrepository.com)

搜索MySQL,选择如下:

这里选择5.1.47版本

复制如下代码

复制到pom.xml里


2)建库建表

create database if not exists message_wall charset utf8;
use message_wall;
-- 删表的目的是为了防止之前数据库里有一样的表
drop table if exists message;
use message_wall;
create table message(`from` varchar(1024),`to` varchar(1024),message varchar(1024));

3)编写数据库代码

// 1. 创建数据源
private DataSource dataSource = new MysqlDataSource();
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3307/message_wall?characterEncoding=utf8&useSSL=false");
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("root");
// 2. 建立连接
Connection connection = dataSource.getConnection();

// 3. 构造 SQL
String sql = "insert into message values(?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, message.from);
statement.setString(2, message.to);
statement.setString(3, message.message);

// 3. 执行 SQL
statement.executeUpdate();

// 4. 回收资源
statement.close();
connection.close();

整体代码 

MessageServlet.java

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

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 javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

class Message {
    public String from;
    public String to;
    public String message;

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    // 引入数据库, 此时 messageList 就不再需要了.
    // private List<Message> messageList = new ArrayList<>();

    private DataSource dataSource = new MysqlDataSource();

    @Override
    public void init() throws ServletException {
        // 1. 创建数据源
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3307/message_wall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource) dataSource).setPassword("root");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 读取前端发来的数据, 把这个数据保存到服务器这边.
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        System.out.println("请求中收到的 message: " + message);
        // 最简单的办法, 直接在内存中保存. 可以使用一个集合类, 把所有收到的 message 都存到内存中.
        // 很明显, 保存到内存, 并非是一个非常合理的办法. 后续一旦重启服务器, 数据丢失了.
        // 相比之下, 把这个数据持久化存储到数据库中, 更科学的.
        // messageList.add(message);
        // 插入数据库
        try {
            save(message);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        // 返回一个响应
        resp.setStatus(200);
        resp.getWriter().write("ok");
        // resp.setContentType("application/json");
        // resp.getWriter().write("{ ok: true }");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过这个方法来处理当前获取消息列表的 get 请求. 不需要解析参数, 直接返回数据即可.
        resp.setStatus(200);
        resp.setContentType("application/json; charset=utf8");
        // 从数据库查询
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String respJson = objectMapper.writeValueAsString(messageList);
        resp.getWriter().write(respJson);
    }

    private void save(Message message) throws SQLException {
        // 通过这个方法把 message 插入到数据库中

        // 1. 建立连接
        Connection connection = dataSource.getConnection();

        // 2. 构造 SQL
        String sql = "insert into message values(?, ?, ?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, message.from);
        statement.setString(2, message.to);
        statement.setString(3, message.message);

        // 3. 执行 SQL
        statement.executeUpdate();

        // 4. 回收资源
        statement.close();
        connection.close();
    }

    private List<Message> load() throws SQLException {
        // 通过这个方法从数据库读取到 message.

        // 1. 建立连接
        Connection connection = dataSource.getConnection();

        // 2. 构造 SQL
        String sql = "select * from message";
        PreparedStatement statement = connection.prepareStatement(sql);

        // 3. 执行 sql
        ResultSet resultSet = statement.executeQuery();

        // 4. 遍历结果集合
        List<Message> messageList = new ArrayList<>();
        while (resultSet.next()) {
            Message message = new Message();
            message.from = resultSet.getString("from");
            message.to = resultSet.getString("to");
            message.message = resultSet.getString("message");
            messageList.add(message);
        }

        // 5. 回收资源
        resultSet.close();
        statement.close();
        connection.close();

        // 6. 返回 messageList
        return messageList;
    }
}

 message_wall.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表白墙</title>
    <style>
        /* * 通配符选择器, 是选中页面所有元素 */
        * {
            /* 消除浏览器的默认样式. */
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .container {
            width: 600px;
            margin: 20px auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
            margin: 20px 0;
        }

        .row {
            /* 开启弹性布局 */
            display: flex;
            height: 40px;
            /* 水平方向居中 */
            justify-content: center;
            /* 垂直方向居中 */
            align-items: center;
        }

        .row span {
            width: 80px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 280px;
            height: 30px;
            color: white;
            background-color: orange;
            /* 去掉边框 */
            border: none;
            border-radius: 5px;
        }

        /* 点击的时候有个反馈 */
        .row button:active {
            background-color: grey;
        }
    </style>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
    <h1>表白墙</h1>
    <p>输入内容后点击提交, 信息会显示到下方表格中</p>
    <div class="row">
        <span>谁: </span>
        <input type="text">
    </div>
    <div class="row">
        <span>对谁: </span>
        <input type="text">
    </div>
    <div class="row">
        <span>说: </span>
        <input type="text">
    </div>
    <div class="row">
        <button id="submit">提交</button>
    </div>
    <!-- <div class="row">
        xxx 对 xx 说 xxxx
    </div> -->
</div>

<script>
    // 实现提交操作. 点击提交按钮, 就能够把用户输入的内容提交到页面上显示.
    // 点击的时候, 获取到三个输入框中的文本内容
    // 创建一个新的 div.row 把内容构造到这个 div 中即可.
    let containerDiv = document.querySelector('.container');
    let inputs = document.querySelectorAll('input');
    let button = document.querySelector('#submit');
    button.onclick = function() {
        // 1. 获取到三个输入框的内容
        let from = inputs[0].value;
        let to = inputs[1].value;
        let msg = inputs[2].value;
        if (from == '' || to == '' || msg == '') {
            return;
        }
        // 2. 构造新 div
        let rowDiv = document.createElement('div');
        rowDiv.className = 'row message';
        rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
        containerDiv.appendChild(rowDiv);
        // 3. 清空之前的输入框内容
        for (let input of inputs) {
            input.value = '';
        }
        // 4. 把用户填写的内容, 发送给服务器. 让服务器来保存.
        //    $ 是 jquery 提供的全局变量. ajax 就是 $ 的一个方法.
        //    ajax 的参数是一个 js 对象, 可以有很多属性
        let requestBody = {
            "from": from,   // from 变量里的值, 就是第一个输入框的内容, "张三"
            "to": to,       // to 变量的值, 就是第二个输入框的内容, "李四"
            "message": msg  // msg 变量的值, 就是第三个输入框的内容, "我喜欢你很久了"
        };
        // 上述 body 是一个 js 对象, 还需要转成 json 字符串.
        let jsonString = JSON.stringify(requestBody);
        $.ajax({
            type: 'post',
            url: 'message',
            contentType: 'application/json; charset=utf8',
            data: jsonString,
            success: function(responseBody) {
                // 这个回调就是收到响应之后要执行的代码了.
                // 前端使用 console.log 打印日志到控制台. (chrome 开发者工具的控制台)
                console.log("responseBody: " + responseBody);
            }
        });
    }

    // 直接在 script 里面写的 js 代码, 就是在页面加载时被执行到的.
    // 发起一个 get 请求, 从服务器获取到数据
    // get 请求不需要 body, 也就不需要上述 data 和 contentType 属性了.
    $.ajax({
        type: 'get',
        url: 'message',
        success: function(body) {
            // 由于响应中已经有 Content-Type: application/json 了, 就不需要使用 parse 方法手动转换了.
            // body = JSON.parse(body);

            // 拿到 container 这个元素
            let containerDiv = document.querySelector('.container');
            // 处理服务器返回的响应数据. (json 格式的数组了)
            for (let i = 0; i < body.length; i++) {
                // body 是一个数组, 此时 message 也就是 js 对象了.
                // 这个 message 对象里, 有三个属性, from, to, message
                let message = body[i];

                // 根据 message 对象构建 html 片段, 把这个片段给显示到网页上.
                // createElement 方法就能构造出一个 html 标签.
                // 此时就得到了 <div></div>
                let div = document.createElement('div');
                // 还需要往里面设置一个 属性 , class="row" (设置这个属性, 是为了让 css 能够给这个元素设置一些样式)
                // 此时就得到了 <div class="row"></div>
                div.className = 'row';
                // 给这个 div 里设置内容
                // 此时就得到了 <div class="row">张三 对 李四 说: 我喜欢你很久了</div>
                div.innerHTML = message.from + " 对 " + message.to + " 说: " + message.message;
                // 把 div 添加到 containerDiv 的末尾
                containerDiv.appendChild(div);
            }
        }
    });
</script>
</body>
</html>

利用Cookie和Session实现登录逻辑

Cookie是客户端存储数据的机制

Session是服务器存储数据的机制(不算持久化存储)

1.登录页面(html)

2.通过一个Servlet处理上述的登录请求

通过这个Servlet读取用户名和密码,并且验证是否登录成功。

如果登陆成功,就会给当前用户,创建一个会话 ,并且把得到的sessionid,通过cooki返回给客户端,客户端就把cookie保存起来了。

3.网站主页,通过另一个servlet生成的动态页面

在这个页面中,就会把刚才这里的用户数据给显示到页面上。

getSession(true)

这个方法,就是根据请求的cookie中的sessionid,查询服务器的hash表,找到对应的session对象。如果cookie中没有sessionid(首次登录的时候,就是没有的)或者sessionid没有查找到对应的session对象,就可以创建出一个session对象出来。

参数为true,允许不存在时自动创建;false不能创建,直接返回null

//可以给会话中保存一些自定义的数据,通过Attribute的方式来保存
HttpSession session = req.getSession(true);
//此处Atrribute也是键值对,这里的内容存储什么都可以
session.setAttribute("username",username);
session.setAttribute("loginTime",System.currentTimeMillis());
//此处相当于登录成功,让页面跳转网站首页
resp.sendRedirect("index");

此处的getSession会创建新会话

1)生成sessionid和HttpSession对象

2)把上述sessionid和HttpSession对象保存到内存hash表中

3)把sessionid设置到响应报文的header中的 Set-Cookie字段

浏览器拿到响应,就会把这个Set-Cookie的内容保存到浏览器的Cookie中 。


http://www.kler.cn/a/273168.html

相关文章:

  • 每周算法比赛
  • 物联网赋能的人工智能图像检测系统
  • IsADirectoryError: [Errno 21] Is a directory: ‘xxxxx/.ipynb_checkpoints‘
  • C++ 模板专题 - 静态分支(if)
  • 【逆向基础】十八、PE文件格式(三)
  • 【初阶数据结构篇】链式结构二叉树(二叉链)的实现(感受递归暴力美学)
  • HTML选择文件的实时预览
  • Netty中的核心概念
  • python中的闭包
  • 使用 ONLYOFFICE API 构建 Java 转换器,在 Word 和 PDF 之间进行转换
  • 本地mysql测试成功后上传至云服务器出现了这么多问题?
  • 一.Netedit的简要介绍
  • 修改/etc/resolve.conf重启NetworkManager之后自动还原
  • leetcode刷题(javaScript)——动态规划相关场景题总结
  • 微信小程序 nodejs+vue+uninapp学生在线选课作业管理系统
  • 【概率论中的两种重要公式:全概率和贝叶斯】
  • js判断对象是否有某个属性
  • Android SystemServer进程解析
  • MapReduce面试重点
  • 详解Python中的缩进和选择
  • 搜索二叉树迭代和递归的两种*简单*实现方式
  • python--剑指offer--题目目录-学习计划
  • Spring Bean的生命周期流程
  • ElasticSearch架构设计
  • 中国移动端第三方输入法市场专题2024
  • 掘根宝典之C++迭代器简介