废话不多说,我们继续上次的进度,这次我们来做文章模块
跟用户模块相似,我们先来写实体类,在com.software.entities包里new出来一个Article.java
代码就不再贴出来了,要不篇幅太长了,很简单就是声明一下属性然后添加get和set方法。接下来来写ArticleDao.java,里面包含增删改查查全部等方法
public class ArticleDao {
/**
* 新增文章
* @param article
*/
public static void insert(Article article) {
Connection conn = DB.getConnection();
String sql = "INSERT INTO `t_article` VALUES (null, ?, ?, ?, ?, ?, ?)";
PreparedStatement pstmt = DB.preparedStmt(conn, sql);
try {
pstmt.setString(1, article.getTitle());
pstmt.setString(2, article.getAuthor());
pstmt.setString(3, article.getContent());
pstmt.setInt(4, article.getClickTimes());
pstmt.setString(6, article.getType());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(pstmt);
DB.close(conn);
}
/**
* 根据id删除文章
* @param id
*/
public static void delById(int id) {
String sql = "DELETE FROM `t_article` WHERE `id` = " + id;
Connection conn = DB.getConnection();
Statement stmt = DB.createStmt(conn);
try {
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(stmt);
DB.close(conn);
}
/**
* 更新文章
* @param article
*/
public static void update(Article article) {
Connection conn = DB.getConnection();
String sql = "UPDATE `t_article` SET `title` = ?, `author` = ?, `content` = ?,"
+ " `click_times` = ?, `publish_time` = ?, `type` = ? WHERE `id` = ?";
PreparedStatement pstmt = DB.preparedStmt(conn, sql);
try {
pstmt.setString(1, article.getTitle());
pstmt.setString(2, article.getAuthor());
pstmt.setString(3, article.getContent());
pstmt.setInt(4, article.getClickTimes());
pstmt.setDate(5, (Date) article.getPublishTime());
pstmt.setString(6, article.getType());
pstmt.setInt(7, article.getId());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(pstmt);
DB.close(conn);
}
/**
* 根据id查找文章
* @param id
*/
public static Article queryById(int id) {
Article article = null;
String sql = "SELECT * FROM `t_article` WHERE `id` = " + id;
Connection conn = DB.getConnection();
Statement stmt = DB.createStmt(conn);
ResultSet rs = null;
try {
rs = stmt.executeQuery(sql);
if(rs.next()) {
article.setId(rs.getInt("id"));
article.setTitle(rs.getString("title"));
article.setAuthor(rs.getString("author"));
article.setContent(rs.getString("content"));
article.setClickTimes(rs.getInt("click_times"));
article.setPublishTime(rs.getDate("publish_time"));
article.setType(rs.getString("type"));
}
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(rs);
DB.close(stmt);
DB.close(conn);
return article;
}
/**
* 查找全部文章
* @return
*/
public static List<Article> listAll() {
List<Article> articleList = new ArrayList<>();
String sql = "SELECT * FROM `t_article`";
Connection conn = DB.getConnection();
Statement stmt = DB.createStmt(conn);
ResultSet rs = DB.executeQuery(stmt, sql);
try {
while(rs.next()) {
int id = rs.getInt("id");
String title = rs.getString("title");
String author = rs.getString("author");
String content = rs.getString("content");
int clickTimes = rs.getInt("click_times");
Date publishTime = rs.getDate("publish_time");
String type = rs.getString("type");
Article article = new Article();
article.setId(id);
article.setTitle(title);
article.setAuthor(author);
article.setContent(content);
article.setClickTimes(clickTimes);
article.setPublishTime(publishTime);
article.setType(type);
articleList.add(article);
}
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(rs);
DB.close(stmt);
DB.close(conn);
return articleList;
}
}
封装好之后开始套页,我们需要展示所有article的页面首先就是首页index.jsp。所以这就涉及到一个问题:要运行首页之前,肯定要先运行查找所有文章的servlet,所以我们来写一下查找所有文章的servlet
我们的大致思想是这样的:先运行articleList这个servlet,然后将得到的articleList放到session中去,再跳转到columnList,同样将得到的columnList放到session,最后再跳转到index.jsp,在index.jsp中将所有的Article和Column读出来
这里我们在articleList中还写了一个分页,下面我把分页的基本思想给大家介绍一下:
对于一个文章列表,如果其中只有几个文章,那么没有问题,但是如果其中包含了成百上千个的文章,想要在一个页面展示出来显然不太现实,用户体验度也极差,所以这就引出来了分页这个概念。
如果我们要做分页,我们有这样的两种想法:第一种,是我先一次性把所有的文章全部查找出来,然后再根据用户所选的页码,来判断我应该显示哪些。这样做的话显然会比较麻烦,每次用户重新选择页码,都需要把所有文章都找出来一遍。那我们不禁就想到了第二种方法:我根据用户所选的页码,做一个计算,计算出需要查找出第几条到第几条数据,然后再去数据库中进行查询操作。这样做显然是合理的,也是高效率的,所以这就引出来sql语句中的limit关键字。
limit关键字的用法是这样的:在sql语句的后面加上”limit startNo , pageSize”,startNo是从哪条记录开始查询,pageSize是查询多少条数据。我们来看个例子,就直接以我们的这个项目为例,我们在ArticleDao里面添加一个方法listByNum()
/**
* 分页查找全部文章
* @return
*/
public static List<Article> listByNum(int pageNo, int pageSize, String column) {
List<Article> articleList = new ArrayList<>();
int startNo = (pageNo-1)*pageSize ;
String sql = "SELECT * FROM `t_article`";
if(column != "null") {
sql += " WHERE `type` = '" + column + "'";
}
sql += " ORDER BY `id` DESC LIMIT " + startNo + ", " + pageSize;
Connection conn = DB.getConnection();
Statement stmt = DB.createStmt(conn);
ResultSet rs = DB.executeQuery(stmt, sql);
try {
while(rs.next()) {
int id = rs.getInt("id");
String title = rs.getString("title");
String author = rs.getString("author");
String content = rs.getString("content");
int clickTimes = rs.getInt("click_times");
Date publishTime = rs.getDate("publish_time");
String type = rs.getString("type");
Article article = new Article();
article.setId(id);
article.setTitle(title);
article.setAuthor(author);
article.setContent(content);
article.setClickTimes(clickTimes);
article.setPublishTime(publishTime);
article.setType(type);
articleList.add(article);
}
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(rs);
DB.close(stmt);
DB.close(conn);
return articleList;
}
这里startNo的计算方法就是(pageNo - 1) * pageSize,注意第一条数据在这里是记做第零条的哈
这里提一下,我们的第一种方法也是可以的。我们后面的一个分页用的就是第一种方法,采用的是前台的BootStrap,这里就不做过多介绍了
所以这样我们就可以在ArticleList.java里面调用这个方法了。我们来贴一个ArticleList.java的代码,
/**
*
*/
package com.software.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
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 javax.servlet.http.HttpSession;
import com.software.Dao.ArticleDao;
import com.software.entities.Article;
import com.software.util.DB;
/**
* 查找所有文章servlet
* @author lw
* @time 2017年6月10日下午9:02:54
*/
@WebServlet(name="articleList", value="/articleList")
public class ArticleList extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Article> articleList = new ArrayList<>();
//文章类型
String column = request.getParameter("column");
if(column==null) {
column = "null";
}
//第几页
String strPageNo = request.getParameter("pageNo");
int pageNo = 0;
if(strPageNo == null || strPageNo.trim().equals("")) {
pageNo = 1;
} else {
pageNo = Integer.parseInt(strPageNo.trim());
}
//每页几篇文章
String strPageSize = request.getParameter("pageSize");
int pageSize = 0;
if(strPageSize == null || strPageSize.trim().equals("")) {
pageSize = 5;
} else {
pageSize = Integer.parseInt(strPageSize);
}
Connection conn = DB.getConnection();
String sql = "SELECT count(*) FROM `t_article`";
Statement stmtCount = DB.createStmt(conn);
ResultSet rsCount = DB.executeQuery(stmtCount, sql);
int totalNum = 0;
try {
if(rsCount.next()) {
totalNum = rsCount.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
/*
总页数的计算方法,如果totalNum/pageSize能整除,就是totalNum/pageSize,如果不能整除,就是totalNum/pageSize + 1
*/
int totalPages = totalNum % pageSize == 0 ? totalNum / pageSize : totalNum / pageSize + 1;
//防止不合法输入
if(pageNo > totalPages) {
pageNo = totalPages;
}
HttpSession session = request.getSession();
session.setAttribute("totalPages", totalPages);
session.setAttribute("pageNo", pageNo);
session.setAttribute("pageSize", pageSize);
//调用listByNum方法
articleList = ArticleDao.listByNum(pageNo, pageSize, column);
session.setAttribute("articleList", articleList);
response.sendRedirect("columnList");
}
}
最后在index.jsp里面用session读出来
<div style="border-bottom: 1px solid rgb(228, 228, 228);">
<p class="article_title" id="article_recommend_title" style="display:inline">
最新文章</p>
<form action="articleList" method="post" style="display:inline">
<%--设置每页显示几条--%>
<span style="margin-left:450px;color:#37acd3;display:inline-block;font-size:15px;">显示</span>
<select class="form-control" name="pageSize" style="border:1px solid #37acd3;width:60px;height:30px;">
<option>5</option>
<option>10</option>
<option>15</option>
<option>20</option>
</select>
<span style="color:#37acd3;display:inline-block;font-size:15px;">条</span>
<input type="submit" value="提交" style="display:inline;width:70px;">
</form>
</div>
<ul>
<c:forEach items="${sessionScope.articleList}" var="article">
<li>
<div class="articleCtx clearfix">
<a href="detail?id=${article.id}">
${article.title}
<span style="float: right;">
${article.publishTime}
</span>
</a>
</div>
</li>
</c:forEach>
</ul>
<div class="pageNum fr clearfix">
<%
System.out.println("totalPages = " + session.getAttribute("totalPages"));
System.out.println("pageNo = " + session.getAttribute("pageNo"));
%>
<%--共几页,第几页--%>
<span style="float:left;">共${sessionScope.totalPages}页,第${sessionScope.pageNo}页</span>
<div style="float:right;">
<a href="articleList?pageNo=${sessionScope.pageNo-1}&${sessionScope.pageSize}">上一页</a>
<a href="articleList?pageNo=${sessionScope.pageNo+1}&${sessionScope.pageSize}">下一页</a>
</div>
</div>
</div>
</div>
这样,主页中就可以从数据库中读出来所有的article啦~
然后我们开始写文章的添加,其实很简单,如果大家是按照前面的操作步骤一步步来的话已经清除熟路了。先设置跳转页面,然后提交到servlet,最后请求转发或者请求重定向回index.jsp
我们直接贴代码
首先是index.jsp中的链接,用了一个<c:choose>
标签
<c:choose>
<c:when test="${sessionScope.username == null}">
<a href="login.jsp">登陆</a>
<a href="register.jsp">注册</a>
</c:when>
<c:otherwise>
欢迎您, ${sessionScope.username} <br>
<a href="new_article.jsp">写文章</a>
<a href="logout">退出登录</a>
<c:if test="${sessionScope.username eq 'admin'}">
<a href="back/production/user_manage.jsp">去往后台管理页面</a>
</c:if>
</c:otherwise>
</c:choose>
然后是new_article.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" import="com.software.entities.*"%>
<%@ page isELIgnored = "false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gentelella Alela! | </title>
<!-- Bootstrap -->
<link href="back/vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="back/vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<!-- NProgress -->
<link href="back/vendors/nprogress/nprogress.css" rel="stylesheet">
<!-- iCheck -->
<link href="back/vendors/iCheck/skins/flat/green.css" rel="stylesheet">
<!-- bootstrap-wysiwyg -->
<link href="back/vendors/google-code-prettify/bin/prettify.min.css" rel="stylesheet">
<!-- Select2 -->
<link href="back/vendors/select2/dist/css/select2.min.css" rel="stylesheet">
<!-- Switchery -->
<link href="back/vendors/switchery/dist/switchery.min.css" rel="stylesheet">
<!-- starrr -->
<link href="back/vendors/starrr/dist/starrr.css" rel="stylesheet">
<!-- bootstrap-daterangepicker -->
<link href="back/vendors/bootstrap-daterangepicker/daterangepicker.css" rel="stylesheet">
<!-- Custom Theme Style -->
<link href="back/build/css/custom.min.css" rel="stylesheet">
<link href="js/simditor/styles/simditor.css" rel="stylesheet">
<style>
.col-md-6 {
width: 66%;
}
.col-md-3 {
width: 20%;
}
</style>
</head>
<!-- page content -->
<div class="right_col" role="main">
<div class="">
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2>文章添加</h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br />
<form id="demo-form2" data-parsley-validate class="form-horizontal form-label-left" action="newArticle" method="post">
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="">标题
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" id="last-name" name="title" required="required" class="form-control col-md-7 col-xs-12">
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="">作者
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<p class="form-control col-md-7 col-xs-12" style="margin:0px;">${sessionScope.username}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="">归属栏目
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<select class="form-control" name="column">
<c:forEach items="${sessionScope.columnList}" var="column">
<option>
${column.name}
</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" rows="3">内容
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<!-- 插件开始 -->
<textarea id="editor" placeholder="这里输入内容" name="content"autofocus></textarea>
<!--插件结束-->
<br />
</div>
</div>
<div class="ln_solid"></div>
<div class="form-group">
<div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3">
<button class="btn btn-primary" type="reset">重置</button>
<button type="submit" class="btn btn-success">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /page content -->
<!-- footer content -->
<footer>
<div class="pull-right">
</div>
<div class="clearfix"></div>
</footer>
<!-- /footer content -->
</div>
</div>
<!-- jQuery -->
<script src="back/vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="back/vendors/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- FastClick -->
<script src="back/vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->
<script src="back/vendors/nprogress/nprogress.js"></script>
<!-- bootstrap-progressbar -->
<script src="back/vendors/bootstrap-progressbar/bootstrap-progressbar.min.js"></script>
<!-- iCheck -->
<script src="back/vendors/iCheck/icheck.min.js"></script>
<!-- bootstrap-daterangepicker -->
<script src="back/vendors/moment/min/moment.min.js"></script>
<script src="back/vendors/bootstrap-daterangepicker/daterangepicker.js"></script>
<!-- bootstrap-wysiwyg -->
<script src="back/vendors/bootstrap-wysiwyg/js/bootstrap-wysiwyg.min.js"></script>
<script src="back/vendors/jquery.hotkeys/jquery.hotkeys.js"></script>
<script src="back/vendors/google-code-prettify/src/prettify.js"></script>
<!-- jQuery Tags Input -->
<script src="back/vendors/jquery.tagsinput/src/jquery.tagsinput.js"></script>
<!-- Switchery -->
<script src="back/vendors/switchery/dist/switchery.min.js"></script>
<!-- Select2 -->
<script src="back/vendors/select2/dist/js/select2.full.min.js"></script>
<!-- Parsley -->
<script src="back/vendors/parsleyjs/dist/parsley.min.js"></script>
<!-- Autosize -->
<script src="back/vendors/autosize/dist/autosize.min.js"></script>
<!-- jQuery autocomplete -->
<script src="back/vendors/devbridge-autocomplete/dist/jquery.autocomplete.min.js"></script>
<!-- starrr -->
<script src="back/vendors/starrr/dist/starrr.js"></script>
<!-- Custom Theme Scripts -->
<script src="back/build/js/custom.min.js"></script>
<!-- <script type="text/javascript" src="js/jquery.min.js"></script> -->
<script type="text/javascript" src="back/layer/layer.js"></script>
<script type="text/javascript" src="js/simditor/scripts/jquery.min.js"></script>
<script type="text/javascript" src="js/simditor/scripts/module.js"></script>
<script type="text/javascript" src="js/simditor/scripts/uploader.js"></script>
<script type="text/javascript" src="js/simditor/scripts/hotkeys.js"></script>
<script type="text/javascript" src="js/simditor/scripts/simditor.js"></script>
<script type="text/javascript">
var editor = new Simditor({
textarea: $('#editor'),
});
</script>
</body>
</html>
这里我是用了一个simditor这样的一个编辑器,这是一个非常轻量级的编辑器,比Ueditor,或者是我在写这个项目的时候有同学想要搞一点骚操作想嵌入的MarkDown编辑器,比起这些编辑器,simditor用起来会非常方便
然后是NewArticle.java
/**
*
*/
package com.software.servlet;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
import com.software.Dao.ArticleDao;
import com.software.entities.Article;
/**
* 添加文章servlet类
* @author lw
* @time 2017年6月20日下午3:01:29
*/
@WebServlet(name="newArticle", value="/newArticle")
public class NewArticle extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String title = request.getParameter("title");
HttpSession session = request.getSession();
String author = (String)session.getAttribute("username");
String column = request.getParameter("column");
String content = request.getParameter("content");
content = content.replaceAll("\n","<br>");
Article article = new Article();
article.setTitle(title);
article.setAuthor(author);
article.setContent(content);
article.setType(column);
ArticleDao.insert(article);
response.sendRedirect("articleList");
}
}
这里可以看到我最后请求重定向到了articleList这个servlet,而没有重定向到index.jsp,这是因为我在添加文章之后,文章列表肯定有所更新,所以我需要重新获取一下articleList,来更新一下session中的文章列表
删、改这些操作我们在前面的模块都已经说过了,Article模块中也是大同小异,这里我们说一下过滤器
过滤器是什么我就不再说了,如果有不了解的同学可以去翻一翻资料。过滤器多数会用于字符编码方式的统一、或者是对没有权限进入页面的用户进行阻止。在我们这个项目里,分为前台普通用户可视页面和后台管理页面,那么问题就在于,如果作为一个普通用户,当我输入后台管理页面的网址时,肯定是不能进入这个页面的,所以,我们这个项目的过滤器主要就是这个作用。
我们过滤器的代码放在了项目src/com.software.filter这个包里面,右键新建一个类,实现Filter接口并重写方法。我们filter的主要功能实现的代码都写在doFilter里面,这里我们直接把代码贴出来
package com.software.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 后台页面登录验证过滤器
* @author lw
* @time 2017年6月27日上午11:16:40
*/
public class BackFilter implements Filter {
/* (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)arg0;
HttpServletResponse response = (HttpServletResponse)arg1;
HttpSession session = request.getSession();
String username = (String)session.getAttribute("username");
if((username != null && username =="admin" )) {
chain.doFilter(request, response);
} else {
response.sendRedirect("/Software_Party/error.jsp");
}
}
/* (non-Javadoc)
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
然后,我们还需要在web.xml里对filter进行配置,代码如下
<filter>
<filter-name>backFilter</filter-name>
<filter-class>com.software.filter.BackFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>backFilter</filter-name>
<url-pattern>/back/*</url-pattern>
</filter-mapping>
这里是完成了一个类和路径的一一对应关系意味着:所有路径为/back/(代表所有文件)的页面都会被com.software.filter.BackFilter这个类,或者说这个过滤器处理。
再说一下这个过滤器,BackFilter.java的代码
在doFilter方法中,前两行代码是先将ServletRequest和ServletResponse强制转换成HttpServletRequet和HttpServleteResponse,然后从session中取出用户的username,如果username不为空,并且username为”admin”,那么,放行。否则,请求重定向到error.jsp
以下是error.jsp的代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'error.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
对不起,您没有权限进行此操作<br>
如想进行此操作,请联系超级管理员<br>
<a href="index.jsp">返回首页</a>
</body>
</html>
截止到目前为止,这个项目就大致成型了。其中运用了jsp、servlet、以及过滤器filter等JavaWeb开发的基本知识。其实在我测试这个项目的时候,发现在这个项目里面也存在很多bug,其中比较严重的就是分页那里,比如当我选择了每页有10条,然后当我选择下一页的时候,就会发现每页又变成了5条。其实这个bug也不难调,只是当时由于时间不够,忙着项目验收以及期末考试,所以就匆匆结项了。大家可以尝试修改一下。
这三篇博客的时间拖延比较长,最后这一篇是已经一个月之后写的了,所以有一些地方说的不是很清楚,或者有一些遗漏。我相信博客中也有一些错误的地方,也欢迎大家指出。jsp+servlet的开发模式也只是JavaWeb中最基础的一部分,企业中也很少有人会使用这种模式了,它还是我们JavaWeb中的基础,很多东西还是要以它们作为基础的。