源码地址: https://download.csdn.net/download/m0_51152186/85262287
基于 springmvc+tomcat+mysql 的BBS论坛
本系统具有以下功能:
1.前台服务功能
登录、注册、修改信息、注销、管理个人留言信息、查看发表回复帖子、查询留言
2.后台管理功能
用户管理、版主后台管理、管理员后台管理、系统设置、留言管理、公告管理、其他管理。
项目功能图:
一、eclipse中建立以下目录的web工程,配置tomcat
二、建立数据库连接类,连接本地MySQL8.0
package common;
import java.sql.*;
public class DBConnect {
/*建立数据库连接*/
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs = null;
private PreparedStatement ps = null;
public DBConnect()
{
try
{
//Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Class.forName("com.mysql.cj.jdbc.Driver");
//conn = DriverManager.getConnection("jdbc:mysql://localhost/mybbs?&useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true", "root", "123456");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybbs?&useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true", "root", "123456");
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
}
catch (SQLException ex)
{
System.out.println(ex.getMessage() + "璺緞閿欒锛�");
}
catch (ClassNotFoundException ex)
{
System.out.println(ex.getMessage() + "椹卞姩閿欒锛�");
}
}
/*返回更新影响的记录数*/
public PreparedStatement getPs(String sql) throws SQLException {
try {
ps = conn.prepareStatement(sql);
conn.commit();
return ps;
} catch (Exception e) {
//conn.rollback();
e.printStackTrace();
return ps;
}
}/*返回查询后的结果集*/
public ResultSet executeQuery(String ssql) throws SQLException{
try{
rs = stmt.executeQuery(ssql);
return rs;
}
catch(SQLException se){
//conn.rollback();
System.out.println("DBBean.executeQuery() ERROR:"+se.getMessage());
}
return rs;
}
public int executeUpdate(String ssql) throws SQLException{
int iupdate = 0;
try{
iupdate = stmt.executeUpdate(ssql);
return iupdate;
}
catch(SQLException se){
//conn.rollback();
System.out.println("DBBean.executeUpdate() ERROR:"+se.getMessage());
}
return iupdate;
}/*释放数据库连接资源*/
public void free() throws SQLException{
try{
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
catch(SQLException se){
System.out.println("DBBean.free() ERROR:"+se.getMessage());
}
}
public Connection getConnection() {/*返回连接*/
return conn;
}
}
数据库导入语句如下:(在MYSQL中复制粘贴即可导入项目数据)
/*
Navicat MySQL Data TransferSource Server : local
Source Server Version : 50519
Source Host : localhost:3306
Source Database : mybbsTarget Server Type : MYSQL
Target Server Version : 50519
File Encoding : 65001Date: 2017-12-10 18:54:04
*/
create database mybbs;
use mybbs;SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for board
-- ----------------------------
DROP TABLE IF EXISTS `board`;
CREATE TABLE `board` (
`BoardName` varchar(50) NOT NULL,
`BoardId` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`BoardId`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of board
-- ----------------------------
INSERT INTO `board` VALUES ('Java集合类学习讨论', '00000000001');
INSERT INTO `board` VALUES ('JSP内置对象使用', '00000000002');
INSERT INTO `board` VALUES ('Servlet使用', '00000000003');
INSERT INTO `board` VALUES ('HTML5学习讨论', '00000000004');-- ----------------------------
-- Table structure for reply
-- ----------------------------
DROP TABLE IF EXISTS `reply`;
CREATE TABLE `reply` (
`Contentinfo` text NOT NULL,
`CreateDate` datetime DEFAULT NULL,
`UserId` int(11) NOT NULL,
`TopicId` int(11) NOT NULL,
`ReplyId` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ReplyId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of reply
-- ------------------------------ ----------------------------
-- Table structure for topic
-- ----------------------------
DROP TABLE IF EXISTS `topic`;
CREATE TABLE `topic` (
`Title` varchar(50) NOT NULL,
`Contentinfo` text NOT NULL,
`CreateDate` datetime DEFAULT NULL,
`UserId` int(11) NOT NULL,
`ClickNum` int(11) DEFAULT NULL,
`ReplyNum` int(11) DEFAULT NULL,
`BoardId` int(11) NOT NULL,
`TopicId` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`TopicId`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of topic
-- ----------------------------
INSERT INTO `topic` VALUES ('hi', 'aaabbb', '2017-12-10 16:13:23', '1', '0', '0', '1', '0000000001');
INSERT INTO `topic` VALUES ('List', 'dggw', '2017-12-10 16:21:36', '1', '0', '0', '1', '0000000002');
INSERT INTO `topic` VALUES ('request对象', 'request.setAttribute(\"pass\",\"123\");', '2017-12-10 17:01:49', '1', '0', '0', '2', '0000000003');
INSERT INTO `topic` VALUES ('HttpServlet', 'javax.servlet.http.HttpServlet', '2017-12-10 17:03:55', '1', '0', '0', '3', '0000000004');
INSERT INTO `topic` VALUES ('HTML', '<HTML>\r\n<Body>\r\n</Body>\r\n</HTML>', '2017-12-10 17:04:55', '1', '0', '0', '4', '0000000005');-- ----------------------------
-- Table structure for userinfo
-- ----------------------------
DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo` (
`UserName` varchar(20) DEFAULT NULL,
`Password` varchar(50) NOT NULL,
`UserId` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`UserId`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of userinfo
-- ----------------------------
INSERT INTO `userinfo` VALUES ('2', '2', '0000000001');
INSERT INTO `userinfo` VALUES ('3', '3', '0000000002');
INSERT INTO `userinfo` VALUES ('4', '4', '0000000003');
三、SpringMVC其实就一种基于Servlet的MVC模型:
1、模型:一个或多个javabean对象,用于存储数据和业务逻辑。
package entity;
public class Board {
String boardId;
String boradname;
String topicNum;
String newTopic;
public String getTopicNum() {
return topicNum;
}
public void setTopicNum(String topicNum) {
this.topicNum = topicNum;
}
public String getNewTopic() {
return newTopic;
}
public void setNewTopic(String newTopic) {
this.newTopic = newTopic;
}
public String getBoardId() {
return boardId;
}
public void setBoardId(String boardId) {
this.boardId = boardId;
}
public String getBoradname() {
return boradname;
}
public void setBoradname(String boradname) {
this.boradname = boradname;
}
}
package entity;
public class Topic {
String topicId;
String topicTitle;
String clicknum;
String replynum;
String content;
String CreateDate;
String Userid;
public String getUserid() {
return Userid;
}
public void setUserid(String userid) {
Userid = userid;
}
public String getCreateDate() {
return CreateDate;
}
public void setCreateDate(String createDate) {
CreateDate = createDate;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTopicId() {
return topicId;
}
public void setTopicId(String topicId) {
this.topicId = topicId;
}
public String getTopicTitle() {
return topicTitle;
}
public void setTopicTitle(String topicTitle) {
this.topicTitle = topicTitle;
}
public String getClicknum() {
return clicknum;
}
public void setClicknum(String clicknum) {
this.clicknum = clicknum;
}
public String getReplynum() {
return replynum;
}
public void setReplynum(String replynum) {
this.replynum = replynum;
}
}
2、控制器:一个或多个Servlet对象,根据视图提交的请求进行控制,即将请求转发给业务逻辑的javabean,并将处理记过存放到实体模型javabean中,输出给视图显示。
package servlet;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import dao.SaveTopicDAO;
import dao.SaveTopicDAOImp;
public class AddTopicServlet extends HttpServlet {
/**
* Constructor of the object.
*/
public AddTopicServlet() {
super();
}
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设定请求中的字符编码格式为GBK,避免汉字乱码
request.setCharacterEncoding("gbk");
//从request中获得session对象
HttpSession session=request.getSession();
//从session中获得userID数据
String userid=(String)session.getAttribute("userid");
//从请求中获得参数(title、contentinfo、boardid)
String title=request.getParameter("title");
String content=request.getParameter("content");
String boardid=request.getParameter("boardid");
String boardname=request.getParameter("boardname");
//定义业务类对象,并调用业务方法
SaveTopicDAO t=new SaveTopicDAOImp();
int i=t.saveTopic(title, content, userid, boardid);
//跳转到GetTopicServlet
if(i==1){
response.sendRedirect("GetTopicServlet?boardId="+boardid+"&boardName="+boardname);
}
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
}
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.net.URLEncoder;
import dao.GetBoard;
public class GetboardServlet extends HttpServlet {
/**
* Constructor of the object.
*/
public GetboardServlet() {
super();
}
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//实例化业务类,调用getboard方法获得版块信息
GetBoard gb=new GetBoard();
List result=gb.getBoard();
//保存数据
request.setAttribute("result", result);
//页面转向到index.jsp页面(请求转发)
request.getRequestDispatcher("index.jsp").forward(request, response);
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
}
视图:一个和多个JSP页面,想控制器提交数据和为模型提供数据显示,JSP页面主要使用HTML标记和JavaBean标记来显示数据。
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<HTML>
<HEAD>
<TITLE>Java在线学习论坛--看贴</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gbk">
<Link rel="stylesheet" type="text/css" href="style/style.css" />
</HEAD>
<BODY>
<DIV>
<IMG src="images/logo.gif">
</DIV>
<!-- 用户信息、登录、注册 -->
<DIV class="h">
欢迎你,***
</DIV>
<!-- 主体 -->
<DIV>
<br />
<!-- 导航 -->
<DIV>
>>
<B>论坛首页</B>>>
<B></B>
</DIV>
<br />
<!-- 回复、新帖 -->
<DIV>
<A href="reply.jsp"><IMG
src="images/reply.gif" border="0">
</A>
<A href="post.jsp"><IMG
src="images/post.gif" border="0">
</A>
</DIV>
<!-- 翻 页 -->
<!-- 本页主题的标题 -->
<DIV>
<TABLE cellSpacing="0" cellPadding="0" width="100%">
<TR>
<TH class="h">
本页主题:***</TH>
</TR>
<TR class="tr2">
<TD>
</TD>
</TR>
</TABLE>
</DIV>
<!-- 主题 -->
<DIV class="t">
<TABLE style="BORDER-TOP-WIDTH: 0px; TABLE-LAYOUT: fixed"
cellSpacing="0" cellPadding="0" width="100%">
<TR class="tr1">
<TH style="WIDTH: 20%">
<B>XXX</B>
<BR />
<B>该贴不存在</B>
<BR />
<B>发表该贴的用户已被删除</B>
<BR />
</TH>
<TH>
<H4>
话题标题
</H4>
<DIV>
话题内容
</DIV>
<DIV class="tipad gray">
发表:2011-01-11
支持率:5 回帖总数:6
</DIV>
<DIV class="zc">
<div align="right">
<font color="#FF0000"> <a
>支 持</a>
</font>
<font color="#818a89">支 持 </font>
</div>
</DIV>
</TH>
<TH>
<H4>
该贴已被删除
</H4>
<DIV>
</DIV>
<DIV class="tipad gray">
</DIV>
<DIV class="zc">
<div align="right">
</div>
</DIV>
</TH>
</TR>
</TABLE>
</DIV>
<!-- 回复 -->
<DIV class="t">
<TABLE style="BORDER-TOP-WIDTH: 0px; TABLE-LAYOUT: fixed"
cellSpacing="0" cellPadding="0" width="100%">
<TR class="tr1">
<TH style="WIDTH: 20%">
<B>回复用户名</B>
<BR />
</TH>
<TH>
<DIV>回复内容</DIV>
<DIV class="tipad gray">
发表:回复时间
</DIV>
</TH>
</TR>
</TABLE>
</DIV>
<!-- 翻 页 -->
<DIV>
</DIV>
</DIV>
<!-- 声明 -->
<BR>
</BODY>
</HTML>
<%@ page language="java" import="java.util.List,entity.*" pageEncoding="GBK"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<HTML>
<HEAD>
<TITLE>欢迎访问Java在线学习论坛</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gbk">
<Link rel="stylesheet" type="text/css" href="style/style.css" />
</HEAD>
<BODY>
<DIV>
<IMG src="images/logo.gif">
</DIV>
<!-- 用户信息、登录、注册 -->
<c:if test="${sessionScope.isLogined=='true'}">
<DIV class="h">
欢迎你${sessionScope.username }
</DIV>
</c:if>
<c:if test="${sessionScope.isLogined==null}">
<DIV class="h">
您尚未登录 <a href="login.jsp?where=index.jsp">登录</a>
| <A href="reg.jsp">注册</A> |
</DIV>
</c:if>
<!-- 主体 -->
<DIV class="t">
<TABLE cellSpacing="0" cellPadding="0" width="100%">
<TR class="tr2" align="center">
<TD colSpan="2">版块</TD>
<TD style="WIDTH: 10%;">主贴数</TD>
<TD style="WIDTH: 30%">最新发表</TD>
</TR>
<TR class="tr3">
<TD colspan="4"><br></TD>
</TR>
<c:forEach items="${result}" var="b">
<TR class="tr3">
<TD width="5%"> </TD>
<TD align="left">
<IMG src="images/board.gif">
<A href="GetTopicServlet?boardId=${b.boardId }&boardName=${b.boradname}">${b.boradname}
</A>
</TD>
<TD align="center">${b.topicNum }</TD>
<TD align="left">${b.newTopic }</TD>
</TR>
</c:forEach>
<TR class="tr3">
<TD colspan="4"> </TD>
</TR>
</TABLE>
</DIV>
</BODY>
</HTML>
<%@ page language="java" pageEncoding="GBK"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<HTML>
<HEAD>
<TITLE>Java在线学习论坛--发布帖子</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gbk">
<Link rel="stylesheet" type="text/css" href="style/style.css" />
<script type="text/javascript">
function check(){
if(document.postForm.title.value=="") {
alert("标题不能为空");
return false;
}
if(document.postForm.content.value=="") {
alert("内容不能为空");
return false;
}
if(document.postForm.content.value.length>3000) {
alert("长度不能大于3000");
return false;
}
}
</script>
</HEAD>
<BODY>
<DIV>
<IMG src="images/logo.gif">
</DIV>
<!-- 用户信息 -->
<%
String boardid = request.getParameter("boardid");
System.out.println("测试数据:"+boardid);
//判断处理用户登录
String boardname=request.getParameter("boardName");
String username = (String)session.getAttribute("username");
String isLogined = (String)session.getAttribute("isLogined");
/* if(isLogined==null){
isLogined = "false";
response.sendRedirect("login.jsp");
}*/
%>
<c:if test="${sessionScope.isLogined==null }">
<c:set var="isLogined" scope="page" value="false"></c:set>
<c:redirect url="login.jsp"></c:redirect>
</c:if>
<DIV class="h">
欢迎你,${sessionScope.username }
</DIV>
<!-- 主体 -->
<DIV><BR/>
<!-- 导航 -->
<DIV>
<B>论坛首页</B>>> ${param.boardname }
</DIV><BR/>
<DIV>
<FORM name="postForm" onSubmit="return check()" action="AddTopicServlet" method="POST">
<INPUT type="hidden" name="boardid" value="${param.boardid }"/>
<INPUT type="hidden" name="boardname" value="${param.boardname }"/>
<DIV class="t">
<TABLE cellSpacing="0" cellPadding="0" align="center">
<TR>
<TD class="h" colSpan="3"><B>发表帖子</B></TD>
</TR>
<TR class="tr3">
<TH width="20%"><B>标题</B></TH>
<TH><INPUT class="input" style="PADDING-LEFT: 2px; FONT: 14px Tahoma"
tabIndex="1" size="60" name="title">
</TH>
</TR>
<TR class="tr3">
<TH vAlign=top>
<DIV><B>内容</B></DIV>
</TH>
<TH colSpan=2>
<DIV>
<span><textarea style="WIDTH: 385px;" name="content" rows="7" cols="80" tabIndex="2" ></textarea></span>
</DIV>
(不能多于1500个汉字)
</TH>
</TR>
</TABLE>
</DIV>
<DIV style="MARGIN: 15px 0px; TEXT-ALIGN: center">
<INPUT class="btn" tabIndex="3" type="submit" value="提 交">
<INPUT class="btn" tabIndex="4" type="reset" value="重 置">
</DIV>
</FORM>
</DIV>
</DIV>
<!-- 声明 -->
<BR/>
</BODY>
</HTML>
四、使用Servlet完成BBS
五、EL表达式与JSTL标签
六、功能实现及运行效果图
登陆界面如下:
注册界面如下:
论坛帖如下:
论坛话题分类如下:
论坛发帖界面如下:
回复帖子的实现如下:
异常处理界面如下:
七、BBS论坛项目总结