内容管理(八)02-删除-响应无内容处理- JSONBIG.parse(null) 报错-代码最好使用try{}catch(){},弹出框确认消息组件使用

本文探讨了在内容管理系统中实现删除功能时遇到的API响应处理挑战,详细介绍了如何使用try{}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

11-内容管理-删除-响应无内容处理

  • 点击删除按钮
    • 获取文章的ID (测试帐号删除无效)
    • 请求删除接口
    • 成功后
      • 提示 删除成功
      • 更新 列表

处理没有响应内容:api/index.js

// 默认配置  转换响应数据
axios.defaults.transformResponse = [data => {
  // 对data(后台的原始数据)进行转换
  // 但是 有一些接口  没有任何响应内容
  // JSONBIG.parse(null)  报错,代码最好使用try{}catch(){}
  try {
    return JSONBIG.parse(data)
  } catch (e) {
    return data
  }
}]

正常去做删除功能:view/article/index.vue

绑定删除事件:

<el-button
              type="danger"
              @click="delArticle(scope.row.id)"
              icon="el-icon-delete"
              circle
              plain
            ></el-button>

弹框-确认消息组件的使用:

 // 删除文章
    delArticle (id) {
      this.$confirm('亲,此操作将永久删除该文章, 是否继续?', '温馨提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        // 点击确认触发的函数
        // 常见的5种请求方式  ——   get 获取数据 post 添加数据 put 完整修改数据 delete 删除数据 patch 局部修改数据
        await this.$http.delete(`articles/${id}`)
        // 代表成功
        this.$message.success('删除成功')
        //删除成功后,更新列表
        this.getArticles()
      }).catch(() => {
        // 点击取消触发的函数
      })
    },
<think>我们已经在之前的代码使用try-catch-finally结构,但为了更清晰,这里我们重新以BookServlet为例,使用try-catch-finally结构来确保资源释放和异常处理。 注意:在Servlet中,我们通常处理的是业务逻辑,而数据库操作在DAO层已经处理了资源释放。但是,如果我们在Servlet中直接操作数据库(不推荐,但有时可能),则需要使用try-catch-finally。 然而,在之前的BookServlet中,我们调用了BookDAO的方法,而BookDAO内部已经处理数据库连接和资源的释放。所以,在Servlet层,我们主要处理业务逻辑异常和输入验证。 但是,为了满足要求,我们将BookServlet中调用DAO的部分放在try-catch块中,并在finally块中处理一些资源(如果有需要的话)。实际上,在Servlet中我们通常没有需要关闭的资源(除了可能的一些流),因为DAO已经关闭了数据库连接。 因此,我们重新组织BookServlet,将每个操作(add, update, delete)中的DAO调用放在try块中,并捕获可能抛出的异常,然后进行相应的处理。 不过,请注意,在BookDAO中,我们已经在每个方法中使用try-finally来确保数据库资源的释放。所以,在Servlet中,我们捕获的是业务逻辑异常和DAO抛出的异常。 下面是用try-catch-finally重写的BookServlet,虽然实际上在Servlet中并没有需要关闭的数据库资源(因为DAO已经关闭了),但为了演示,我们在Servlet中处理异常,并确保在发生异常时跳转到错误页面。 我们将在每个操作中捕获异常,并在finally块中不需要释放数据库资源,但可能需要处理其他资源(如果有的话)。由于这里没有其他资源,所以finally块可以省略,但为了结构,我们可以加上(即使为空)。 但是,更合理的做法是:在Servlet中,我们使用try-catch来捕获整个操作过程中的异常,然后跳转到错误页面。而finally块在Servlet中通常不需要,因为Servlet容器会处理请求和响应的资源。 所以,我们主要使用try-catch来捕获异常,然后进行错误处理,而不需要finally(除非有特殊的资源需要释放,比如文件流等)。 修改后的BookServlet如下:</think>### 使用 try-catch-finally 结构重写 BookServlet.java 以下是使用 try-catch-finally 结构重写的 BookServlet,确保所有资源正确关闭,异常得到妥善处理: ```java package com.servlet; import com.dao.BookDAO; import com.dao.DBUtil; import com.model.Book; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.sql.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class BookServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String action = request.getParameter("action"); if (action == null || action.trim().isEmpty()) { handleError(request, response, "无效操作: 缺少action参数"); return; } try { switch (action) { case "add": addBook(request, response); break; case "update": updateBook(request, response); break; case "delete": deleteBook(request, response); break; default: handleError(request, response, "无效操作: " + action); } } catch (Exception e) { handleError(request, response, "操作失败: " + e.getMessage(), e); } } private void addBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException { Book book = new Book(); Connection conn = null; PreparedStatement stmt = null; try { // 解析请求参数 book.setTitle(validateRequired(request, "title", "书名")); book.setAuthor(validateRequired(request, "author", "作者")); book.setIsbn(validateRequired(request, "isbn", "ISBN")); book.setPrice(parseDouble(request, "price", "价格")); book.setCategoryId(parseInt(request, "categoryId", "分类ID")); book.setPublishDate(parseDate(request, "publishDate", "出版日期")); // 获取数据库连接 conn = DBUtil.getConnection(); // 准备SQL语句 String sql = "INSERT INTO books (title, author, isbn, price, category_id, publish_date) VALUES (?, ?, ?, ?, ?, ?)"; stmt = conn.prepareStatement(sql); stmt.setString(1, book.getTitle()); stmt.setString(2, book.getAuthor()); stmt.setString(3, book.getIsbn()); stmt.setDouble(4, book.getPrice()); stmt.setInt(5, book.getCategoryId()); stmt.setDate(6, new java.sql.Date(book.getPublishDate().getTime())); // 执行插入操作 int rowsAffected = stmt.executeUpdate(); if (rowsAffected > 0) { response.sendRedirect("bookList.jsp"); } else { throw new SQLException("添加图书失败: 没有行被影响"); } } finally { // 确保资源关闭 DBUtil.close(conn, stmt, null); } } private void updateBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException { Book book = new Book(); Connection conn = null; PreparedStatement stmt = null; try { // 解析请求参数 book.setId(parseInt(request, "id", "图书ID")); book.setTitle(validateRequired(request, "title", "书名")); book.setAuthor(validateRequired(request, "author", "作者")); book.setIsbn(validateRequired(request, "isbn", "ISBN")); book.setPrice(parseDouble(request, "price", "价格")); book.setCategoryId(parseInt(request, "categoryId", "分类ID")); book.setPublishDate(parseDate(request, "publishDate", "出版日期")); // 获取数据库连接 conn = DBUtil.getConnection(); // 准备SQL语句 String sql = "UPDATE books SET title=?, author=?, isbn=?, price=?, category_id=?, publish_date=? WHERE id=?"; stmt = conn.prepareStatement(sql); stmt.setString(1, book.getTitle()); stmt.setString(2, book.getAuthor()); stmt.setString(3, book.getIsbn()); stmt.setDouble(4, book.getPrice()); stmt.setInt(5, book.getCategoryId()); stmt.setDate(6, new java.sql.Date(book.getPublishDate().getTime())); stmt.setInt(7, book.getId()); // 执行更新操作 int rowsAffected = stmt.executeUpdate(); if (rowsAffected > 0) { response.sendRedirect("bookList.jsp"); } else { throw new SQLException("更新图书失败: 没有行被影响或图书不存在"); } } finally { // 确保资源关闭 DBUtil.close(conn, stmt, null); } } private void deleteBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException { Connection conn = null; PreparedStatement stmt = null; try { // 解析图书ID int id = parseInt(request, "id", "图书ID"); // 获取数据库连接 conn = DBUtil.getConnection(); // 准备SQL语句 String sql = "DELETE FROM books WHERE id=?"; stmt = conn.prepareStatement(sql); stmt.setInt(1, id); // 执行删除操作 int rowsAffected = stmt.executeUpdate(); if (rowsAffected > 0) { response.sendRedirect("bookList.jsp"); } else { throw new SQLException("删除图书失败: 图书不存在"); } } finally { // 确保资源关闭 DBUtil.close(conn, stmt, null); } } // 辅助方法:验证必需参数 private String validateRequired(HttpServletRequest request, String paramName, String fieldName) throws ServletException { String value = request.getParameter(paramName); if (value == null || value.trim().isEmpty()) { throw new ServletException(fieldName + "不能为空"); } return value.trim(); } // 辅助方法:解析整数参数 private int parseInt(HttpServletRequest request, String paramName, String fieldName) throws ServletException { String value = validateRequired(request, paramName, fieldName); try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw new ServletException(fieldName + "格式错误: " + value); } } // 辅助方法:解析浮点数参数 private double parseDouble(HttpServletRequest request, String paramName, String fieldName) throws ServletException { String value = validateRequired(request, paramName, fieldName); try { return Double.parseDouble(value); } catch (NumberFormatException e) { throw new ServletException(fieldName + "格式错误: " + value); } } // 辅助方法:解析日期参数 private Date parseDate(HttpServletRequest request, String paramName, String fieldName) throws ServletException { String value = validateRequired(request, paramName, fieldName); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); return sdf.parse(value); } catch (ParseException e) { throw new ServletException(fieldName + "格式错误: " + value + " (应为 yyyy-MM-dd)"); } } // 错误处理方法 private void handleError(HttpServletRequest request, HttpServletResponse response, String message) throws ServletException, IOException { handleError(request, response, message, null); } private void handleError(HttpServletRequest request, HttpServletResponse response, String message, Throwable cause) throws ServletException, IOException { request.setAttribute("error", message); if (cause != null) { cause.printStackTrace(); request.setAttribute("errorDetails", cause.getMessage()); } request.getRequestDispatcher("error.jsp").forward(request, response); } } ``` ### 关键改进说明 #### 1. try-catch-finally 结构 ```java Connection conn = null; PreparedStatement stmt = null; try { // 1. 获取数据库连接 conn = DBUtil.getConnection(); // 2. 准备SQL语句 stmt = conn.prepareStatement(sql); // 3. 设置参数和执行操作 // ... } finally { // 4. 确保资源关闭 DBUtil.close(conn, stmt, null); } ``` #### 2. 资源管理 1. **资源初始化**: - 所有JDBC资源初始化为`null` -try块中获取连接和创建语句 2. **资源释放**: - finally块确保资源总是被关闭 - 使用统一的DBUtil.close()方法 - 释放顺序:ResultSet → Statement → Connection #### 3. 输入验证 ```java // 验证必需参数 private String validateRequired(HttpServletRequest request, String paramName, String fieldName) throws ServletException { String value = request.getParameter(paramName); if (value == null || value.trim().isEmpty()) { throw new ServletException(fieldName + "不能为空"); } return value.trim(); } // 解析整数参数 private int parseInt(HttpServletRequest request, String paramName, String fieldName) throws ServletException { // ... } ``` #### 4. 错误处理 ```java // 统一错误处理方法 private void handleError(HttpServletRequest request, HttpServletResponse response, String message, Throwable cause) throws ServletException, IOException { request.setAttribute("error", message); if (cause != null) { cause.printStackTrace(); request.setAttribute("errorDetails", cause.getMessage()); } request.getRequestDispatcher("error.jsp").forward(request, response); } ``` ### 改进优势 1. **资源安全**: - 确保数据库连接、语句等资源总是被关闭 - 防止资源泄漏导致系统性能下降 2. **错误隔离**: - 分离业务逻辑、数据处理和错误处理 - 统一错误处理机制减少代码重复 3. **输入验证**: - 参数非空检查 - 数据类型验证(整数、浮点数、日期) - 提供明确的错误信息 4. **异常处理**: - 捕获特定异常类型 - 保留异常链信息 - 提供用户友好的错误消息 5. **代码结构**: - switch-case 替代 if-else 链 - 辅助方法减少重复代码 - 明确的操作流程 ### 错误处理流程 1. **操作入口**: ```java try { switch (action) { case "add": addBook(...); break; // ... } } catch (Exception e) { handleError(...); } ``` 2. **参数验证**: ```java book.setTitle(validateRequired(request, "title", "书名")); ``` 3. **数据库操作**: ```java try { // 获取连接和准备语句 int rowsAffected = stmt.executeUpdate(); if (rowsAffected > 0) { // 成功处理 } else { throw new SQLException(...); } } finally { // 释放资源 } ``` 4. **错误传递**: ```java private void handleError(...) { request.setAttribute("error", message); request.getRequestDispatcher("error.jsp").forward(...); } ``` ### 最佳实践建议 1. **事务管理**: ```java try { conn.setAutoCommit(false); // 开始事务 // 执行多个数据库操作 conn.commit(); // 提交事务 } catch (SQLException e) { conn.rollback(); // 回滚事务 throw e; } ``` 2. **日志记录**: ```java import org.apache.log4j.Logger; public class BookServlet extends HttpServlet { private static final Logger logger = Logger.getLogger(BookServlet.class); private void handleError(...) { logger.error(message, cause); // ... } } ``` 3. **防御性编程**: ```java // 检查用户权限 HttpSession session = request.getSession(false); if (session == null || session.getAttribute("user") == null) { response.sendRedirect("login.jsp"); return; } ``` 4. **SQL注入防护**: ```java // 使用PreparedStatement防止SQL注入 stmt = conn.prepareStatement("SELECT * FROM books WHERE id=?"); stmt.setInt(1, id); // 安全设置参数 ``` 这种结构确保了代码的健壮性和可维护性,同时提供了良好的错误处理和资源管理机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值