基于JSP+Servlet的新闻发布与管理系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-143 浏览

文章摘要

本项目是一款基于JSP+Servlet技术栈构建的新闻发布与管理系统,旨在为中小型媒体机构或内容运营团队提供一套功能完整、开发高效、维护便捷的网站内容管理解决方案。系统核心解决了传统静态网页更新困难、内容管理效率低下以及动态信息发布的技术门槛问题。通过将新闻内容结构化存储于数据库,并实现基于Web的...

在当今信息爆炸的时代,新闻内容的快速发布与高效管理成为各类组织机构的核心需求。传统的静态网页更新方式不仅技术门槛高,而且效率低下,难以满足信息实时性的要求。为此,一套基于JSP+Servlet技术栈构建的新闻发布与管理系统应运而生,该系统被命名为“新闻矩阵内容管理平台”,旨在为中小型媒体机构提供一套功能完整、开发高效、维护便捷的网站内容管理解决方案。

该系统严格遵循Java EE经典的Model 1架构模式,采用分层设计思想,将表示层、控制层和模型层清晰分离。JSP页面负责前端动态内容渲染,Servlet作为核心控制器处理业务逻辑调度,JDBC实现数据持久化操作。这种架构确保了系统的高内聚低耦合特性,使得开发维护更加规范化。

系统架构与技术栈解析

新闻矩阵内容管理平台采用典型的三层架构设计,每层各司其职,共同构建了稳定可靠的系统基础。

表示层使用JSP技术结合HTML、CSS和JavaScript,实现了丰富的用户交互界面。JSP的内置对象如request、session等为数据传递和状态管理提供了便利,同时通过JavaBean封装业务数据,确保了前后端数据交互的规范性。

控制层基于Servlet技术实现,充当系统的"交通指挥中心"。每个用户请求都经由对应的Servlet进行处理,根据业务需求调用相应的模型层组件,最终将结果返回给表示层。这种集中式的请求处理机制大大提高了系统的可维护性。

数据持久层采用JDBC直接操作MySQL数据库,通过DAO模式封装所有数据库CRUD操作。这种设计使得业务逻辑与数据访问逻辑完全分离,当需要更换数据库时,只需修改DAO实现即可,大大提升了系统的可扩展性。

数据库设计深度剖析

系统的数据库设计体现了严谨的数据建模思想,以下是几个核心表的详细分析:

新闻分类表设计

CREATE TABLE `news_category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_name` varchar(50) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `status` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `uk_category_name` (`category_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表设计具有以下技术亮点:

  • 使用自增主键category_id确保唯一性和查询性能
  • category_name字段设置唯一约束,防止分类名称重复
  • 采用timestamp类型的时间字段,自动记录创建和更新时间
  • status字段使用tinyint类型实现软删除功能,避免物理删除带来的数据丢失风险

新闻内容表设计

CREATE TABLE `news_content` (
  `news_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(200) NOT NULL,
  `content` text NOT NULL,
  `category_id` int(11) NOT NULL,
  `author` varchar(50) NOT NULL,
  `publish_time` datetime NOT NULL,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `view_count` int(11) NOT NULL DEFAULT '0',
  `status` tinyint(1) NOT NULL DEFAULT '0',
  `is_top` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`news_id`),
  KEY `idx_category_id` (`category_id`),
  KEY `idx_publish_time` (`publish_time`),
  KEY `idx_status` (`status`),
  CONSTRAINT `fk_news_category` FOREIGN KEY (`category_id`) REFERENCES `news_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

此表设计体现了高性能数据库设计的多个重要原则:

  • 建立了合理的索引策略,在category_idpublish_timestatus字段上创建索引,优化查询性能
  • 使用外键约束确保数据完整性,防止无效的分类ID
  • view_count字段默认值为0,自动统计新闻浏览量
  • is_top字段实现置顶功能,重要的新闻可以优先显示
  • 文本内容使用text类型,支持大容量新闻内容存储

用户评论表设计

CREATE TABLE `news_comment` (
  `comment_id` int(11) NOT NULL AUTO_INCREMENT,
  `news_id` int(11) NOT NULL,
  `user_name` varchar(50) NOT NULL,
  `content` text NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `ip_address` varchar(45) NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`comment_id`),
  KEY `idx_news_id` (`news_id`),
  KEY `idx_create_time` (`create_time`),
  CONSTRAINT `fk_comment_news` FOREIGN KEY (`news_id`) REFERENCES `news_content` (`news_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

评论表设计注重用户体验和数据追踪:

  • 记录用户IP地址,便于管理恶意评论
  • 时间戳自动记录评论时间,确保时间准确性
  • 与新闻内容表建立外键关系,保证评论数据的有效性
  • 状态字段支持评论审核机制,防止不当内容展示

核心功能实现详解

新闻分类管理功能

新闻分类是内容组织的基础,系统提供了完整的分类管理功能。管理员可以通过友好的界面进行分类的增删改查操作。

Servlet控制器实现:

@WebServlet("/admin/category")
public class CategoryServlet extends HttpServlet {
    private CategoryDAO categoryDAO;
    
    @Override
    public void init() throws ServletException {
        categoryDAO = new CategoryDAOImpl();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        if ("list".equals(action)) {
            listCategories(request, response);
        } else if ("edit".equals(action)) {
            showEditForm(request, response);
        } else if ("delete".equals(action)) {
            deleteCategory(request, response);
        } else {
            listCategories(request, response);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        if ("create".equals(action)) {
            createCategory(request, response);
        } else if ("update".equals(action)) {
            updateCategory(request, response);
        }
    }
    
    private void listCategories(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        List<Category> categories = categoryDAO.findAll();
        request.setAttribute("categories", categories);
        RequestDispatcher dispatcher = request.getRequestDispatcher("/admin/category-list.jsp");
        dispatcher.forward(request, response);
    }
    
    private void createCategory(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        String categoryName = request.getParameter("categoryName");
        Category category = new Category();
        category.setCategoryName(categoryName);
        categoryDAO.create(category);
        response.sendRedirect("category?action=list");
    }
}

DAO数据访问层实现:

public class CategoryDAOImpl implements CategoryDAO {
    private Connection connection;
    
    public CategoryDAOImpl() {
        connection = DatabaseConnection.getConnection();
    }
    
    @Override
    public List<Category> findAll() {
        List<Category> categories = new ArrayList<>();
        String sql = "SELECT * FROM news_category WHERE status = 1 ORDER BY create_time DESC";
        
        try (PreparedStatement statement = connection.prepareStatement(sql);
             ResultSet resultSet = statement.executeQuery()) {
            
            while (resultSet.next()) {
                Category category = new Category();
                category.setCategoryId(resultSet.getInt("category_id"));
                category.setCategoryName(resultSet.getString("category_name"));
                category.setCreateTime(resultSet.getTimestamp("create_time"));
                categories.add(category);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return categories;
    }
    
    @Override
    public void create(Category category) {
        String sql = "INSERT INTO news_category (category_name) VALUES (?)";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setString(1, category.getCategoryName());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

新闻分类管理

新闻发布与编辑功能

新闻发布是系统的核心功能,支持富文本编辑、图片上传、格式排版等高级特性。

新闻发布Servlet实现:

@WebServlet("/admin/news")
public class NewsServlet extends HttpServlet {
    private NewsDAO newsDAO;
    private CategoryDAO categoryDAO;
    
    @Override
    public void init() throws ServletException {
        newsDAO = new NewsDAOImpl();
        categoryDAO = new CategoryDAOImpl();
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        
        if ("publish".equals(action)) {
            publishNews(request, response);
        } else if ("update".equals(action)) {
            updateNews(request, response);
        }
    }
    
    private void publishNews(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        String title = request.getParameter("title");
        String content = request.getParameter("content");
        int categoryId = Integer.parseInt(request.getParameter("categoryId"));
        String author = request.getParameter("author");
        
        News news = new News();
        news.setTitle(title);
        news.setContent(content);
        news.setCategoryId(categoryId);
        news.setAuthor(author);
        news.setPublishTime(new Date());
        news.setStatus(1);
        
        newsDAO.create(news);
        response.sendRedirect("news?action=list");
    }
    
    private void updateNews(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        int newsId = Integer.parseInt(request.getParameter("newsId"));
        String title = request.getParameter("title");
        String content = request.getParameter("content");
        int categoryId = Integer.parseInt(request.getParameter("categoryId"));
        
        News news = newsDAO.findById(newsId);
        if (news != null) {
            news.setTitle(title);
            news.setContent(content);
            news.setCategoryId(categoryId);
            newsDAO.update(news);
        }
        response.sendRedirect("news?action=list");
    }
}

新闻实体类设计:

public class News {
    private int newsId;
    private String title;
    private String content;
    private int categoryId;
    private String author;
    private Date publishTime;
    private Date updateTime;
    private int viewCount;
    private int status;
    private int isTop;
    
    // 构造函数
    public News() {}
    
    // Getter和Setter方法
    public int getNewsId() { return newsId; }
    public void setNewsId(int newsId) { this.newsId = newsId; }
    
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
    
    public int getCategoryId() { return categoryId; }
    public void setCategoryId(int categoryId) { this.categoryId = categoryId; }
    
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
    
    public Date getPublishTime() { return publishTime; }
    public void setPublishTime(Date publishTime) { this.publishTime = publishTime; }
    
    public int getViewCount() { return viewCount; }
    public void setViewCount(int viewCount) { this.viewCount = viewCount; }
    
    public int getStatus() { return status; }
    public void setStatus(int status) { this.status = status; }
    
    public int getIsTop() { return isTop; }
    public void setIsTop(int isTop) { this.isTop = isTop; }
}

新闻管理界面

前台新闻展示功能

前台页面负责向普通用户展示新闻内容,支持分类浏览、搜索、分页等功能。

新闻列表展示JSP页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<div class="news-list">
    <c:forEach var="news" items="${newsList}">
        <div class="news-item">
            <h3 class="news-title">
                <a href="news?action=detail&id=${news.newsId}">
                    <c:if test="${news.isTop == 1}">
                        <span class="badge badge-warning">置顶</span>
                    </c:if>
                    ${news.title}
                </a>
            </h3>
            <div class="news-meta">
                <span class="author">作者:${news.author}</span>
                <span class="category">分类:${news.categoryName}</span>
                <span class="time">
                    发布时间:<fmt:formatDate value="${news.publishTime}" pattern="yyyy-MM-dd HH:mm"/>
                </span>
                <span class="views">浏览量:${news.viewCount}</span>
            </div>
            <div class="news-summary">
                ${news.content.length() > 200 ? 
                  news.content.substring(0, 200) + "..." : news.content}
            </div>
        </div>
    </c:forEach>
    
    <!-- 分页控件 -->
    <nav aria-label="Page navigation">
        <ul class="pagination">
            <c:if test="${currentPage > 1}">
                <li class="page-item">
                    <a class="page-link" href="?page=${currentPage - 1}">上一页</a>
                </li>
            </c:if>
            
            <c:forEach begin="1" end="${totalPages}" var="i">
                <li class="page-item ${i == currentPage ? 'active' : ''}">
                    <a class="page-link" href="?page=${i}">${i}</a>
                </li>
            </c:forEach>
            
            <c:if test="${currentPage < totalPages}">
                <li class="page-item">
                    <a class="page-link" href="?page=${currentPage + 1}">下一页</a>
                </li>
            </c:if>
        </ul>
    </nav>
</div>

新闻详情页Servlet:

@WebServlet("/news")
public class FrontNewsServlet extends HttpServlet {
    private NewsDAO newsDAO;
    
    @Override
    public void init() throws ServletException {
        newsDAO = new NewsDAOImpl();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        if ("detail".equals(action)) {
            showNewsDetail(request, response);
        } else if ("list".equals(action)) {
            showNewsList(request, response);
        } else if ("category".equals(action)) {
            showNewsByCategory(request, response);
        }
    }
    
    private void showNewsDetail(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        int newsId = Integer.parseInt(request.getParameter("id"));
        News news = newsDAO.findById(newsId);
        
        if (news != null) {
            // 更新浏览量
            newsDAO.incrementViewCount(newsId);
            request.setAttribute("news", news);
            RequestDispatcher dispatcher = request.getRequestDispatcher("/news-detail.jsp");
            dispatcher.forward(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
    }
}

新闻详情页

用户评论系统

评论系统增强了用户互动性,支持评论发布、回复、审核等功能。

评论功能Servlet实现:

@WebServlet("/comment")
public class CommentServlet extends HttpServlet {
    private CommentDAO commentDAO;
    
    @Override
    public void init() throws ServletException {
        commentDAO = new CommentDAOImpl();
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        if ("add".equals(action)) {
            addComment(request, response);
        }
    }
    
    private void addComment(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        int newsId = Integer.parseInt(request.getParameter("newsId"));
        String userName = request.getParameter("userName");
        String content = request.getParameter("content");
        String ipAddress = request.getRemoteAddr();
        
        Comment comment = new Comment();
        comment.setNewsId(newsId);
        comment.setUserName(userName);
        comment.setContent(content);
        comment.setIpAddress(ipAddress);
        
        commentDAO.create(comment);
        
        // 返回新闻详情页
        response.sendRedirect("news?action=detail&id=" + newsId);
    }
}

评论管理后台实现:

@WebServlet("/admin/comment")
public class AdminCommentServlet extends HttpServlet {
    private CommentDAO commentDAO;
    
    @Override
    public void init() throws ServletException {
        commentDAO = new CommentDAOImpl();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        if ("list".equals(action)) {
            listComments(request, response);
        } else if ("approve".equals(action)) {
            approveComment(request, response);
        } else if ("delete".equals(action)) {
            deleteComment(request, response);
        }
    }
    
    private void listComments(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        List<Comment> comments = commentDAO.findAllWithNews();
        request.setAttribute("comments", comments);
       
本文关键词
JSPServlet新闻发布管理系统源码解析

上下篇

上一篇
没有更多文章
下一篇
没有更多文章