JavaWeb开发 : tomcat+Servlet+JSP

news2024/11/27 8:09:37

tomcat+Servlet+JSP

现在已经不是主流了,可以学习一下,了解springboot框架的原理(悲,为什么要学过时的老东西)

不过可能在维护老应用时可能用到,小型项目也是一个不错的选择

教程视频

https://www.bilibili.com/video/BV1Sm4y1d76Q?spm_id_from=333.788.videopod.episodes&vd_source=837d4fe54a9ceb585673b377f66d35cb

tomcat

因为使用的java8,只能选用tomcat9 下载.zip文件后解压

创建环境变量,新建CATALINA_HOME值为D:\development\apache-tomcat-9.0.97

然后在path中添加%CATALINA_HOME%\bin

然后浏览器输入 localhost:8080

新建项目

基于idea2022,新建jakarta ee 模板选择web application,应用程序服务器选择安装的tomcat版本,下一步,选择版本java ee 8

src/main/webapp/index.jsp就是我们启动的首页文件

然后我们编辑配置,添加配置,选择tomcat 本地

部署中添加工程目录

就可以运行了,注意要关闭之前启动的tomcat命令行,不然会端口占用,导致运行失败

Model

模型层,封装对象,让操作逻辑更加清晰

package model;

public class User {
    private int userId;
    private String username;
    private String password;  // 保存加密后的密码
    private String salt;      // 保存盐

    // 构造函数
    public User(int userId, String username, String password, String salt) {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.salt = salt;
    }

    // 获取用户ID
    public int getUserId() {
        return userId;
    }

    // 获取用户名
    public String getUsername() {
        return username;
    }
}

Mysql

先创建数据库javaweb

连接数据库

package db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Database {
    private static final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER = "root";
    private static final String PASSWORD = "root";

    public static Connection getConnection() throws SQLException {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("Database connected");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return DriverManager.getConnection(URL, USER, PASSWORD);
    }
}

DAO

DAO(Data Access Object) 是一种常用的设计模式,旨在将应用程序的业务逻辑与数据访问逻辑分离,从而提高代码的可维护性、可扩展性和测试性。

使用model层,将sql语句封装,提供接口给servlet

package db;

import model.User;

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;

public class UserDAO {

    // 检查用户名是否已存在
    public boolean isUsernameExists(String username) {
        String sql = "SELECT COUNT(*) FROM users WHERE username = ?";
        try (Connection conn = Database.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, username);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                return rs.getInt(1) > 0;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 注册用户
    public boolean registerUser(String username, String password) {
        if (isUsernameExists(username)) {
            System.out.println("username already exists!");
            return false;
        }

        // 生成盐并加密密码
        String salt = generateSalt();
        String encryptedPassword = encryptPassword(password, salt);

        String sql = "INSERT INTO users (username, password, salt) VALUES (?, ?, ?)";
        try (Connection conn = Database.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, username);
            stmt.setString(2, encryptedPassword); // 只存储加密后的密码
            stmt.setString(3, salt); // 单独存储盐
            int rowsInserted = stmt.executeUpdate();
            return rowsInserted > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 用户登录
    public User loginUser(String username, String password) {
        String sql = "SELECT user_id, password, salt FROM users WHERE username = ?";
        try (Connection conn = Database.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, username);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                int userId = rs.getInt("user_id");
                String storedEncryptedPassword = rs.getString("password");
                String salt = rs.getString("salt");

                if (storedEncryptedPassword.equals(encryptPassword(password, salt))) {
                    System.out.println("login success!");
                    // 返回一个 User 对象,包含用户ID、用户名、盐和密码
                    return new User(userId, username, storedEncryptedPassword, salt);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("username or password incorrect!");
        return null; // 登录失败返回 null
    }

    // 加密密码
    private String encryptPassword(String password, String salt) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(salt.getBytes()); // 使用盐加密密码
            byte[] hashedPassword = md.digest(password.getBytes());
            return Base64.getEncoder().encodeToString(hashedPassword);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 生成盐
    private String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }
}

Servlet

ServLet = Server+Applet(小程序) ,一种在服务器端运行的小程序,用于处理来自jsp的请求,通过DAO操控数据库给出响应

package servlet;

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.PrintWriter;

@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");

        int id = Integer.parseInt(req.getParameter("id"));
        String password = req.getParameter("pwd");

        PrintWriter out = resp.getWriter();
        out.println("账号"+id+"密码"+ password);

    }
}

Jsp

Jsp = JavaServer Pages,用于绘制可视化界面

html的绘制

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页面</title>
    <link rel="stylesheet" type="text/css" href="styles/style.css">
</head>
<body>
<div class="container">
    <h2>登录页面</h2>

    <!-- 登录表单 -->
    <form action="login" method="POST">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" required/>

        <label for="password">密码:</label>
        <input type="password" id="password" name="password" required/>

        <input type="submit" value="登录"/>
        <a href="register.jsp" class="button">注册</a>

    </form>
</div>
</body>
</html>

css的封装

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f9;
    color: #333;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.container {
    background: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    max-width: 400px;
    width: 100%;
    text-align: center;
}

h2 {
    margin-bottom: 20px;
    color: #2c3e50;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"],
input[type="password"] {
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

input[type="submit"],
.button {
    background-color: #3498db;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 4px;
    cursor: pointer;
    text-transform: uppercase;
    font-size: 14px;
}

input[type="submit"]:hover,
.button:hover {
    background-color: #2980b9;
}

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

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

相关文章

ArcGIS pro中的回归分析浅析(加更)关于广义线性回归工具的补充内容

在回归分析浅析中篇的文章中&#xff0c; 有人问了一个问题&#xff1a; 案例里的calls数据貌似离散&#xff0c;更符合泊松模型&#xff0c;为啥不采用泊松而采用高斯呢&#xff1f; 确实&#xff0c;在中篇中写道&#xff1a; 在这个例子中我们为了更好地解释变量&#x…

第R4周:LSTM-火灾温度预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 往期文章可查阅&#xff1a; 深度学习总结 任务说明&#xff1a;数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度…

《操作系统 - 清华大学》5 -4:虚拟技术

文章目录 0. 虚拟存储的定义1. 目标2.局部性原理3. 虚拟存储的思路与规则4. 虚拟存储的基本特征5. 虚拟页式存储管理5.1 页表表项5.2 示例 0. 虚拟存储的定义 1. 目标 虚拟内存管理技术&#xff0c;简称虚存技术。那为什么要虚存技术&#xff1f;在于前面覆盖和交换技术&#…

MYSQL 表的增删改查(上)

目录 1.新增数据 2.查询数据 一般查询 去重查询 排序查询 关于NULL 条件查询 分页查询 1.新增数据 语法&#xff1a;insert into 表名[(字段1&#xff0c;字段2...)] values (值&#xff0c;值....); 插入一条新数据行&#xff0c;前面指定的列&#xff0c;要与后面v…

OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。

2024-11-22 &#xff0c;由格拉斯哥大学创建的OSPTrack数据集&#xff0c;目的是通过捕获在隔离环境中执行包和库时生成的特征&#xff0c;包括静态和动态特征&#xff0c;来识别开源软件&#xff08;OSS&#xff09;中的恶意指标&#xff0c;特别是在源代码访问受限时&#xf…

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…

如何寻找适合的HTTP代理IP资源?

一、怎么找代理IP资源&#xff1f; 在选择代理IP资源的时候&#xff0c;很多小伙伴往往将可用率作为首要的参考指标。事实上&#xff0c;市面上的住宅IP或拨号VPS代理IP资源&#xff0c;其可用率普遍在95%以上&#xff0c;因此IP可用率并不是唯一的评判标准 其实更应该关注的…

idea_卸载与安装

卸载与安装 卸载1、设置 -> 应用2、查找到应用&#xff0c;点击卸载3、把删除记录和设置都勾选上4、删除其它几个位置的残留 安装1、下载安装包2、欢迎安装 -> Next3、选择安装目录 -> Next4、创建快捷图标和添加到环境变量5、确认文件夹的名称 -> Install6、完成安…

【Axure高保真原型】天气模板

今天和大家分享天气模板的原型模板&#xff0c;里面包括晴天、多云、阴天、小雨、大雨、暴雨、强雷阵雨、小雪、中雪、大雪、暴雪、雨夹雪、微风、强风、狂风、龙卷风、轻雾、大雾等&#xff0c;后续也可以自行添加。 这个模板是用中继器制作的&#xff0c;所以使用也很方便&a…

深度学习模型:循环神经网络(RNN)

一、引言 在深度学习的浩瀚海洋里&#xff0c;循环神经网络&#xff08;RNN&#xff09;宛如一颗独特的明珠&#xff0c;专门用于剖析序列数据&#xff0c;如文本、语音、时间序列等。无论是预测股票走势&#xff0c;还是理解自然语言&#xff0c;RNN 都发挥着举足轻重的作用。…

Prometheus告警带图完美解决方案

需求背景 告警分析处理流程 通常我们收到 Prometheus 告警事件通知后&#xff0c;往往都需要登录 Alertmanager 页面查看当前激活的告警&#xff0c;如果需要分析告警历史数据信息&#xff0c;还需要登录 Prometheus 页面的在 Alerts 中查询告警 promQL 表达式&#xff0c;然…

深入理解 Java 基本语法之运算符

&#xff08;一&#xff09;研究背景 在 Java 编程中&#xff0c;运算符是处理数据和变量的基本工具&#xff0c;掌握各种运算符的使用方法对于提高编程效率至关重要。 &#xff08;二&#xff09;研究目的 深入理解 Java 基础运算符的概念、分类和作用&#xff0c;通过具体…

iOS 17.4 Not Installed

0x00 系统警告 没有安装 17.4 的模拟器&#xff0c;任何操作都无法进行&#xff01; 点击 OK 去下载&#xff0c;完成之后&#xff0c;依旧是原样&#xff01; 0x01 解决办法 1、先去官网下载对应的模拟器&#xff1a; https://developer.apple.com/download/all/?q17.4 …

Flink细粒度的资源管理

Apache Flink致力于为所有应用程序自动导出合理的默认资源需求。对于希望根据其特定场景微调其资源消耗的用户,Flink提供了细粒度的资源管理。这里我们就来看下细粒度的资源管理如何使用。(注意该功能目前仅对DataStream API有用) 1. 适用场景 使用细粒度的资源管理的可能…

Ubuntu20.04运行msckf_vio

文章目录 环境配置修改编译项目运行MSCKF_VIO运行 Launch 文件运行 rviz播放 ROSBAG 数据集 运行结果修改mskcf 保存轨迹EVO轨迹评价EVO轨迹评估流程实操先把euroc的真值转换为tum&#xff0c;保存为data.tum正式评估 报错1问题描述 报错2问题描述问题分析问题解决 参考 环境配…

计算机网络 第4章 网络层

计算机网络 &#xff08;第八版&#xff09;谢希仁 第 4 章 网络层4.2.2 IP地址**无分类编址CIDR**IP地址的特点 4.2.3 IP地址与MAC地址4.2.4 ARP 地址解析协议4.2.5 IP数据报的格式题目2&#xff1a;IP数据报分片与重组题目&#xff1a;计算IP数据报的首部校验和(不正确未改) …

Angular面试题汇总系列一

1. 如何理解Angular Signal Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates. 什么是信号 信号是一个值的包装器&#xff0c;可以在该值发生变化时…

SAR ADC系列15:基于Vcm-Base的开关切换策略

VCM-Based开关切换策略&#xff1a;采样~第一次比较 简单说明: 电容上下极板分别接Vcm&#xff08;一般Vcm1/2Vref&#xff09;。采样断开瞬间电荷锁定&#xff0c;进行第一次比较。 当VIP > VIN 时&#xff0c;同时 减小VIP 并 增大VIN 。P阵列最高权重电容从Vcm(1/2Vref)…

实现Excel文件和其他文件导出为压缩包,并导入

导出 后端&#xff1a; PostMapping("/exportExcelData")public void exportExcelData(HttpServletRequest request, HttpServletResponse response, RequestBody ResData resData) throws IOException {List<Long> menuIds resData.getMenuIds();List<Co…