当前位置:首页 > 技术 > 正文内容

基于JavaWeb的流浪动物收容所管理系统设计与实现

访客 技术 2026年9月28日 13

系统功能预览

系统界面展示

项目背景与需求分析

现代宠物收容机构亟需信息化管理手段,以应对日益增长的动物收养、寄养及领养需求。传统手工记录方式效率低下、易出错,且难以支持多维度数据查询与统计。本系统旨在通过构建一套完整的Web管理平台,提升收容所运营效率,优化用户服务体验,同时增强数据安全性与可追溯性。

技术架构与开发环境

  • 后端语言: Java (JDK 11+)
  • Web容器: Apache Tomcat 9+
  • 数据库: MySQL 8.0,使用Navicat Premium进行管理
  • IDE: IntelliJ IDEA 或 Eclipse
  • 架构模式: Servlet + JSP + JavaBean(MVC三层结构)
  • 前端组件:
    • My97DatePicker:日期选择控件
    • FCKeditor / UEditor:富文本编辑器
    • DWR:实现AJAX异步调用Java方法
    • JSTL标签库:简化JSP页面逻辑

核心数据表设计

动物收养记录表(t_adoption)

字段名类型描述
idINT主键ID
receipt_noVARCHAR(50)收养单据编号
adopt_timeDATETIME收养时间
total_feeINT费用总额
handlerVARCHAR(50)经办人
remarkVARCHAR(50)备注信息

动物分类表(t_category)

字段名类型描述
idINT分类ID
nameVARCHAR(50)分类名称
descriptionVARCHAR(5000)详细说明

后端控制器重构示例

package controller;

import model.Animal;
import service.CategoryService;
import util.DatabaseUtil;

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.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/animal")
public class AnimalController extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        switch (action != null ? action : "") {
            case "list":
                listAnimals(req, resp);
                break;
            case "delete":
                deleteAnimal(req, resp);
                break;
            case "editForm":
                showEditForm(req, resp);
                break;
            case "viewPhoto":
                viewPhoto(req, resp);
                break;
            default:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        }
    }

    private void listAnimals(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int page = getPageNumber(req);
        final int PAGE_SIZE = 10;

        // 获取总记录数
        int totalRecords = getTotalAnimalCount();
        int totalPages = (int) Math.ceil((double) totalRecords / PAGE_SIZE);

        // 查询当前页数据
        List<Animal> animals = fetchPageData(page, PAGE_SIZE);

        req.setAttribute("animals", animals);
        req.setAttribute("currentPage", page);
        req.setAttribute("totalPages", totalPages);
        req.setAttribute("pageSize", PAGE_SIZE);

        req.getRequestDispatcher("/WEB-INF/views/animal/list.jsp").forward(req, resp);
    }

    private List<Animal> fetchPageData(int page, int pageSize) {
        List<Animal> list = new ArrayList<>();
        String sql = "SELECT * FROM t_animal WHERE is_deleted = 0 ORDER BY id DESC LIMIT ?, ?";
        try (DatabaseUtil db = new DatabaseUtil()) {
            ResultSet rs = db.executeQuery(sql, (page - 1) * pageSize, pageSize);
            while (rs.next()) {
                Animal animal = new Animal();
                animal.setId(rs.getInt("id"));
                animal.setCategoryId(rs.getInt("category_id"));
                animal.setName(rs.getString("name"));
                animal.setOrigin(rs.getString("origin"));
                animal.setGender(rs.getString("gender"));
                animal.setWeight(rs.getString("weight"));
                animal.setAge(rs.getString("age"));
                animal.setPhotoPath(rs.getString("photo"));
                animal.setCategoryName(CategoryService.getCategoryName(rs.getInt("category_id")));
                list.add(animal);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    private void deleteAnimal(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        String sql = "UPDATE t_animal SET is_deleted = 1 WHERE id = ?";
        try (DatabaseUtil db = new DatabaseUtil()) {
            db.executeUpdate(sql, id);
            req.getSession().setAttribute("message", "删除成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        resp.sendRedirect(req.getContextPath() + "/animal?action=list");
    }

    private void showEditForm(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        Animal animal = getAnimalById(id);
        req.setAttribute("animal", animal);
        req.getRequestDispatcher("/WEB-INF/views/animal/edit.jsp").forward(req, resp);
    }

    private Animal getAnimalById(int id) {
        Animal animal = null;
        String sql = "SELECT * FROM t_animal WHERE id = ?";
        try (DatabaseUtil db = new DatabaseUtil()) {
            ResultSet rs = db.executeQuery(sql, id);
            if (rs.next()) {
                animal = new Animal();
                animal.setId(rs.getInt("id"));
                animal.setCategoryId(rs.getInt("category_id"));
                animal.setName(rs.getString("name"));
                animal.setOrigin(rs.getString("origin"));
                animal.setGender(rs.getString("gender"));
                animal.setWeight(rs.getString("weight"));
                animal.setAge(rs.getString("age"));
                animal.setPhotoPath(rs.getString("photo"));
                animal.setRemark(rs.getString("remark"));
                animal.setCategoryName(CategoryService.getCategoryName(rs.getInt("category_id")));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return animal;
    }

    private void viewPhoto(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        Animal animal = getAnimalById(id);
        req.setAttribute("animal", animal);
        req.getRequestDispatcher("/WEB-INF/views/animal/photo.jsp").forward(req, resp);
    }

    private int getPageNumber(HttpServletRequest req) {
        String p = req.getParameter("page");
        return (p == null || p.isEmpty()) ? 1 : Integer.parseInt(p);
    }

    private int getTotalAnimalCount() {
        String sql = "SELECT COUNT(*) as total FROM t_animal WHERE is_deleted = 0";
        try (DatabaseUtil db = new DatabaseUtil()) {
            ResultSet rs = db.executeQuery(sql);
            if (rs.next()) return rs.getInt("total");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}

前端列表页优化示例

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String ctx = request.getContextPath();
%>

<!DOCTYPE html>
<html>
<head>
    <title>动物管理</title>
    <link rel="stylesheet" href="<%=ctx%>/css/style.css">
    <script src="<%=ctx%>/js/utils.js"></script>
</head>
<body>

<div class="toolbar">
    <button onclick="navigateTo('<%=ctx%>/animal/add')">新增动物</button>
    <form method="get" action="<%=ctx%>/animal" style="display:inline-block;">
        <input type="hidden" name="action" value="list"/>
        <input type="text" name="keyword" placeholder="搜索名称..." />
        <button type="submit">🔍</button>
    </form>
</div>

<table class="data-table">
    <thead>
        <tr>
            <th>类别</th>
            <th>名称</th>
            <th>产地</th>
            <th>性别</th>
            <th>体重(kg)</th>
            <th>年龄</th>
            <th>备注</th>
            <th>图片</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach var="item" items="${animals}">
        <tr>
            <td>${item.categoryName}</td>
            <td>${item.name}</td>
            <td>${item.origin}</td>
            <td>${item.gender}</td>
            <td>${item.weight}</td>
            <td>${item.age}</td>
            <td>${item.remark}</td>
            <td>
                <c:if test="${not empty item.photoPath}">
                    <a href="#" onclick="showImageModal(${item.id})">📷 查看</a>
                </c:if>
            </td>
            <td>
                <button onclick="editAnimal(${item.id})">✏️ 编辑</button>
                <button onclick="confirmDelete(${item.id})">🗑️ 删除</button>
            </td>
        </tr>
        </c:forEach>
    </tbody>
</table>

<div class="pagination">
    <span>共 ${totalRecords} 条记录,${totalPages} 页,当前第 ${currentPage} 页</span>
    <a href="?action=list&page=1">首页</a>
    <a href="?action=list&page=${currentPage > 1 ? currentPage - 1 : 1}">上一页</a>
    <a href="?action=list&page=${currentPage < totalPages ? currentPage + 1 : totalPages}">下一页</a>
    <a href="?action=list&page=${totalPages}">尾页</a>
    跳至第 <input type="number" min="1" max="${totalPages}" value="${currentPage}" onchange="jumpToPage(this.value)" /> 页
</div>

<script>
function confirmDelete(id) {
    if (confirm('确定要删除该动物记录吗?')) {
        window.location.href = '<%=ctx%>/animal?action=delete&id=' + id;
    }
}

function editAnimal(id) {
    window.location.href = '<%=ctx%>/animal/editForm?id=' + id;
}

function showImageModal(id) {
    const popup = new Popup({
        contentType: 1,
        width: 400,
        height: 300,
        isReloadOnClose: false
    });
    popup.setContent("contentUrl", "<%=ctx%>/animal?action=viewPhoto&id=" + id);
    popup.setContent("title", "动物照片");
    popup.build();
    popup.show();
}

function navigateTo(url) {
    window.location.href = url;
}

function jumpToPage(pageNum) {
    window.location.href = '?action=list&page=' + pageNum;
}
</script>

</body>
</html>
标签: JavaWeb

相关文章

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

PHPStan 有什么用?怎么用?

PHPStan 是一个 PHP 的静态分析工具,在不运行代码的情况下就能帮你发现潜在问题,比如:传错类型(把 string 传给接受 int 的函数)访问不存在的属性 / 方法null 没处理好永远不会执行到的代码数组 key/值类型不一致返回值不符合声明注释和真实类型不匹配它非常适合:想提升代码质量、减少线上 bug、统一团队风格的人(尤其是中大型项目)。一、PHPStan 有什么用(通俗点说)...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。