HTML/JSP_上古互联网时期,天地混沌,前后端尚未分离霓虹的IT正是这种未开化的状态20230421

HTML/JSP_上古互联网时期,天地混沌,前后端尚未分离霓虹的IT是这种未开化的状态20230421

开篇吐槽:
HTML/JSP_上古互联网时期,天地混沌,前后端尚未分离,而霓虹的IT就是这种未开化的状态,依旧通过非物质文化遗产JSP技术进行数据库的管理,正是为了累死开发。20230421_卒

一、表单块元素语法form_method action

1. form开始标签 method=“post|get” 表单提交方式 必须

post|get :规定如何发送表单数据常用值

2. form开始标签 action:表示向何处发送表单数据 必须

action=""必填 表单信息提交的位置,可以是网站 也可以是一个请求 处理地址

3.示例表单

<form method="post" action="result.html">
    <p>名字: <input name="name" type="text" value="我是你爹"> <p>
    <p>密码: <input name="pass" type="password" > <p>
    <input type="submit" name="Button" value="提交">
    <input type="reset" name="Reset" value="重填“>

</form>

4.输入框input及其指定类型type

form method action >input type=text/radio> 等
form表单元素内_指定input输入框元素类型type为文本框text/单选框radio等属性

1. form表单元素内各元素的格式

属性说明
type指定input输入框元素的类型。text文本框,password密码框、checkbox多选框、radio单选框、submit提交按钮、reset重置按钮, file文件, hidden隐藏, image图片 和 button, 默认为 text类型的文本输入框
name必须指定表单元素的名称,尤其是设置单选框时
value元素的初始值。type 元素类型 为radio单选框时必须指定一个值
size指定表单元素的初始宽度。当 type 为text或password时,表单元素的大小以字符为单位。对于其他类型,宽度以像素为单位
maxlengthtype为text或 password 时,输入的最大字特数
checkedtype为radio或checkbox时,指定按钮是否是被选中

1. 单选效果的实现:

  1. 将文本框类型为单选框的两个性别radio单选框放在一个p标签元素块中
  2. 在单选框设置相同的name元素名称,使男女单选框都同属于gender单选组内
  3. 设置value元素的为数据提交的初始数据值 type元素类型为radio单选框时必须指定一个值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title10。表单学习——登陆注册</title>
</head>
<body>
<h1>注册</h1>
<!--表单form-->
<!--要注意 一个完整的form标签,闭合标签应该将所有控件标签包含其中 -->
<!--action=""必填 表单信息提交的位置,可以是网站 也可以是一个请求 处理地址
method="post/get" 提交方式,
get方式提交:我们可以在url中看到我们提交的信息,高效但不安全
而用post提交,则在
url标签中<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title10。表单学习——登陆注册</title>
</head>
<body>
<h1>注册</h1>
    表单form
要注意 一个完整的form标签,闭合标签应该将所有控件标签包含其中 -->
<!--action=""必填 表单信息提交的位置,可以是网站 也可以是一个请求 处理地址
method="post/get" 提交方式,
get方式提交:我们可以在url中看到我们提交的信息,高效但不安全
而用post提交,则在
url标签中 没有输入参数,比较安全-->


<form action="1.我的第一个网页.html" method="get">
    <p>
        用户名:<input type="text" name="username" maxlength="8">
    </p>
    <p>
        卡号:<input type="number" name="id"></p>
    <p> 密码:<input type="pwd"></p>

    <!-- 单选框-->
    <!-- 单选效果的实现:-->
    <!--    1、将文本框类型为单选框的两个性别radio单选框放在一个p标签元素块中,-->
    <!--    2、在单选框设置相同的name元素名称,使男女单选框都同属于gender单选组内-->
    <!--    3、设置value为提交元素的初始数据值 type元素类型为radio单选框时必须指定一个值-->

    <p>性别:
        <input type="radio" name="gender" value="boy"><input type="radio" name="gender" value="girl"><input type="radio" name="gender" value="othergender">其他

    </p>
    <!--    多选框-->
    <p>
        服务器端一般把多选框储存为一个名为name的数组
        hoppy[][]={code,chat,sleep,game};
        爱好:
        <input type="checkbox" name="hobby" value="sports">运动
        <input type="checkbox" name="hobby" value="code">造轮
        <input type="checkbox" name="hobby" value="chat">撩妹
        <input type="checkbox" name="hobby" value="sleep">睡觉
        其他 <input type="text" name="hobby">
    </p>
    <p>
        <input type="submit">
        <input type="reset">
        <a href="mailto:iehmltym@gmail.com">点击告诉我密码</a>

    </p>

</form>


</body>
</html>

二、

1. 单选框 redio checked

2. 多选框 checkbox checked

3. 下拉框 select_option_selected

4. 文本域 textarea

5. 文件域 type file

6. 数字 type number

7. 邮箱 type email

8. 滑块 type range

9. 搜索框 type search


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title10。表单学习——登陆注册</title>
</head>
<body>
<h1>注册</h1>
<!--表单form-->
<!--要注意 一个完整的form标签,闭合标签应该将所有控件标签包含其中 -->
<!--action=""必填 表单信息提交的位置,可以是网站 也可以是一个请求 处理地址
method="post/get" 提交方式,
get方式提交:我们可以在url中看到我们提交的信息,高效但不安全
而用post提交,则在
url标签中<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title10。表单学习——登陆注册</title>
</head>
<body>
<h1>注册</h1>
    表单form
要注意 一个完整的form标签,闭合标签应该将所有控件标签包含其中 -->
<!--action=""必填 表单信息提交的位置,可以是网站 也可以是一个请求 处理地址
method="post/get" 提交方式,
get方式提交:我们可以在url中看到我们提交的信息,高效但不安全
而用post提交,则在
url标签中 没有输入参数,比较安全-->


<form action="1.我的第一个网页.html" method="get">
    <p>
        用户名:<input type="text" name="username" maxlength="8" value="我是你爹">
    </p>
    <p>
        卡号:<input type="number" name="id"></p>
    <p> 密码:<input type="pwd"></p>

    <!-- 单选框-->
    <!-- 单选效果的实现:-->
    <!--    1、将文本框类型为单选框的两个性别radio单选框放在一个p标签元素块中,-->
    <!--    2、在单选框设置相同的name元素名称,使男女单选框都同属于gender单选组内-->
    <!--    3、设置value为提交元素的初始数据值 type元素类型为radio单选框时必须指定一个值-->

    <p>性别:
        <input type="radio" name="gender" value="boy"><input type="radio" name="gender" value="girl"><input type="radio" name="gender" value="othergender" checked>其他

    </p>
    <!--    多选框-->
    <p>
        服务器端一般把多选框储存为一个名为name的数组
        hoppy[][]={code,chat,sleep,game};
        爱好:
        <input type="checkbox" name="hobby" value="sports">运动
        <input type="checkbox" name="hobby" value="code" >造轮
        <input type="checkbox" name="hobby" value="chat">撩妹
        <input type="checkbox" name="hobby" value="sleep">睡觉
        其他 <input type="text" name="hobby">
    </p>
    <p>
        <!--        图片提交自带submit功能-->
        <input type="button" name="btn1" value="点击变长">
        <input type="image" src="../resources/image/image00.jpeg">
    </p>
    <p>
        <input type="submit">
        <input type="reset" value="一键清空表单">
        <a href="mailto:iehmltym@gmail.com">点击告诉我密码</a>

    </p>
    <!--    下拉框 select_option_selected-->
    <p>下拉框:
        <select name="国家">
            <option value="china">中国</option>
            <option value="japan">日本</option>
            <option value="canada" selected>加拿大</option>
            <option value="usa">美国</option>

        </select>

    </p>
    <!--    文本域-->
    <p>反馈:
        <textarea name="advice" cols="10" rows="10">Please... </textarea>
    </p>
    <!--    文件域-->

    <p>
        <input type="file" name="files">
        <input type="button" name="upload" value="上传">
    </p>
    <!--    邮箱验证-->
    <p>
        邮箱
        <input type="email" name="email">
    </p>
    <p>url
        <input type="url" name="url">
    </p>
    <!--    数字-->
    <p>
        鸡蛋数量(限购3盒):
        <input type="number" min="0" max="3" step="1" name="eggs" value="eggs">
    </p>
    <!--    滑块-->
    <p>滑块声音:
        <input type="range" name="voise" min="0" max="100" step="2">
    </p>
    <!--    <搜索框-->
    <p>搜素:
        </搜索框-->
        <input type="search" name="search"></p>

</form>


</body>
</html>


三、HTML表单插播:切换服务器视角

  • 根据客户网页端的提交的表单数据,如何储存到数据库进行管理呢?
    HTML只是一种标记语言,不具备编程功能,因此以Java语言来写指令,进行数据库的操作。而在HTML中使用Java代码更是不可行的。

(一)分支选项 结局一:JSP

HTML/JSP_上古互联网时期,天地混沌,前后端尚未分离,而霓虹的IT就是这种未开化的状态,依旧通过非物质文化遗产JSP技术进行数据库的管理,直接在Web页面中嵌入动态的Java代码,

1、JavaServer Pages(JSP)

  1. JSP是一种基于Java的Web页面技术,它允许开发人员在HTML页面中嵌入Java代码,从而动态生成页面内容。
  2. 在JSP中,Java代码被包含在<% %>标记中。
  3. 例:一个简单的JSP页面,让它从MySQL数据库中获取数据并在Web页面上显示。




<!DOCTYPE html>
<html>
<head>
	<title>累死开发之HTML嵌入Java代码</title>
</head>
<body>

	<%-- 在这里写Java代码 --%>
	<%
		// 运气 - 导入JDBC包
		import java.sql.*;

		// 打通任督二脉 - 连接数据库   
		// 创建数据库连接:通过 DriverManager.getConnection 方法创建数据库连接。    方法的参数包括连接字符串、用户名和密码。例如,若要连接名为 test 的 MySQL 数据库,可以使用以下代码创建连接:

		//声明一个名为conn的Connection类型变量,并将其初始化为null。Connection是Java中用于表示数据库连接的接口,表示一个数据库连接,用于和数据库进行通信,它定义了一些方法,如创建Statement和PreparedStatement对象、提交事务、关闭连接等。在使用JDBC连接数据库时,首先需要建立一个Connection对象,然后通过该对象创建Statement和PreparedStatement对象,执行SQL语句并获取结果集。

//1-1 Statement 接口提供了两种发送 SQL 语句的方式:executeQuery() 方法用于执行 SELECT 语句并返回结果集,executeUpdate() 方法用于执行 INSERT、UPDATE 或 DELETE 等更新操作,并返回受影响的行数。

//1-2 PreparedStatement 接口是 Statement 的子接口,它通过预编译 SQL 语句的方式提高了 SQL 执行效率,并且能够有效地防止 SQL 注入攻击。在创建 PreparedStatement 对象时,需要先使用 SQL 语句创建一个模板,然后通过 setXXX() 方法设置 SQL 语句中占位符(?)的值,最后使用 executeQuery() 或 executeUpdate() 方法执行 SQL 语句。

    //1-2例1:使用Statement对象查询数据库


Connection conn = null;
PreparedStatement pstmt = null;

try {
    // 1. 建立数据库连接
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");

    // 2. 创建 PreparedStatement 对象
    String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
    pstmt = conn.prepareStatement(sql);

    // 3. 设置参数值
    pstmt.setString(1, "John");
    pstmt.setString(2, "john@example.com");
    pstmt.setInt(3, 1);

    // 4. 执行更新操作
    int rows = pstmt.executeUpdate();
    System.out.println(rows + " rows updated.");
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    // 5. 释放资源
    try {
        if (pstmt != null) {
            pstmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}


//1-2例2:使用PreparedStatement对象更新数据库 
 Connection conn = null;
PreparedStatement pstmt = null;

try {
    // 1. 建立数据库连接
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");

    // 2. 创建 PreparedStatement 对象
    String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
    pstmt = conn.prepareStatement(sql);

    // 3. 设置参数值
    pstmt.setString(1, "John");
    pstmt.setString(2, "john@example.com");
    pstmt.setInt(3, 1);

    // 4. 执行更新操作
    int rows = pstmt.executeUpdate();
    System.out.println(rows + " rows updated.");
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    // 5. 释放资源
    try {
        if (pstmt != null) {
            pstmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}



//在使用 PreparedStatement 时,通常建议先使用 Connection 接口中的 prepareStatement() 方法创建一个 PreparedStatement 对象,然后通过设置占位符的值执行 SQL 语句。这种方式可以有效地避免 SQL 注入攻击。



		Connection conn = null;
		String url = "jdbc:mysql://localhost:3306/mydb";
		String user = "root";
		String password = "123456";
		
		
		
		//或者我们一次到位 
				
//Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "username", "password");




		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(url, user, password);
			

			System.out.println("连接成功!");
		} catch (ClassNotFoundException e) {
			System.out.println("未找到驱动程序!");
			e.printStackTrace();
		} catch (SQLException e) {
			System.out.println("数据库连接失败!");
			e.printStackTrace();
		}

		// 查询数据库 执行 SQL 语句
		//例如 通过实例化Statement信息类的一个对象stmt并调用  stmt.executeQuery 方法执行 SQL 查询语句,或通过对象 stmt.executeUpdate 方法执行 SQL 更新语句。
		Statement stmt = null;
		//结果处理集 实例化结果处理集类的一个对象 命名为 rs  通过rs调用 rs.next 方法遍历结果集,使用 rs.getString、rs.getInt 等方法获取指定列的数据。最后,遍历结果集并打印所有数据信息:
		ResultSet rs = null;
		//套娃:又例若,查询 user 表中的所有数据,可以使用以下代码执行 SQL 查询语句并获取结果集:ResultSet rs = stmt.executeQuery();处理结果集:通过 rs.next 方法遍历结果集,使用 rs.getString、rs.getInt 等方法获取指定列的数据。例如,可以使用while/try循环遍历结果集、打印数据:


/**
while (rs.next()) {
    String username = rs.getString("username");
    int age = rs.getInt("age");
    System.out.println("Username: " + username + ", Age: " + age);
}
	
结果处理集ResultSet 	的next方法,用于将结果集中的模拟游标指针移动到下一行,并返回是否移动成功的布尔值,若不成功则SQLException异常类会抛出异常 。
    //  预备知识 :
1-1 首先出场,SQLException -- Java异常类,用于表示 SQL 异常。当在使用 JDBC 连接数据库时发生错误时,SQLException 内的try catch捕获异常并抛出包含了错误的具体信息,例如 SQL 语句执行错误、连接断开等。
try {
    // 执行 SQL 语句
} catch (SQLException e) {
    // 处理异常
    e.printStackTrace();
}

1-2 checkClosed方法 。检查结果集ResultSet对象rs是否被关闭的checkClosed方法的伪代码,会调用SQLException异常类,检查结果处理集对象rs、所属的 Statement stmt对象、所属的连接、所属的 PreparedStatement 对象是否已经关闭、结果集对象是否处于插入行、首行之前或最后一行之后的状态。如果检查失败,将抛出 SQL 异常。
public boolean checkClosed() throws SQLException {
//例中例中例 检查结果集对象是否被关闭
    if (isOnInsertRow) {
        // 如果结果集对象处于插入行状态,抛出 SQL 异常
        SQLException sqle = new SQLException("Invalid operation: result set is on the insert row");
        sqle.fillInStackTrace();
        throw sqle;
    } else if (isInBeforeFirst) {
        // 如果结果集对象处于首行之前的状态,抛出 SQL 异常
        SQLException sqle = new SQLException("Invalid operation: result set is before the first row");
        sqle.fillInStackTrace();
        throw sqle;
    } else if (isInAfterLast) {
        // 如果结果集对象处于最后一行之后的状态,抛出 SQL 异常
        SQLException sqle = new SQLException("Invalid operation: result set is after the last row");
        sqle.fillInStackTrace();
        throw sqle;
    }
    // 返回结果集对象是否被关闭的状态
    return isClosed;
}
1-3 终于,扒穿底裤后,我们回到 模拟游标指针的结果处理集中的rs.next()方法,现在有种一眼看穿的快感,指哪打哪,下面是伪代码:

public boolean next() throws SQLException {
    // 用了1-2 checkClosed(); 方法 检查 ResultSet 是否关闭,如果关闭则通过java JDBC 的Sql异常类 抛出异常
    checkClosed();
    // 如果当前行指向最后一行,则返回 false
    if (isAfterLast()) {
        return false;
    }
    // rows 是一个列表,保存了所有的行。如果当前行指向第一行或尚未定位到行,则将行指向下一行
    if (row == 0 || isBeforeFirst()) {
        row++;
    } else {
        // 如果当前行不是最后一行,则将行指向下一行
        row++;
        if (row > rsMetaData.getColCount()) {
            // 如果新的行超过了结果集的列数,则说明结果集已经扫描完成
            afterLast = true;
            return false;
        }
    }
    // 如果当前行为最后一行,则将 isLast 设为 true
    if (row > rsMetaData.getRowCount()) {
        isLast = true;
    }
    // 返回当前行是否有效的标志
    return !isAfterLast();
}


	*/	

		//将rs.next()方法连根拔起,捋清了盘根错节源码后(封装),再来回顾开头的遍历打印结果集,看到了方法下,java旺盛的生命力,所以对象枝繁叶茂(多态)
		/**
while (rs.next()) {
    String username = rs.getString("username");
    int age = rs.getInt("age");
    System.out.println("Username: " + username + ", Age: " + age);
}
	//若只是简单地查询某个字段,以try catch为例:
		
		try {
			stmt = conn.createStatement();
			//创建
			rs = stmt.executeQuery("SELECT * FROM user");
			while (rs.next()) {
				System.out.println(rs.getString("username"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}//逐一关闭连接
	%>

</body>
</html>

%>

(二)分支选项 结局二 Java Servlet

前后端分离Java Servlet技术

  1. 设置Java环境和MySQL数据库的正常连接。可以使用JDBC连接MySQL数据库。
  2. 在MySQL数据库中创建一个表来存储提交的文本表单数据。例如,可以创建一个名为“form_data”的表,该表包含列“id”(作为主键)、“name”、“email”和“age”。
  3. 在网页前端,创建一个表单form,其中包含要提交的文本数据。确保表单的提交方式为“POST”。
  4. 在Java应用程序中,使用Servlet来处理表单提交。在Servlet中,使用JDBC连接到MySQL数据库,并将提交的表单数据插入到“form_data”表中。
import java.sql.*; 
import java.io.*import javax.servlet.*//导入Java JDBC相关的包

//或者精细化作业逐个导包

public class Main {
  public static void main(String[] args) {
    try {
      //1. 加载MySQL的JDBC驱动
      Class.forName("com.mysql.jdbc.Driver");

      //2. 创建一个数据库连接
      String url = "jdbc:mysql://localhost:3306/mydatabase"; //数据库的URL
      String user = "root"; //数据库用户名
      String password = "mypassword"; //数据库密码
      Connection con = DriverManager.getConnection(url, user, password);

      //3. 创建一个Statement对象
      Statement stmt = con.createStatement();

      //4. 获取客户端提交的表单数据
      String name = request.getParameter("name"); //从表单中获取姓名
      String email = request.getParameter("email"); //从表单中获取邮箱
      int age = Integer.parseInt(request.getParameter("age")); //从表单中获取年龄

      //5. 构造SQL语句
      String sql = "INSERT INTO customers (name, email, age) VALUES ('" + name + "', '" + email + "', " + age + ")";

      //6. 执行SQL语句
      int rowsAffected = stmt.executeUpdate(sql);

      //7. 输出执行结果
      System.out.println(rowsAffected + " rows affected");

      //8. 关闭Statement和数据库连接
      stmt.close();
      con.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

1. SQL注入 数据注入

SQL注入是一种常见的网络攻击方式,攻击者通过构造恶意SQL语句来实现对数据库的非授权访问和操作。

2. SQL注入示例

假设有一个登录页面,用户输入用户名和密码,然后页面将用户名和密码提交到后台进行验证:

String sql = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'";
ResultSet rs = stmt.executeQuery(sql);

攻击者可以在用户名和密码的输入框中输入恶意的SQL语句,例如在用户名输入框中输入 ’ OR 1=1–,密码输入框中随意输入,那么构造出的SQL语句如下:

SELECT * FROM users WHERE username='' OR 1=1--' AND password=''

sql注入解决:
使用PreparedStatement来代替Statement,PreparedStatement支持参数化查询,可以将参数的值与SQL语句进行分离,从而避免了恶意参数的注入,以下是一个使用PreparedStatement进行查询的示例代码:

String sql = "SELECT * FROM users WHERE username=? AND password=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

pstmt使用了参数化查询,将查询条件的值与SQL语句进行了分离,使得恶意参数无法注入到SQL语句中,从而避免了SQL注入攻击的风险。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值