【JavaWeb】Servlet系列 --- 使用纯Servlet做一个单表的CRUD操作(oa小项目,超详细笔记)

news2024/10/3 6:34:19

使用纯Servlet做一个单表的CRUD操作

  • 实现步骤
    • 第一步:准备一张数据库表(sql脚本/可视化工具)
    • 第二步:准备一套HTML页面(页面原型)【前端开发工具使用vscode / IDEA】
    • 第三步:分析我们这个系统包括哪些功能?
    • 第四步:在IDEA当中搭建开发环境以及数据库配置
    • 第五步:动态实现每个功能
      • 查看部门列表
      • 查看部门详情
      • 删除部门
      • 新增部门
      • 跳转到修改部门的页面
      • 修改部门
  • 将oa项目中的资源跳转修改为合适的跳转方式(优化)

使用纯粹的Servlet完成单表【对部门的】的增删改查操作。(B/S结构)

该操作方法的问题所在:

  • 若使用jsp简化代码
  • 若使用重定向,优势更大

实现步骤

第一步:准备一张数据库表(sql脚本/可视化工具)

drop table if exists dept;
# 部门表
create table dept(
  deptno int primary key,
  dename varchar(255),
  loc varchar(255)
);

# 添加数据
insert into dept(deptno, dename, loc) values(10, 'XiaoShouBu', 'BEIJING');
insert into dept(deptno, dename, loc) values(20, 'YanFaBu', 'SHANGHAI');
insert into dept(deptno, dename, loc) values(30, 'JiShuBu', 'GUANGZHOU');
insert into dept(deptno, dename, loc) values(40, 'MeiTiBu', 'SHENZHEN');

select *from dept;

在这里插入图片描述

第二步:准备一套HTML页面(页面原型)【前端开发工具使用vscode / IDEA】

  1. 把HTML页面准备好,然后将HTML页面中的链接都能够跑通。(保证每个页面流转没问题)
  2. 应该设计哪些页面呢?
  • 欢迎页面:index.html
  • 列表页面:list.html(以列表页面为核心,展开其他操作:增删改查。)
  • 新增页面:add.html
  • 修改页面:edit.html
  • 详情页面:detail.html

以下目前代码为各页面:

  • index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>欢迎使用OA系统</title>
  </head>
  <body>
    <a href="list.html">查看部门列表</a>
  </body>
</html>

在这里插入图片描述

  • list.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>部门列表页面</title>
  </head>
  <body>
    <h1 align="center">部门列表</h1>
    <hr>
    <table border="1px" align="center" width="50%">
      <tr>
        <th>序号</th>
        <th>部门编号</th>
        <th>部门名称</th>
        <th>操作</th>
      </tr>
      <tr>
        <td>1</td>
        <td>10</td>
        <td>销售部</td>
        <td>
          <a href="javascript:void(0)" οnclick=window.confirm("您好!是否确认删除呢?")>删除</a>
          <a href="edit.html">修改</a>
          <a href="detail.html">详情</a>
        </td>
      </tr>
      <tr>
        <td>2</td>
        <td>20</td>
        <td>研发部</td>
        <td>
          <a href="javascript:void(0)" οnclick=window.confirm("您好!是否确认删除呢?")>删除</a>
          <a href="edit.html">修改</a>
          <a href="detail.html">详情</a>
        </td>
      </tr>
      <tr>
        <td>3</td>
        <td>30</td>
        <td>运营部</td>
        <td>
          <a href="javascript:void(0)" οnclick=window.confirm("您好!是否确认删除呢?")>删除</a>
          <a href="edit.html">修改</a>
          <a href="detail.html">详情</a>
        </td>
      </tr>
    </table>

    <hr>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <a href="add.html">新增部门</a>
  </body>
</html>

在这里插入图片描述

  • add.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>新增部门</title>
  </head>
  <body>
    <h1>新增部门</h1>
    <hr >
    <form action="list.html" method="post">
      部门编号<input type="text" name="deptno"/><br>
      部门名称<input type="text" name="dename"/><br>
      部门位置<input type="text" name="loc"/><br>
      <input type="submit" value="保存"/><br>
    </form>
  </body>
</html>

在这里插入图片描述

  • edit.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>修改部门</title>
  </head>
  <body>
    <h1>修改部门</h1>
    <hr >
    <form action="list.html" method="get">
      部门编号<input type="text" name="deptno" value="20" readonly /><br><!--部门编号只读不改-->
      部门名称<input type="text" name="dename" value="销售部"/><br>
      部门位置<input type="text" name="loc" value="北京"/><br>
      <input type="submit" value="修改"/><br>
    </form>
  </body>
</html>

在这里插入图片描述

  • detail.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>部门详情</title>
  </head>
  <body>
    <h1>部门详情</h1>
    <hr >
    部门编号:20 <br>
    部门名称:销售部<br>
    部门位置:北京<br>

    <input type="button" value="返回部门列表" onclick="window.history.back()"/>
  </body>
</html>

在这里插入图片描述

第三步:分析我们这个系统包括哪些功能?

什么叫做一个功能呢?

  • 只要 这个操作(以上的增删改查)连接了数据库,就表示一个独立的功能。

包括哪些功能?

  • 查看部门列表
  • 新增部门
  • 删除部门
  • 查看部门详细信息
  • 跳转到修改页面
  • 修改部门

第四步:在IDEA当中搭建开发环境以及数据库配置

  1. 创建一个webapp(给这个webapp添加servlet-api.jar和jsp-api.jar到classpath当中。)【操作和以前部署一样】
  2. 向webapp中添加连接数据库的jar包(mysql驱动
    ○ 必须在WEB-INF目录下新建lib目录,然后将mysql的驱动jar包拷贝到这个lib目录下。这个目录名必须叫做lib,全部小写的。
    在这里插入图片描述
  3. JDBC的工具类(自己配)【具体解析在阶段一的第三阶段JDBC详解】
    在这里插入图片描述

为了满足“OCP开闭原则:对扩展开放,对修改关闭”,就是更加灵活,不把代码写死。故新建一个专门存放jdbc配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/zxt_javaweb
user=root
password=13686644128zxt

接着就是编写JDBC的工具类:DBUtil类【复制即可】

import java.sql.*;
import java.util.ResourceBundle;

/**
* @Author: 爱摸鱼的TT~
* @Description: JDBC的工具类
* @Date Created in 2022-11-21 20:29
* @Modified By:
*/
public class DBUtil {
    // 静态变量:在类加载时执行。
    // 并且是有顺序的。自上而下的顺序。
    // 属性资源文件绑定
    private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
    // 根据属性配置文件key获取value
    private static String driver = bundle.getString("driver");
    private static String url = bundle.getString("url");
    private static String user = bundle.getString("user");
    private static String password = bundle.getString("password");

    static {
        // 注册驱动(注册驱动只需要注册一次,放在静态代码块当中。DBUtil类加载的时候执行。)
        try {
            // "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为以后可能还会连接Oracle数据库。
            // 如果连接oracle数据库的时候,还需要修改java代码,显然违背了OCP开闭原则。
            // OCP开闭原则:对扩展开放,对修改关闭。(什么是符合OCP呢?在进行功能扩展的时候,不需要修改java源代码。)
            //Class.forName("com.mysql.jdbc.Driver");

            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
* 获取数据库连接对象
* @return conn 连接对象
* @throws SQLException
*/
    public static Connection getConnection() throws SQLException {
        // 获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }

    /**
* 释放资源
* @param conn 连接对象
* @param ps 数据库操作对象
* @param rs 结果集对象
*/
    public static void close(Connection conn, Statement ps, ResultSet rs){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

将所有HTML页面拷贝到web目录下。

第五步:动态实现每个功能

我们应该怎么去实现一个功能呢?

  • 建议:你可以从后端往前端一步一步写。也可以从前端一步一步往后端写。都可以。但是千万要记住不要想起来什么写什么。你写代码的过程最好是程序的执行过程。也就是说:程序执行到哪里,你就写哪里。这样一个顺序流下来之后,基本上不会出现什么错误、意外。

那我们从哪里开始?

  • 假设从前端开始,那么一定是从用户点击按钮那里开始的。

查看部门列表

  1. 第一:先修改前端页面的超链接,因为用户先点击的就是这个超链接。该超链接是要与数据库连接
    在这里插入图片描述

  2. 第二:编写web.xml文件

<servlet>
  <servlet-name>list</servlet-name>
  <servlet-class>com.aimoyudett.oa.web.action.DeptListServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>list</servlet-name>
  <!--web.xml文件中的这个路径也是以“/”开始的,但是不需要加项目名-->
  <url-pattern>/dept/list</url-pattern>
</servlet-mapping>
  1. 第三:编写DeptListServlet类继承HttpServlet类。然后重写doGet方法。
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-21 21:22
* @Modified By:
*/
public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
  1. 第四:在DeptListServlet类的doGet方法中连接数据库,查询所有的部门,动态的展示部门列表页面

以下是目前DeptListServlet类中的初始代码,接下来根据具体业务步骤来添加代码

连接数据库,查询所有的部门:

// 第一步:功能实现:连接数据库,查询所有的部门【分为:1,2,3,4,5】
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    // 1.获取连接
    conn = DBUtil.getConnection();
    // 2.获取预编译的数据库操作对象
    String sql = "select deptno as a, dename, loc from dept";
    ps = conn.prepareStatement(sql);
    // 3.执行SQL查询语句
    rs = ps.executeQuery();
    // 4.处理结果集
    while(rs.next()){
        String deptno = rs.getString("a");
        String dename = rs.getString("dename");
        String loc = rs.getString("loc");
    }
} catch (SQLException e) {
    e.printStackTrace();
}finally {
    // 5.释放资源
    DBUtil.close(conn, ps, rs);
}

动态获取数据:

// 第二步:要动态获取数据,而不能写死在前端界面
// 设置响应的内容类型以及字符集,防止中文乱码问题
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

a. 分析list.html页面中哪部分是固定死的,哪部分是需要动态展示的。【目的是便于在DeptListServlet类中编写代码,实现动态展示】
在这里插入图片描述
注意:由于list.html页面属于动态获取数据,所以全部代码写进DeptListServlet类,从而可以把该部分前端文件删除

b. list.html页面中的内容所有的双引号要替换成单引号,因为java类【DeptListServlet类】中out.print(“”)这里有一个双引号,容易冲突。

c. 接下来在DeptListServlet类中将list.html copy进去,并将前端固定代码和动态代码分类写进该类中。

更新DeptListServlet类:

public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 第二步:要动态获取数据,而不能写死在前端界面
        // 设置响应的内容类型以及字符集,防止中文乱码问题
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("<!DOCTYPE html>");
        out.print("<html lang='en'>");
        out.print("<head>");
        out.print("    <meta charset='UTF-8'>");
        out.print("    <title>部门列表页面</title>");
        out.print("</head>");
        out.print("<body>");
        out.print("    <h1 align='center'>部门列表</h1>");
        out.print("    <hr>");
        out.print("    <table border='1px' align='center' width='50%'>");
        out.print("        <tr>");
        out.print("            <th>序号</th>");
        out.print("            <th>部门编号</th>");
        out.print("            <th>部门名称</th>");
        out.print("            <th>操作</th>");
        out.print("        </tr>");
        /*上面一部分是死的*/
        
        // 第一步:功能实现:连接数据库,查询所有的部门【分为:1,2,3,4,5】
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 1.获取连接
            conn = DBUtil.getConnection();
            // 2.获取预编译的数据库操作对象
            String sql = "select deptno as a, dename, loc from dept";
            ps = conn.prepareStatement(sql);
            // 3.执行SQL查询语句
            rs = ps.executeQuery();
            // 4.处理结果集
            int i = 0;// 序号
            while(rs.next()){
                String deptno = rs.getString("a");
                String dename = rs.getString("dename");
                String loc = rs.getString("loc");

                /*这部分是动态的*/
                out.print("        <tr>");
                out.print("            <td>"+(++i)+"</td>");
                out.print("            <td>"+ deptno +"</td>");
                out.print("            <td>"+ dename +"</td>");
                out.print("            <td>");
                out.print("                <a href=''>删除</a>");
                out.print("                <a href='edit.html'>修改</a>");
                out.print("                <a href='detail.html'>详情</a>");
                out.print("            </td>");
                out.print("        </tr>");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            // 5.释放资源
            DBUtil.close(conn, ps, rs);
        }
        
        /*下面一部分是死的*/
        out.print("    </table>");
        out.print("    <hr>");
        out.print("                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    <a href='add.html'>新增部门</a>");
        out.print("</body>");
        out.print("</html>");
    }
}

d. 现在写完这个功能之后,你会有一种感觉,感觉开发很繁琐,因为还没学jsp技术或者其他技术,目前只使用servlet写代码,故太繁琐了。

运行结果:
在这里插入图片描述

查看部门详情

建议:从前端往后端一步一步实现。首先要考虑的是,用户点击的是什么?用户点击的东西在哪里?

  1. 一定要先找到用户点的“详情”在哪里。在后端的java程序中找到了
<a href='写一个路径'>详情</a>
  1. 详情 是需要连接数据库的,所以这个超链接点击之后也是需要执行一段java代码的。所以要将这个超链接的路径修改一下。
    注意:修改路径之后,这个路径是需要加项目名的。【在这里即为 “/oa/dept/detail”】

  2. 问题来了:
    a. 上面的项目名路径在Java类中是可以动态获取,没必要按照上面这样静态写死;
    在这里插入图片描述
    b. 还有个问题就是在点击详情时,跳转的详情页要对应点击的具体部门编号,而不是全部部门都显示出来,故也得在超链接路径后动态获取编号。
    在这里插入图片描述
    运行结果:【点哪个部门编号,就显示哪个部门详情】
    在这里插入图片描述
    重点:向服务器提交数据的格式:uri?name=value&name=value&name=value&name=value
    这里的问号,必须是英文的问号。不能中文的问号。

  3. 解决404的问题。写web.xml文件。

<servlet>
  <servlet-name>detail</servlet-name>
  <servlet-class>com.aimoyudett.oa.web.action.DeptDetailServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>detail</servlet-name>
  <!--web.xml文件中的这个路径也是以“/”开始的,但是不需要加项目名-->
  <url-pattern>/dept/detail</url-pattern>
</servlet-mapping>
  1. 编写一个类:DeptDetailServlet继承HttpServlet,重写doGet方法。
package com.bjpowernode.oa.web.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class DeptDetailServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        //中文思路(思路来源于:你要做什么?目标:查看部门详细信息。)
        // 第一步:获取部门编号
        // 第二步:根据部门编号查询数据库,获取该部门编号对应的部门信息。
        // 第三步:将部门信息响应到浏览器上。(显示一个详情。)
    }
}
  1. 在doGet方法当中:连接数据库,根据部门编号查询该部门的信息。动态展示部门详情页。
package com.aimoyudett.oa.web.action;

import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @Author: 爱摸鱼的TT~
 * @Description:
 * @Date Created in 2022-11-21 23:03
 * @Modified By:
 */
public class DeptDetailServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 第四步:要动态获取数据,而不能写死在前端界面
        // 设置响应的内容类型以及字符集,防止中文乱码问题
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("<!DOCTYPE html>");
        out.print("<html lang='en'>");
        out.print("<head>");
        out.print("    <meta charset='UTF-8'>");
        out.print("    <title>部门详情</title>");
        out.print("</head>");
        out.print("<body>");
        out.print("    <h1>部门详情</h1>");
        out.print("    <hr >");

        //中文思路(思路来源于:你要做什么?目标:查看部门详细信息。)
        // 第一步:获取部门编号
        // /oa/dept/detail?deptno=30
        // 虽然是提交的30,但是服务器获取的是“30”这个字符串
        String deptno = request.getParameter("deptno");

        // 第二步:连接数据库,根据部门编号查询数据库,获取该部门编号对应的部门信息。
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = DBUtil.getConnection();
            String sql = "select dename,loc from dept where deptno = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,deptno);
            rs = ps.executeQuery();
            // 这个结果集一定只有一条记录
            if(rs.next()){
                String dename = rs.getString("dename");
                String loc = rs.getString("loc");

                out.print("部门编号:"+ deptno +"<br>");
                out.print("部门名称:"+ dename +"<br>");
                out.print("部门位置:"+ loc +"<br>");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(conn, ps, rs);
        }
        // 第三步:将部门信息响应到浏览器上。(显示一个详情。)

        out.print("    <input type='button' value='返回部门列表' οnclick='window.history.back()'/>");
        out.print("</body>");
        out.print("</html>");
    }
}

在这里插入图片描述

删除部门

  1. 怎么开始?从哪里开始?从前端页面开始,用户点击删除按钮的时候,应该提示用户是否删除。因为删除这个动作是比较危险的。任何系统在进行删除操作之前,是必须要提示用户的,因为这个删除的动作有可能是用户误操作。(在前端页面上写JS代码,来提示用户是否删除。)
<!--href后面设置为 javascript:void(0) 表示:仍然保留住超链接的样子-->
<!--点击此超链接之后,不进行页面的跳转。-->
<!--我只是希望用户点击该超链接的时候执行一段JS代码,不进行页面的跳转。-->
<a href="javascript:void(0)" onclick="del(30)" >删除</a>

<script type="text/javascript">
  function del(dno){
    // 弹出确认框,用户点击确定,返回true,点击取消返回false
    var ok = window.confirm("亲,删了不可恢复哦!");
    if(ok){
      // 发送请求进行删除数据的操作。
      // 在JS代码当中如何发送请求给服务器?
      //alert("正在删除数据,请稍后...")

      //写法1:document.location.href = "请求路径"
      //写法2:document.location = "请求路径"
      //写法3:window.location.href = "请求路径"
      //写法4:window.location = "请求路径"
      document.location.href = "/oa/dept/delete?deptno=" + dno;
    }
  }
</script>
  1. 以上的前端程序要写到后端的java代码当中:
    a. DeptListServlet类的doGet方法当中,使用out.print()方法,将以上的前端代码输出到浏览器上。
    b. 下面两张图是新增/修改的代码
    在这里插入图片描述在这里插入图片描述
    更进DeptListServlet类:
package com.aimoyudett.oa.web.action;

import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-21 21:22
* @Modified By:
*/
public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 获取应用的根路径
        String contextPath = request.getContextPath();

        // 第二步:要动态获取数据,而不能写死在前端界面
        // 设置响应的内容类型以及字符集,防止中文乱码问题
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("<!DOCTYPE html>");
        out.print("<html lang='en'>");
        out.print("<head>");
        out.print("    <meta charset='UTF-8'>");
        out.print("    <title>部门列表页面</title>");

        out.print("<script type='text/javascript'>");
        out.print("    function del(dno){");
        out.print("        if(window.confirm('亲,删了不可恢复哦!')){");
        out.print("            document.location.href = '"+contextPath+"/dept/delete?deptno=' + dno");
        out.print("        }");
        out.print("    }");
        out.print("</script>");

        out.print("</head>");
        out.print("<body>");
        out.print("    <h1 align='center'>部门列表</h1>");
        out.print("    <hr>");
        out.print("    <table border='1px' align='center' width='50%'>");
        out.print("        <tr>");
        out.print("            <th>序号</th>");
        out.print("            <th>部门编号</th>");
        out.print("            <th>部门名称</th>");
        out.print("            <th>操作</th>");
        out.print("        </tr>");
        /*上面一部分是死的*/

        // 第一步:功能实现:连接数据库,查询所有的部门【分为:1,2,3,4,5】
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 1.获取连接
            conn = DBUtil.getConnection();
            // 2.获取预编译的数据库操作对象
            String sql = "select deptno as a, dename, loc from dept";
            ps = conn.prepareStatement(sql);
            // 3.执行SQL查询语句
            rs = ps.executeQuery();
            // 4.处理结果集
            int i = 0;// 序号
            while(rs.next()){
                String deptno = rs.getString("a");
                String dename = rs.getString("dename");
                String loc = rs.getString("loc");

                /*这部分是动态的*/
                out.print("			<tr>");
                out.print("				<td>"+(++i)+"</td>");
                out.print("				<td>"+ deptno +"</td>");
                out.print("				<td>"+ dename +"</td>");
                out.print("				<td>");
                out.print("					<a href='javascript:void(0)' οnclick='del("+ deptno +")'>删除</a>");
                out.print("					<a href='"+ contextPath +"/dept/edit?deptno="+ deptno +"'>修改</a>");
                out.print("					<a href='"+ contextPath +"/dept/detail?fdsafdsas="+ deptno +"'>详情</a>");
                out.print("				</td>");
                out.print("			</tr>");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            // 5.释放资源
            DBUtil.close(conn, ps, rs);
        }

        /*下面一部分是死的*/
        out.print("    </table>");
        out.print("    <hr>");
        out.print("                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.print("    <a href='add.html'>新增部门</a>");
        out.print("</body>");
        out.print("</html>");
    }
}

在这里插入图片描述

  1. 解决404的问题
    从上面结果可以看出,在点击确认删除后,会进行页面跳转。由于没有在web.html文件 和 新建一个关于该删除的类相关操作,导致出现404问题
    a. 写web.xml文件
<servlet>
  <servlet-name>delete</servlet-name>
  <servlet-class>com.aimoyudett.oa.web.action.DeptDelServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>delete</servlet-name>
  <url-pattern>/dept/delete</url-pattern>
</servlet-mapping>

b. 编写DeptDelServlet继承HttpServlet,重写doGet方法。

package com.aimoyudett.oa.web.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class DeptDelServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        // 根据部门编号,删除部门。

    }
}

c. 删除成功或者失败的时候的一个处理(这里我们选择了转发,并没有使用重定向机制。)

(1)在判断失删除失败后,需要新建一个error.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error</title>
</head>
<body>
<h1>操作失败,<a href="javascript:void(0)" onclick="window.history.back()">返回</a></h1>
</body>
</html>

(2) 接着就是处理删除成功或失败的操作

// 判断删除成功了还是失败了。
if (count == 1) {
    //删除成功
    //仍然跳转到部门列表页面
    //部门列表页面的显示需要执行另一个Servlet。怎么办?转发。【后面学了重定向,也可以用这个】
    request.getRequestDispatcher("/dept/list").forward(request, response);
    //response.sendRedirect(request.getContextPath() + "/dept/list");
}else{
    // 删除失败
    request.getRequestDispatcher("/error.html").forward(request, response);
    //response.sendRedirect(request.getContextPath() + "/error.html");
}

总体DeptDelServlet类的代码:

package com.aimoyudett.oa.web.action;


import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 1:00
* @Modified By:
*/
public class DeptDelServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        // 根据部门编号,删除部门。
        // 获取部门编号
        String deptno = request.getParameter("deptno");

        // 连接数据库删除数据
        Connection conn = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            conn = DBUtil.getConnection();
            // 删除/增加 等操作 最好使用事务方法
            // 开启事务(自动提交机制关闭)
            conn.setAutoCommit(false);
            String sql = "delete from dept where deptno = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, deptno);
            // 返回值是:影响了数据库表当中多少条记录。
            count = ps.executeUpdate();
            // 事务提交
            conn.commit();
        } catch (SQLException e) {
            // 遇到异常要回滚
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, null);
        }

        // 判断删除成功了还是失败了。
        if (count == 1) {
            //删除成功
            //仍然跳转到部门列表页面
            //部门列表页面的显示需要执行另一个Servlet。怎么办?转发。【后面学了重定向,也可以用这个】
            request.getRequestDispatcher("/dept/list").forward(request, response);
            //response.sendRedirect(request.getContextPath() + "/dept/list");
        }else{
            // 删除失败
            request.getRequestDispatcher("/error.html").forward(request, response);
            //response.sendRedirect(request.getContextPath() + "/error.html");
        }
    }
}

在这里插入图片描述
在这里插入图片描述

新增部门

  1. 先修改DeptListServlet类中的最后html代码,使保存操作处于动态保存
    在这里插入图片描述
  2. 写web.xml文件
<!--保存部门-->
<servlet>
  <servlet-name>save</servlet-name>
  <servlet-class>com.aimoyudett.oa.web.action.DeptSaveServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>save</servlet-name>
  <url-pattern>/dept/save</url-pattern>
</servlet-mapping>
  1. 编写DeptSaveServlet继承HttpServlet,重写doGet方法。
package com.aimoyudett.oa.web.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 1:34
* @Modified By:
*/
public class DeptSaveServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取部门的信息
        // 连接数据库执行insert语句
        // 保存成功跳转到列表页面
        // 保存失败跳转到错误页面
    }
}

总体DeptDelServlet类的代码:

package com.aimoyudett.oa.web.action;

import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 1:34
* @Modified By:
*/
public class DeptSaveServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        // 1. 获取部门的信息
        // 注意乱码问题(Tomcat10不会出现这个问题)
        request.setCharacterEncoding("UTF-8");
        String deptno = request.getParameter("deptno");
        String dename = request.getParameter("dename");
        String loc = request.getParameter("loc");

        // 2. 连接数据库执行insert语句
        Connection conn = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            conn = DBUtil.getConnection();
            String sql = "insert into dept(deptno, dename, loc) values(?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, deptno);
            ps.setString(2, dename);
            ps.setString(3, loc);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, null);
        }

        if (count == 1) {
            // 3. 保存成功跳转到列表页面
            // 转发是一次请求。
            request.getRequestDispatcher("/dept/list").forward(request, response);

            // 这里最好使用重定向(浏览器会发一次全新的请求。)
            // 浏览器在地址栏上发送请求,这个请求是get请求。
            //response.sendRedirect(request.getContextPath() + "/dept/list");

        }else{
            // 4. 保存失败跳转到错误页面
            request.getRequestDispatcher("/error.html").forward(request, response);

            // 这里也建议使用重定向。
            //response.sendRedirect(request.getContextPath() + "/error.html");
        }

    }
}

注意:最后保存成功之后,转发到 /dept/list 的时候,会出现405,为什么?问题所在
在这里插入图片描述
● 第一:保存用的是post请求。底层要执行doPost方法。
● 第二:转发是一次请求,之前是post,之后还是post,因为它是一次请求。
● 第三:/dept/list Servlet当中只有一个doGet方法。

怎么解决?两种解决方案

  1. 第一种:在/dept/list Servlet中添加doPost方法,然后在doPost方法中调用doGet。

DeptListServlet类:

// 处理post请求
@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
}
  1. 第二种:重定向。【下节讲解】

在这里插入图片描述

跳转到修改部门的页面

还是从前端往后端写。以下步骤是进行跳转到修改部门的页面,而不是点击“修改”按钮 真正的修改成功!

  1. 修改DeptListServlet类中的前端“修改”超链接的路径代码
    在这里插入图片描述
  2. 编写web.xml文件
<!--跳转到修改页面-->
<servlet>
  <servlet-name>edit</servlet-name>
  <servlet-class>com.aimoyudett.oa.web.action.DeptEditServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>edit</servlet-name>
  <url-pattern>/dept/edit</url-pattern>
</servlet-mapping>
  1. 编写DeptEditServlet类继承HttpServlet类。然后重写doGet方法。
package com.aimoyudett.oa.web.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 1:34
* @Modified By:
*/
public class DeptEditServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取部门的信息
        // 连接数据库,根据部门编号查询部门的信息
        // 输出动态网页
    }
}

总体代码:

package com.aimoyudett.oa.web.action;

import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 10:44
* @Modified By:
*/
public class DeptEditServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        // 获取应用的根路径。
        String contextPath = request.getContextPath();

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("<!DOCTYPE html>");
        out.print("<html>");
        out.print("	<head>");
        out.print("		<meta charset='utf-8'>");
        out.print("		<title>修改部门</title>");
        out.print("	</head>");
        out.print("	<body>");
        out.print("		<h1>修改部门</h1>");
        out.print("		<hr >");
        out.print("		<form action='list.html' method='post'>");

        // 获取部门编号
        String deptno = request.getParameter("deptno");
        // 连接数据库,根据部门编号查询部门的信息。
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = DBUtil.getConnection();
            String sql = "select dename, loc as location from dept where deptno = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, deptno);
            rs = ps.executeQuery();
            // 这个结果集中只有一条记录。
            if(rs.next()){
                String dename = rs.getString("dename");
                String location = rs.getString("location"); // 参数"location"是sql语句查询结果列的列名。
                // 输出动态网页。
                out.print("                部门编号<input type='text' name='deptno' value='"+deptno+"' readonly /><br>");
                out.print("                部门名称<input type='text' name='dename' value='"+dename+"'/><br>");
                out.print("                部门位置<input type='text' name='loc' value='"+location+"'/><br>");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, rs);
        }

        out.print("			<input type='submit' value='修改'/><br>");
        out.print("		</form>");
        out.print("	</body>");
        out.print("</html>");
    }
}

在这里插入图片描述

修改部门

这步是完全实现修改成功的功能!

  1. 从原有基础上的DeptEditServlet类中的动态网页代码form表单跳转目标页action 写成动态的路径。
    在这里插入图片描述

  2. 编写DeptModifyServlet类继承HttpServlet类。然后重写doGet方法。

package com.aimoyudett.oa.web.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
* @Author: 爱摸鱼的TT~
* @Description:
* @Date Created in 2022-11-22 1:34
* @Modified By:
*/
public class DeptEditServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决请求体的中文乱码问题。
        // 获取表单中的数据
        // 连接数据库执行更新语句
        // 更新成功与否判断
    }
}

总体代码:

package com.aimoyudett.oa.web.action;

import com.aimoyudett.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * @Author: 爱摸鱼的TT~
 * @Description:
 * @Date Created in 2022-11-22 11:09
 * @Modified By:
*/
public class DeptModifyServlet extends HttpServlet{

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        // 解决请求体的中文乱码问题。
        request.setCharacterEncoding("UTF-8");

        // 获取表单中的数据
        String deptno = request.getParameter("deptno");
        String dename = request.getParameter("dename");
        String loc = request.getParameter("loc");
        // 连接数据库执行更新语句
        Connection conn = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            conn = DBUtil.getConnection();
            String sql = "update dept set dename = ?, loc = ? where deptno = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, dename);
            ps.setString(2, loc);
            ps.setString(3, deptno);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, null);
        }

        if (count == 1) {
            // 更新成功
            // 跳转到部门列表页面(部门列表页面是通过Java程序动态生成的,所以还需要再次执行另一个Servlet)
            request.getRequestDispatcher("/dept/list").forward(request, response);

            //response.sendRedirect(request.getContextPath() + "/dept/list");
        }else{
            // 更新失败
            request.getRequestDispatcher("/error.html").forward(request, response);
            //response.sendRedirect(request.getContextPath() + "/error.html");
        }
    }
}

在这里插入图片描述

将oa项目中的资源跳转修改为合适的跳转方式(优化)

  • 删除之后,重定向
  • 修改之后,重定向
  • 保存之后,重定向
  • 重定向:
    ○ 成功
    ○ 失败

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

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

相关文章

分布式共识协议 Raft 是如何工作的?

Raft 解决的问题 提供一种共识算法&#xff08;分布式一致性算法&#xff09;。 Paxos是早先的一个分布式共识算法&#xff0c;Paxos 逻辑复杂而难以理解和实现。相比早先的 Paxos&#xff0c; Raft 提供一个容易理解和实现的共识算法&#xff0c;在很多的系统比如 etcd, ozon…

力扣hot100——第3天:11盛最多水的容器、21合并两个有序链表、22括号生成

文章目录1.11盛最多水的容器1.1.题目1.2.解答1.2.1.题解1.2.2.自己对参考题解的进一步解释2.21合并两个有序链表2.1.题目2.2.题解3.22括号生成3.1.题目3.2.题解1.11盛最多水的容器 参考&#xff1a;力扣题目链接&#xff1b;题解 1.1.题目 1.2.解答 1.2.1.题解 这道题目可以…

GIS工具maptalks开发手册(一)——hello world初始化

GIS工具maptalks开发手册(一)——hello world初始化 为何使用maptalks&#xff1f; ​ Maptalks项目是一个HTML5的地图引擎, 基于原生ES6、Javascript开发的二三维一体化地图。 通过二维地图的旋转、倾斜增加三维视角&#xff0c;通过插件化设计, 能与其他图形库echarts、d3.…

微信小程序实战十四:小程序及APP端实现客服功能

文章目录 1.效果预览2.小程序后台添加客服3.小程序代码中集成客服4.APP中添加客服5.企业微信登陆6.获取企业ID值7.设置多客服说明:项目用uni开发的,有小程序版本和APP版本,最开始项目中集成了第三方美洽的客服,2个客服一年收3600,老哥咨询我是否有稍微优惠点的方案,老哥带…

QuEra将研发可重构中性原子量子计算机

&#xff08;图片来源&#xff1a;网络&#xff09; 上个月&#xff0c;借助Amazon Braket&#xff0c;QuEra Computing开始提供对其中性原子量子系统Aquila的访问, Aquila具有256个量子比特。如今&#xff0c;量子公司的数量与日俱增&#xff0c;QuEra是其中之一&#xff0c;它…

java httpclient的digest验证(可恨,找遍全网没有靠谱的,不是少包就是少文件。含泪整理o(╥﹏╥)o~~~~)

背景&#xff1a;调用第三方接口&#xff0c;使用的是digest auth鉴权方式&#xff0c; basic auth和digest auth比较&#xff1a; basic认证是把用户和密码通过base64加密后发送给服务器进行验证。 Basic认证过程简单&#xff0c;每次请求都有发送密码。安全性较低。 为了解决…

[附源码]JAVA毕业设计衡师社团管理系统(系统+LW)

[附源码]JAVA毕业设计衡师社团管理系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

【allegro 17.4软件操作保姆级教程八】布线操作基础之三

目录 1.1扇出操作 1.2差分对过孔间距调整 1.3差分线换层自动添加回流过孔 1.4多人协同操作 1.5导入pin delay 1.6走线导圆弧 1.1扇出操作 关于信号扇出有如下一些需要注意的点&#xff1a; 1、过孔扇出要考虑其间距&#xff0c;要求2个过孔之间保证能过一根信号线&#x…

java+jsp基于ssm的校园OTO超市系统-计算机毕业设计

项目介绍 本网站主要是针对高校学生以超市购物为重点开发的网站。系统从用户上分为三种&#xff1a;卖家、买家和游客。系统从模块分为买家模块和卖家模块&#xff0c;买家模块包括用户注册登录、商品浏览、商品详情、商品加入购物车、购物车中商品删除、购物车商品数量变更、…

vue 微信登录

文章目录前言一、第一步用户授权获取code1、PC扫码方式一方式二&#xff1a;踩坑记录2、移动端微信内置浏览器授权获取code二、第二步 通过code获取access_token三、获取用户个人信息前言 网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 在进行微信…

没想到吧,Spring中还有一招集合注入的写法

Spring作为项目中不可缺少的底层框架&#xff0c;提供的最基础的功能就是bean的管理了。bean的注入相信大家都比较熟悉了&#xff0c;但是有几种不太常用到的集合注入方式&#xff0c;可能有的同学会不太了解&#xff0c;今天我们就通过实例看看它的使用。 首先&#xff0c;声…

[附源码]JAVA毕业设计衡水特产展销系统(系统+LW)

[附源码]JAVA毕业设计衡水特产展销系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

正则匹配删除指令

// 删除以 SameSeed 开头的整行 ^SameSeed.*$执行前&#xff1a; 执行后&#xff1a; 这样我们就可以在代码发布时删除代码中所有的调试信息&#xff0c;使代码中不包含任何 DEADCODE&#xff0c;但这样会导致一个问题&#xff0c;就是会出现一个空行&#xff0c;同时代码中…

生命在于学习——docker逃逸

注意&#xff1a;本篇文章仅用于学习记录&#xff0c;不得用于其他用途。 一、docker逃逸 docker逃逸就是从当前docker容器权限中逃逸出来&#xff0c;获得宿主机的权限。 二、常见的逃逸方法 1、配置不当引起的逃逸 &#xff08;1&#xff09;Docker Remote API未授权访问…

jsp汽车租赁管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 jsp汽车租赁管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库sqlserver2008&#xff…

应用现代化方案实践,重塑企业应用价值—工业篇

应用现代化是指通过更现代和新兴的IT技术来改造或部署传统应用&#xff0c;从而使应用更适合企业发展的一种优化方式。在企业上云背景下&#xff0c;应用现代化改造是将遗留的传统应用改造升级到云计算环境&#xff0c;从而兼容更现代和新兴的计算技术的过程。这种改造升级的同…

软件测试分类

1、是否关注源代码 黑盒测试 - 不关注代码逻辑&#xff0c;只关注输入输出 白盒测试 - 看代码的具体实现逻辑 灰盒测试 - 既关注输入输出&#xff0c;也关注代码 2、基于测试的不同阶段 单元测试 - 在底层进行的测试&#xff0c;又称模块测试&#xff08;module testing&a…

python数组处理方法

一、数组对象的属性 数组的大小&#xff08;元素个数&#xff09; array.size数组的维度 array.ndim数组元素的数据类型 array.dtype数组的形状 array.shape数组中每个元素占用的内存空间 array.itemsize数组所有元素占用的内存空间&#xff08;字节&#xff09; array.nbytes…

实验7 Spark初级编程实践

一、实验目的 掌握使用 Spark 访问本地文件和 HDFS 文件的方法掌握 Spark 应用程序的编写、编译和运行方法 二、实验平台 操作系统&#xff1a;Ubuntu18.04&#xff08;或 Ubuntu16.04&#xff09;Spark 版本&#xff1a;2.4.0Hadoop 版本&#xff1a;3.1.3 三、实验内容和…

举个栗子~Alteryx 技巧(3):离线激活 Alteryx Designer

之前我们分享了 如何下载并安装 Alteryx Designer。然而&#xff0c;对于内网环境的用户来说&#xff0c;就无法使用上述方法来激活软件了&#xff01;那么&#xff0c;不能连接外网的电脑该如何离线激活 Alteryx Designer 呢&#xff1f; 本期《举个栗子&#xff01;Alteryx …