【Servlet】 三

news2024/11/29 13:36:38

本文主要介绍了基于serlvet的表白墙项目的编写. (附完整代码)

一.JS基础

作为后端开发,对于前端的要求是能前端代码能看懂七七八八 . 

JS是一个动态弱类型的编程语言

1. let/war定义变量 (推荐使用let)

2.querySelector是浏览器提供api , 能够获取到页面的元素的

(js的目的就是为了操作页面,想要操作页面就要选中元素)

3.函数可以和变量一样赋值,此处的函数,也相当于是回调函数,合适的时机才会执行

二.表白墙项目

1.创建maven项目

2.引入servlet 和 jackson 依赖

3.修改configuration

4.创建tomcat所需目录,并把前端代码放到webapp目录下

前端代码:love.html

静态页面 (html/css) 需要放到webapp目录下

5.编写后端代码

主要是两个工作:

  • 用户提交的时候,把刚才的内容通过网络传输给服务器 , 由服务器保存这个数据
  • 后续有页面的时候,此时就通过网络,从服务器获取到之前保存的好的内容

约定前后端交互接口 : 约定好 ,前端会给后端发一个什么http请求 , 后端又会返回一个什么样的http响应

5.1针对存档操作

*  前端发起一个 http请求

POST /confessionwall/message (message这个路径怎么约定都可以,但是务必前后端一致)

{

        from:

        to:

        message:

}

此处约定为json格式,把数据传输给后端

*  服务器返回一个http响应

http/1.1 200 OK

5.2针对读档操作

前端页面加载的时候,需要从服务器拿到之前提交的数据

*  请求

GET /confessionwall/message

*  响应

HTTP/1.1 200 OK

响应中的json应该是数组 , 返回的数据有多条 , 示例: 

[

        {

        }

        ,

        {

        }

]

js标准库

提供了JSON.stringify方法,把js对象转成了json字符串

类似于jackson的writeValueString方法

还提供了JSON.parse方法,把json字符串转成js对象

类似于jackson的readValue方法

注意:

1.编写servlet程序时候,不管修改前端代码还是后端代码,都要重启服务器,重新进行编译.

2.js代码在执行过程中,不会先编译,而是直接执行的 

3.html中的每个元素,同时都可以映射到js中的每一个对象

通过对象的属性,就能获取到页面的内容 ; 修改对象的属性,也能更新页面的内容 , 也叫做文档-对象模型 (DOM)

三.代码

1.浏览器输入访问localhost:8080/Confessionwall/message

就相当于是浏览器向服务器发送get请求,服务器从数据库读取数据,并返回给浏览器. 


2.浏览器访问localhost:8080/Confessionwall/love.html就相当于访问前端页面 

当输入内容, 点击提交 , 浏览器就会根据输入的内容构造成一个js对象,然后会将js对象转换为json字符串  , 然后浏览器通过http请求将这个字符串发送给服务器 ; 

服务器会将请求中的json字符串,通过key匹配到的value赋值给对象相应的属性,转换为对象 , 接着服务器将这个对象存储到数据库. 

3.love.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>
</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 src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

<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. 把用户输入的数据, 构造出 HTTP 请求, 发送给服务器.
        let body = {        //body是js对象
            from: from,
            to: to,
            message: msg
            //冒号后面的变量名
        };

        //ajax方法会根据输入的参数,构造出http请求,发送服务器
        $.ajax({
            type: 'post',
            // url: '/Confessionwall/message',  这是绝对路径
            url: 'message',     //这是相对路径  更常见 !
            contentType: 'application/json; charset=utf8',
            data: JSON.stringify(body),     //把js对象body转成json字符串
            success: function(body) {
                // 预期 body 中返回 ok
                console.log(body);
            }
        });
    }

    // 在页面加载的时候, 发起一个 GET 请求给服务器, 从服务器拿到提交过的数据.
    $.ajax({
        type: 'get',
        url: 'message',
        success: function(body) {
            // 但是由于 jquery 见到响应中的 application/json , 就会自动的把响应
            // 转换成 js 对象数组. body 其实是 js 对象数组, 而不是 json 字符串了.
            // 就可以直接按照数组的方式来操作 body, 每个元素都是 js 对象

            // 1. 遍历数组, 取出每个 js 对象.
            // 2. 根据这里的 js 对象构造出 页面元素, 显示到页面上
            let container = document.querySelector('.container');   //依然是浏览器提供的api
            for (let i = 0; i < body.length; i++) {
                let message = body[i];
                // 此处 message 对象, 就形如
                // {
                //   from: '黑猫',
                //   to: '白猫',
                //   message: '喵'
                // }
                // 构造出 html 元素!!
                // 使用浏览器提供的 api (dom api) 创建 div 标签.
                let div = document.createElement('div');
                // 设置一个 CSS 的类. 应用到 CSS 样式了. (设置样式)
                div.className = 'row';
                // 给 div 标签里设置内容, 此处显示一行文本.
                div.innerHTML = message.from + " 对 " + message.to + " 说: " + message.message;
               //把div放到container里面
                container.appendChild(div);
            }
        }
    });

</script>
</body>
</html>

4.MessageServlet.java

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.Connection;
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.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();

    //把消息保存到内存中  更科学的做法史保存到数据库
    //private List<Message> messageList=new ArrayList<>();

    //存档
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //body的格式默认 Content-type:text/plain(纯文本)

        //1.读取请求body,转换成java对象
        //  readValue把json字符串转换为Message对象(把json字符串的key匹配到的value赋值给这个对象相应的属性)
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);

        //2.得到message之后,把这个message保存到服务器
        try {
            save(message);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        //打印个日志
        System.out.println("服务器收到message:"+message);

        //3.返回响应 (可以不写)
        resp.setStatus(200);

    }

    //通过jdbc往数据库存一个数据
    private void save(Message message) throws SQLException {
        //创建数据源
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:13306/confessionwall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");

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

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

        //执行sql
        statement.executeUpdate();

        //释放资源 , 关闭连接
        statement.close();
        connection.close();

    }



    //读档
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置body格式以及字符集
        resp.setContentType("application/json; charset=utf8");

        List<Message> messageList= null;
        try {
            messageList = load();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        //把内存中的对象转成字符串      writeValueAsString 把对象转化为json字符串 (数组也可以转化)
       String resplon= objectMapper.writeValueAsString(messageList);

        resp.getWriter().write(resplon);
    }


    //通过jdbc从数据库取出数据
    private List<Message> load() throws SQLException {
        //创建数据源
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:13306/confessionwall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");

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

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

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

        //遍历结果集
        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);
        }
        //关闭连接,释放资源
        resultSet.close();
        statement.close();
        connection.close();

        return messageList;
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1187573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

aardio 去除收尾空格字符

废话不多说 直接开干&#xff01; 知识点 import console type 关键函数,用于获取对象的数据类型 eval 运行aardio代码&#xff0c;并计算表达式的值 assert 断言函数 assertf 反断言函数 error 抛出异常 tostring 用于转换参数为字符串 topointer 用于转换参数为指针 tonumber…

Nature Food | 南农蒋建东组揭示植物有益细菌的全球分布格局及未来变化(完整版)...

到2100年&#xff0c;化石燃料依赖性情景可能导致全球土壤中植物有益细菌丰度大幅下降 Fossil-fuel-dependent scenarios could lead to a significant decline of global plant-beneficial bacteria abundance in soils by 2100 Article&#xff0c;2023-10-30&#xff0c;Nat…

数据库存储过程

存储过程&#xff1a; 是一组为了完成特定功能的sql语句的集合。类似于函数。 写好了一个存储过程之后&#xff0c;我们可以像函数一样随时调用sql的集合。 复杂的&#xff0c;需要很多sql语句联合执行完成的任务。 存储过程在执行上比sql语句的执行速度要快&#xff0c;效率…

09 # 手写 some 方法

some 使用 some() 方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true&#xff0c;则返回 true&#xff1b;否则返回 false。它不会修改数组。 ele&#xff1a;表示数组中的每一个元素index&#xff1a;表示数…

IDA Pro正版多少钱?本文告诉你!

在软件反向工程和安全分析领域&#xff0c;IDA Pro无疑是一款标志性的工具。这款软件在全球范围内有广泛的应用&#xff0c;用于分析、审计和调试各类软件产品。但是&#xff0c;当我们决定购买这款业界顶级的反汇编和反编译软件时&#xff0c;一个最直接也是最现实的问题摆在面…

Oracle Unifier 22.12 ~ 23.10 功能改进清单表

序言 时隔近一年&#xff0c;Oracle Unifier 22还没握熟&#xff0c;新版本23便已迭代到23.10&#xff0c;根据甲骨文常规的发布规律&#xff0c;相信不久之后便会正式迎来正式本地版V23&#xff0c;了解Unfier的朋友或许知晓&#xff0c;本地版是云版迭代一年后的版本&#x…

怎样使用ovsyunlive在web网页上直接播放rtsp/rtmp视频

业务中需要在网页中直接播放rtsp和rtmp视频&#xff0c;多方比较测试发现ovsyunlive的播放器能直接播放rtsp/rtmp视频&#xff0c;还是非常方便简洁&#xff0c;使用过程如下&#xff1a; 1&#xff0c;Windows系统在github上面下载ovsyunlive绿色包下载解压。 github地址&am…

【中国知名企业高管团队】系列62:海信Hisense

昨天&#xff0c;华研荟介绍了海尔公司的发展历程和张瑞敏先生的创业故事&#xff0c;以及现在海尔集团的高管。今天为您介绍同处一地&#xff0c;发展模式类似的海信集团。 一、关于海信Hisense 海信成立于1969年&#xff0c;前身是“国营青岛无线电二厂”&#xff0c;从收音…

第二章《补基础:不怕学不懂线性代数》笔记

2.1 直观理解向量 2.1.1 理解向量加法与数乘 维度相同的向量之间才可以进行加法运算&#xff0c;向 量进行加法运算时只要将相同位置上的元素相加即可&#xff0c;结果向量的维度保持不变。 向量进行数乘运算时将标量与向量的每个元素 分别相乘即可得到结果向量。 2.1.2 理…

《向量数据库指南》——LlamaIndex 和 Milvus Cloud对于 Chat Towards Data Science 的作用

那么,LlamaIndex 是如何帮助我们协调数据检索?Milvus 又如何帮助搭建聊天机器人的呢?我们可以用 Milvus 作为后端,用于 LlamaIndex 的持久性向量存储(persistent vector store)。使用 Milvus Cloud 实例后,可以从一个 Python 原生且没有协调的应用程序转换到由 LlamaIn…

【代码随想录】算法训练计划15

兄弟们&#xff0c;写到了1点了快 1、层序遍历 题目&#xff1a; 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 思路&#xff1a; 左侧也要加进去的&#xff0c;万有右侧没…

stm32 Bootloader设计(YModem协议)

stm32 Bootloader设计&#xff08;YModem协议&#xff09; Chapter1 stm32 Bootloader设计(YModem协议)YModem协议&#xff1a;STM32 Bootloader软件设计STM32 Bootloader使用方法准备工作stm32 Bootloader修改&#xff1a;stm32目标板程序.bin偏移地址修改&#xff1a; Chapt…

YOLO目标检测——铁轨裂纹检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;安全监控、智能驾驶、人机交互、智能城市数据集说明&#xff1a;&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含有图片标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、…

Java对象的浅拷贝

介绍 Java对象的浅拷贝&#xff08;Shallow Copy&#xff09;是指创建一个新的对象&#xff0c;并复制原始对象的所有非静态字段到新对象。如果字段是基本类型&#xff0c;那么复制的就是基本类型的值。如果字段是引用类型&#xff0c;那么复制的就是引用&#xff0c;而不是引…

哪种小型洗衣机好用?迷你洗衣机品牌推荐

随着科技的快速发展&#xff0c;现在的人们越来越注重自己的卫生问题&#xff0c;不仅在吃上面会注重卫生问题&#xff0c;在用的上面也会更加严格要求&#xff0c;而衣服做为我们最贴身的东西&#xff0c;我们对它的要求也会更加高&#xff0c;所以最近这几年较火爆的无疑是内…

立体库堆垛机取货动作控制程序功能

取货动作功能块 为左出货台有货 DB11.DBX0.0 左出货台车就位 DB11.DBX0.2 右出货台车就位 DB11.DBX1.2 为右出货台有货 DB11.DBX1.0 左出货台车就位 DB11.DBX0.2 右出货台车就位 DB11.DBX1.2 T20上升保护时间

看这里!学习苹果手机更改锁屏密码的方法!

锁屏密码是用于保护设备与隐私安全的一项重要措施。用户设置锁屏密码后&#xff0c;在打开手机时需要输入正确的密码才能进入桌面。定期更改锁屏密码可以减少数据泄露的风险&#xff0c;那么&#xff0c;苹果手机更改锁屏密码&#xff1f;当您想要更改Apple设备的锁屏密码时&am…

createElement的用法

目录 一&#xff1a;介绍 二&#xff1a;语法与例子 1、语法 2、一些例子 例1&#xff1a; 例2&#xff1a; 例3&#xff1a; 3、第二种写法 一&#xff1a;介绍 document.createElement()是在对象中创建一个对象&#xff0c;要与appendChild() 或 insertBefore()方法…

js获取当前日期与7天后的日期

调用 console.log(this.getSectionData(7))结果 函数 getSectionData(section) {const now new Date()const nowYear now.getFullYear()const nowMonth now.getMonth() 1 < 10 ? (0 (now.getMonth() 1)) : (now.getMonth() 1)const nowDay now.getDate() < 1…

AJAX 入门笔记

课程地址 AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09; AJAX 不是新的编程语言&#xff0c;而是一种使用现有标准的新方法 AJAX 最大的优点是在不重新加载整个页面的情况下&#xff0c;可以与服务器交换数据并更新部分网页内容 XML…