通过servlet实现几个网站常用的功能

帮朋友写的小程序,由于功能比较简单所以就偷懒只使用了Servlet

一、JSP页面部分(这个部分的设置比较粗糙,主要是为了查看功能能否实现,如果需要向用户展示还得修饰一下)

1)功能页(所有需要后台实现的功能都放在这里集中展示)

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'index.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="css/styles.css">

</head>

<body>
    <div id="title">功能页:本页面显示所有功能项目,实际开发中请将各自功能项目部署到实际页面中</div>
    <div id="body">
        <div class="funcblack">
            <br> 访客留言:
            <form action="servlet/messageIssue.do" method="post">
                <table>
                    <tr>
                        <td><input type="text" name="contact" placeholder="QQ号" />
                        </td>
                    </tr>
                    <tr>
                        <td><textarea rows="6" cols="20" name="message"
                                placeholder="留言..."></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td><input type="submit" value="提交" />
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div class="funcblack">
            <br>用户注册:
            <form action="servlet/userregister.do" method="post">
                <table>
                    <tr>
                        <td><input type="text" name="userName" placeholder="用户名..." />
                        </td>
                    </tr>
                    <tr>
                        <td><input type="password" name="userPassword"
                            placeholder="密码..." /></td>
                    </tr>
                    <tr>
                        <td><input type="password" name="userPasswordConfirm"
                            placeholder="确认密码..." /></td>
                    </tr>
                </table>
                <input type="submit" value="注册">
            </form>
        </div>
        <div class="funcblack">
            <br>用户登录:
            <form action="servlet/userlog.do" method="post">
                <table>
                    <tr>
                        <td><input type="text" name="userName" placeholder="用户名..." />
                        </td>
                    </tr>
                    <tr>
                        <td><input type="password" name="userPassword"
                            placeholder="密码..." /></td>
                    </tr>
                </table>
                <input type="submit" value="登录">
            </form>
        </div>
        <div class="funcblack">
            <br>新闻发布:
            <form action="servlet/newsIssue.do" method="post">
                <table>
                    <tr>
                        <td><input type="text" name="newsTitle" placeholder="新闻标题..." />
                        </td>
                    </tr>
                    <tr>
                        <td><textarea rows="6" cols="20" name="newsBody"
                                placeholder="详细内容..."></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td><input type="submit" value="发布" />
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div class="clear"></div>
    </div>
    <div id="line">
        <a href="servlet/newsDisplay.do">新闻页</a>
    </div>
</body>
</html>
index.jsp

2)添加一个跳转成功页面和一个失败页面(开发的时候测试使用,开发完成以后可以删除)

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'success.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>
    <h1>success</h1>
    <%=request.getAttribute("remind")%>
</body>
</html>
success.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'success.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>
    <h1>success</h1>
    <%=request.getAttribute("remind")%>
</body>
</html>
failure.jsp

3)由于功能中包含一个新闻展示的功能,所以补充添加一个新闻展示页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'newsBody.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>
    <h1>News</h1>
    <hr>
    <c:forEach var="news" items="${newsList}">
        <c:if test="${param.id==news.id}">
            <c:out value="${news.newsTitle}" />
            <br>
            <textarea rows="15" cols="100" readonly="readonly">${news.newsBody}</textarea>
        </c:if>
    </c:forEach>
</body>
</html>
newsBody.jsp

4)再添加两个管理页面,也是功能展示使用。主要演示如果是管理员登录,页面跳转应与普通用户有所区别(具体当时为什么要这样设计有点忘记了,反正也不重要。参考的时候可以忽略)

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'display.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>
    <h1>inner display</h1>
    <%=request.getAttribute("remind")%>
    <table border="1">
        <c:forEach var="message" items="${messages}">
            <tr>
                <td><c:out value="${message.contact}" /></td>
                <td><c:out value="${message.message}" /></td>
                <td><a href="servlet/messagemanage.do?messageId=${message.id}">删除</a>
                </td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>
display.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'newsTitle.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>
    <h1>News Title</h1>
    <%=request.getAttribute("remind")%>
    <c:forEach var="news" items="${newsList}">
        <br>
        <a href="newsBody.jsp?id=${news.id }">${news.newsTitle}&nbsp;&nbsp;&nbsp;${news.newsDate}</a>
    </c:forEach>
</body>
</html>
newsTitle.jsp

ps:以上的两个页面需要放置在WEB-INF/inner/目录下,只允许服务器跳转。

二、web.xml文件配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name></display-name>
    <servlet>
        <servlet-name>messageIssue</servlet-name>
        <servlet-class>servlet.MessageIssue</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>UserRegister</servlet-name>
        <servlet-class>servlet.UserRegister</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>UserLog</servlet-name>
        <servlet-class>servlet.UserLog</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MessageManage</servlet-name>
        <servlet-class>servlet.MessageManage</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>NewsIssue</servlet-name>
        <servlet-class>servlet.NewsIssue</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>NewsDisplay</servlet-name>
        <servlet-class>servlet.NewsDisplay</servlet-class>
    </servlet>

    <!-- 设置*.do作为调用Servlet的标志 -->
    <servlet-mapping>
        <servlet-name>messageIssue</servlet-name>
        <url-pattern>/servlet/messageIssue.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>UserRegister</servlet-name>
        <url-pattern>/servlet/userregister.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>UserLog</servlet-name>
        <url-pattern>/servlet/userlog.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MessageManage</servlet-name>
        <url-pattern>/servlet/messagemanage.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>NewsIssue</servlet-name>
        <url-pattern>/servlet/newsIssue.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>NewsDisplay</servlet-name>
        <url-pattern>/servlet/newsDisplay.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>
web.xml

三、Java代码及数据库配置

1)目录层次

2)数据库连接

package util;

import java.sql.*;

import java.util.Properties;

/*
 * 根据db.properties的配置获取数据库连接
 */
public class DatabaseConnection {
    private static Connection connection;

    // 返回单例Connection对象
    public static Connection getConnection() {
        if (connection == null) {
            connection = createConnection();
        }
        return connection;
    }
    
    private static Connection createConnection() {
        String driver = null;
        String url = null;
        String username = null;
        String password = null;
        Properties prop = new Properties();
        try {
            prop.load(DatabaseConnection.class.getClassLoader().getResourceAsStream("db.properties"));
            driver = prop.getProperty("driver");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");
            Class.forName(driver);
            return DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void closeStatement(Statement stmt) {
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void closeResultSet(ResultSet rs) {
        try {
            if (rs != null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
util/DatabaseConnection.java
#数据库连接信息保存在这里
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/learnhow
username=root
password=111111111
db.properties

3)Servlet代码

package servlet;

import java.io.IOException;
import java.util.List;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.Message;
import model.News;

import service.MessageService;
import service.NewsService;
import util.DatabaseConnection;

/*
 * servlet工具类,public方法写在这里供所有servlet调用
 * 返回的ServletUtil单例对象,开发环境中放在各自的servlet中,生产环境中如果有前端控制器可以考虑部署里面。
 */
public class ServletUtil {
    private HttpServletRequest request;
    private HttpServletResponse response;
    private static ServletUtil servletUtil = buildServletUtil();

    public static ServletUtil getServletUtil() {
        return servletUtil;
    }

    private ServletUtil() {

    }

    private static ServletUtil buildServletUtil() {
        return new ServletUtil();
    }

    // 插入一条记录到session
    public boolean insertHttpSession(String name, Object value) {
        if (servletUtil.request == null) {
            return false;
        } else {
            request.getSession().setAttribute(name, value);
            return true;
        }
    }

    // 插入一条记录到application
    public boolean insertServletContext(String name, Object value) {
        if (servletUtil.request == null) {
            return false;
        } else {
            request.getServletContext().setAttribute(name, value);
            return true;
        }
    }

    public boolean checkServletContext(String name) {
        if (servletUtil.request == null) {
            return false;
        } else {
            Object o = request.getServletContext().getAttribute(name);
            if (o == null) {
                return false;
            } else {
                return true;
            }
        }
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public ServletUtil setRequest(HttpServletRequest request) {
        this.request = request;
        return this;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    public ServletUtil setResponse(HttpServletResponse response) {
        this.response = response;
        return this;
    }

    public ServletUtil setRequestResponse(HttpServletRequest request,
            HttpServletResponse response) {
        this.request = request;
        this.response = response;
        return this;
    }

    // 读取config.properties中的配置
    public String getConfig(String key) {
        Properties prop = new Properties();
        try {
            prop.load(DatabaseConnection.class.getClassLoader()
                    .getResourceAsStream("config.properties"));
            return prop.getProperty(key);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    // 返回用户意见列表
    public List<Message> getMessages() {
        MessageService messageService = new MessageService();
        return messageService.getMessageList();
    }

    // 删除session中的一条记录
    public boolean removeHttpSession(String key) {
        if (servletUtil.request == null) {
            return false;
        } else {
            request.getSession().removeAttribute(key);
            return true;
        }
    }

    // 返回新闻列表
    public List<News> getNews() {
        NewsService newsService = new NewsService();
        return newsService.getNewsList();
    }

}
ServletUtil.java

ServletUtil.getConfig(String key) 方法需要读取一个名为config.properties配置文件中的信息,这个文件是提供给网站管理员配置除数据库以外的其他参数的。在里面的所有数据都可以在配置完成以后通过前面的方法读取出来。(作为演示只配置一条信息用来确定管理员的用户名,作为管理员可以在数据库中任选一个用户用来登录后台)

#与网站有关的其他信息保存在这里
admin=admin
config.properties
package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.Message;
import model.News;
import service.MessageService;
import service.NewsService;

public class NewsIssue extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        if ((request.getParameter("newsTitle") != null && !request
                .getParameter("newsTitle").equals(""))
                && (request.getParameter("newsBody") != null && !request
                        .getParameter("newsBody").equals(""))) {
            // 非空值和空串
            String title = request.getParameter("newsTitle");
            String body = request.getParameter("newsBody");
            this.saveNews(title, body);
            ServletUtil servletUtil = ServletUtil.getServletUtil()
                    .setRequestResponse(request, response);
            List<News> news = servletUtil.getNews();
            //这里是触发前台新闻列表更新的唯一的地方,不通过这里操作的新闻修改操作都会引发前后台数据不一致,考虑到真实环境中如果有要求更高的用户建议使用框架编写会轻松
            servletUtil.insertServletContext("newsList", news);
            request.setAttribute("remind", "新闻已发布");
            request.getRequestDispatcher("/success.jsp").forward(request,
                    response);
        } else {
            request.setAttribute("remind", "新闻信息填写错误");
            request.getRequestDispatcher("/failure.jsp").forward(request,
                    response);
        }
    }

    private void saveNews(String title, String body) {
        News newsEntity = new News(title, body);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(new Date());
        newsEntity.setNewsDate(date);
        NewsService newsService = new NewsService();
        newsService.save(newsEntity);
    }

}
NewsIssue.java
package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.Message;
import model.User;

import service.MessageService;
import service.UserService;
import util.DatabaseConnection;

public class UserLog extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        ServletUtil servletUtil = ServletUtil.getServletUtil()
                .setRequestResponse(request, response);
        // 获得管理员的名字
        String admin = servletUtil.getConfig("admin");
        String userName = request.getParameter("userName");
        String userPassword = request.getParameter("userPassword");
        if (userName.equals(admin) && this.loggin(userName, userPassword)) {
            // 如果用户名和密码核对成立并且用户名等于指定的管理员则跳转到管理员页面,生产环境中也可以考虑将这个功能单独分开,呵呵哒~
            List<Message> messages = servletUtil.getMessages();
            servletUtil.insertHttpSession("messages", messages);
            servletUtil.insertHttpSession("userName", userName);
            request.setAttribute("remind", "管理员已成功登录");
            request.getRequestDispatcher("/WEB-INF/inner/display.jsp").forward(
                    request, response);
        } else if (this.loggin(userName, userPassword)) {
            // 用户名和密码核对成立,但并非管理员登录
            servletUtil.insertHttpSession("userName", userName);
            request.setAttribute("remind", "您已成功登录");
            request.getRequestDispatcher("/success.jsp").forward(request,
                    response);
        } else {
            request.setAttribute("remind", "用户名不存在或密码不符,请联系系统管理员");
            request.getRequestDispatcher("/failure.jsp").forward(request,
                    response);
        }
    }

    private boolean loggin(String userName, String userPassword) {
        User userEntity = new User(userName, userPassword);
        UserService userService = new UserService();
        return userService.log(userEntity);
    }
}
UserLog.java
package servlet;

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 service.UserService;

import model.User;

public class UserRegister extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //生产环境中建议通过JavaScript做前端检查
        if ((request.getParameter("userPassword") != null && !request
                .getParameter("userPassword").equals(""))
                && (request.getParameter("userPasswordConfirm") != null && !request
                        .getParameter("userPasswordConfirm").equals(""))
                && (request.getParameter("userPassword").equals(request
                        .getParameter("userPasswordConfirm")))) {
            // 用户名和密码非空串和空值并且两次密码相同
            String userName = request.getParameter("userName");
            String userPassword = request.getParameter("userPassword");
            if (this.register(userName, userPassword)) {
                request.setAttribute("remind", "感谢您的注册");
                request.getRequestDispatcher("/success.jsp").forward(request,
                        response);
            } else {
                request.setAttribute("remind", "用户名重复");
                request.getRequestDispatcher("/failure.jsp").forward(request,
                        response);
            }
        } else {
            request.setAttribute("remind", "两次密码不符");
            request.getRequestDispatcher("/failure.jsp").forward(request,
                    response);
        }
    }

    private boolean register(String userName, String userPassword) {
        User userEntity = new User(userName, userPassword);
        UserService userService = new UserService();
        return userService.save(userEntity);
    }
}
UserRegister.java
package servlet;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import service.MessageService;

import model.*;

/*
 * 负责用户留言
 */
public class MessageIssue extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 在开发环境中使用的临时设置,部署到生产环境以后可以通过filter统一设置
        request.setCharacterEncoding("utf-8");

        if ((request.getParameter("contact") != null && !request.getParameter(
                "contact").equals(""))
                && (request.getParameter("message") != null && !request
                        .getParameter("message").equals(""))) {
            // 非空串和空值才可以提交留言
            String contact = request.getParameter("contact");
            String message = request.getParameter("message");
            this.saveMessage(contact, message);
            request.setAttribute("remind", "留言已提交");
            request.getRequestDispatcher("/success.jsp").forward(request,
                    response);
        } else {
            request.setAttribute("remind", "请填写正确的信息");
            request.getRequestDispatcher("/failure.jsp").forward(request,
                    response);
        }
    }

    private void saveMessage(String contact, String message) {
        Message messageEntity = new Message(contact, message);
        messageEntity.setDate(new Date());
        MessageService messageService = new MessageService();
        messageService.save(messageEntity);
    }
}
MessageIssue.java
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 model.Message;

import service.MessageService;

/*
 * 由于用户留言只有后台可见,因此只提供给管理员可以查看和删除
 */
public class MessageManage extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        ServletUtil servletUtil = ServletUtil.getServletUtil()
                .setRequestResponse(request, response);
        int messageId = Integer.valueOf(request.getParameter("messageId"));
        if (removeMessage(messageId)) {
            List<Message> messages = servletUtil.getMessages();
            servletUtil.removeHttpSession("messages");
            servletUtil.insertHttpSession("messages", messages);
            request.setAttribute("remind", "留言已经删除");
            request.getRequestDispatcher("/WEB-INF/inner/display.jsp").forward(
                    request, response);
        } else {
            request.setAttribute("remind", "删除留言出错");
            request.getRequestDispatcher("/failure.jsp").forward(request,
                    response);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    private boolean removeMessage(int messageId) {
        MessageService messageService = new MessageService();
        return messageService.removeMessage(messageId);
    }
}
MessageManage.java
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 model.News;

/*
 * 新闻展示:管理员添加了新闻之后用户登录就可以看到
 */
public class NewsDisplay extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        ServletUtil servletUtil = ServletUtil.getServletUtil()
                .setRequestResponse(request, response);
        /*
         * 第一次访问的用户负责将newsList注入Application,之后其他用户的访问不会触发注入动作。新闻列表通过后台管理员编辑新闻更新。
         * 这样做有一个缺点,当管理员直接操作数据库删除数据的时候不会触发前台的更新列表操作。从而造成展示列表和数据库中的数据不一致,遇到这样的情况需要管理员手动刷新一次列表。
         * 所以一般不建议网站管理人员任意改动数据库中的信息。但是这样做又会带来另一个问题,就是可能随着网站管理功能的增加都需要在程序员编写相应的逻辑代码。
         */
        if (!servletUtil.checkServletContext("newsList")) {
            List<News> newsList = servletUtil.getNews();
            servletUtil.insertServletContext("newsList", newsList);
        }
        request.setAttribute("remind", "新闻概览");
        request.getRequestDispatcher("/WEB-INF/inner/newsTitle.jsp").forward(
                request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
NewsDisplay.java

以上Servlet的部分就全部完成了,一些数据检查的功能在实际生产环境中应该部署到JavaScript中取检查以减少服务器压力。但是考虑到使用servlet编写的程序一般都不会大,普通pc足以运行。

四、model和vo(model和vo最大的区别是vo不需要保存进数据库所以是完整的对象模型)

package model;

import java.util.Date;

/*
 * CREATE TABLE `eps_log` (
 * `id` int(11) NOT NULL AUTO_INCREMENT,
 * `title` varchar(20) NOT NULL,
 * `_date` varchar(20) NOT NULL,
 * PRIMARY KEY (`id`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 */
public class Log {
    private int id;
    private String title;
    private Date date;

    public Log() {
    }

    public Log(String title, Date date) {
        this.title = title;
        this.date = date;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}
Log.java
package model;

import java.util.Date;

/*
 * CREATE TABLE `eps_message` (
 *  `id` int(11) NOT NULL AUTO_INCREMENT,
 *  `contact` varchar(20) NOT NULL,
 *  `message` varchar(255) NOT NULL,
 *  `_date` varchar(20) NOT NULL,
 *  PRIMARY KEY (`id`)
 *  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 */
public class Message {
    private int id;
    private String contact;
    private String message;
    private Date date;

    public Message() {
    }

    public Message(String contact, String message) {
        this.contact = contact;
        this.message = message;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getContact() {
        return contact;
    }

    public void setContact(String contact) {
        this.contact = contact;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "Message [id=" + id + ", contact=" + contact + ", message="
                + message + ", date=" + date + "]";
    }

}
Message.java
package model;

/*
 * CREATE TABLE `sps_news` (
 * `id` int(11) NOT NULL AUTO_INCREMENT,
 * `title` varchar(20) NOT NULL,
 * `body` varchar(255) NOT NULL,
 * `_date` varchar(20) NOT NULL,
 * PRIMARY KEY (`id`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 */
public class News {
    private int id;
    private String newsTitle;
    private String newsBody;
    private String newsDate;

    public News() {
    }

    public News(String newsTitle, String newsBody) {
        this.newsTitle = newsTitle;
        this.newsBody = newsBody;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNewsTitle() {
        return newsTitle;
    }

    public void setNewsTitle(String newsTitle) {
        this.newsTitle = newsTitle;
    }

    public String getNewsBody() {
        return newsBody;
    }

    public void setNewsBody(String newsBody) {
        this.newsBody = newsBody;
    }

    public String getNewsDate() {
        return newsDate;
    }

    public void setNewsDate(String newsDate) {
        this.newsDate = newsDate;
    }

    @Override
    public String toString() {
        return "News [id=" + id + ", newsTitle=" + newsTitle + ", newsBody="
                + newsBody + ", newsDate=" + newsDate + "]";
    }

}
News.java
package model;

/*
 * CREATE TABLE `eps_user` (
 * `id` int(11) NOT NULL AUTO_INCREMENT,
 * `userName` varchar(20) NOT NULL,
 * `userPassword` varchar(20) NOT NULL,
 * PRIMARY KEY (`id`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 */
public class User {
    private int id;
    private String userName;
    private String userPassword;

    public User() {
    }

    public User(String userName, String userPassword) {
        this.userName = userName;
        this.userPassword = userPassword;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

}
User.java

sql代码放在每一个类中需要自己建立,由于没有使用任何orm框架所以得自己建表,好在也没有设计表关联否则操作起来会有点复杂。

package model.vo;

/*
 * 值对象不需要实现持久化
 */
public class UserVo {
    private int id;
    private String userName;
    private String userPassword;
    private String userPasswodConfirm;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserPasswodConfirm() {
        return userPasswodConfirm;
    }

    public void setUserPasswodConfirm(String userPasswodConfirm) {
        this.userPasswodConfirm = userPasswodConfirm;
    }

}
UserVo.java

五、Dao层和Service层

处于安全考虑用户注册,管理员登录,用户登录,留言,新闻发布等功能都会在Log数据库表中保存相应的日志。因此需要在service层配置数据库事物。若不用配置事物可以也可以省略Dao层。

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;

import util.DatabaseConnection;

import model.*;

public class LogDao {
    // 日志数据保存进数据库
    public boolean save(Log log) throws SQLException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String date = sdf.format(log.getDate());
        Connection conn = DatabaseConnection.getConnection();
        String sql = "INSERT INTO eps_log VALUES(NULL,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, log.getTitle());
        ps.setString(2, date);
        ps.execute();
        ps.close();
        return true;
    }
}
LogDao.java
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import util.DatabaseConnection;
import model.Message;

public class MessageDao {
    // 访客留言信息保存进数据库
    public boolean save(Message message) throws SQLException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(message.getDate());
        Connection conn = DatabaseConnection.getConnection();
        String sql = "INSERT INTO eps_message VALUES(NULL,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, message.getContact());
        ps.setString(2, message.getMessage());
        ps.setString(3, date);
        ps.execute();
        ps.close();
        return true;
    }

    // 读取所有访客留言并封装成List对象
    public List<Message> getMessageList() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<Message> messages = new ArrayList<Message>();
        Connection conn = DatabaseConnection.getConnection();
        String sql = "SELECT * FROM eps_message";
        try {
            Statement statement = conn.createStatement();
            ResultSet rs = statement.executeQuery(sql);
            while (rs.next()) {
                Message message = new Message();
                message.setId(rs.getInt(1));
                message.setContact(rs.getString(2));
                message.setMessage(rs.getString(3));
                message.setDate(sdf.parse(rs.getString(4)));
                messages.add(message);
            }
            return messages;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        } catch (ParseException e2) {
            e2.printStackTrace();
            return null;
        }
    }

    // 根据信息id删除相应留言
    public boolean remove(int messageId) throws SQLException {
        Connection conn = DatabaseConnection.getConnection();
        String sql = "DELETE FROM eps_message WHERE id = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, messageId);
        ps.execute();
        ps.close();
        return true;
    }
}
MessageDao.java
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import model.Message;
import model.News;
import util.DatabaseConnection;

//新闻发布
public class NewsDao {
    public boolean save(News news) throws SQLException {
        Connection conn = DatabaseConnection.getConnection();
        String sql = "INSERT INTO eps_news VALUES(NULL,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, news.getNewsTitle());
        ps.setString(2, news.getNewsBody());
        ps.setString(3, news.getNewsDate());
        ps.execute();
        ps.close();
        return true;
    }

    public List<News> getNewsList() {
        List<News> newsList = new ArrayList<News>();
        Connection conn = DatabaseConnection.getConnection();
        String sql = "SELECT * FROM eps_news";
        try {
            Statement statement = conn.createStatement();
            ResultSet rs = statement.executeQuery(sql);
            while (rs.next()) {
                News news = new News();
                news.setId(rs.getInt(1));
                news.setNewsTitle(rs.getString(2));
                news.setNewsBody(rs.getString(3));
                news.setNewsDate(rs.getString(4));
                newsList.add(news);
            }
            return newsList;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
}
NewsDao.java
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import util.DatabaseConnection;

import model.User;

public class UserDao {
    // 用户注册
    public boolean save(User user) throws SQLException {
        Connection conn = DatabaseConnection.getConnection();
        String sql = "INSERT INTO eps_user VALUES(NULL,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, user.getUserName());
        ps.setString(2, user.getUserPassword());
        ps.execute();
        ps.close();
        return true;
    }

    // 用户名和密码的检查,true代表数据库中有符合的记录
    public boolean check(User user) {
        Connection conn = DatabaseConnection.getConnection();
        String sql = "SELECT * FROM eps_user WHERE userName = ?";
        try {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, user.getUserName());
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                if (user.getUserName().equals(rs.getString(2))
                        && user.getUserPassword().equals(rs.getString(3))) {
                    return true;
                }
            }
            return false;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 用户名的检查,true代码数据库中没有相同记录,允许插入数据
    public boolean check(String userName) {
        Connection conn = DatabaseConnection.getConnection();
        String sql = "SELECT * FROM eps_user WHERE userName = ?";
        try {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, userName);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                if (userName.equals(rs.getString(2))) {
                    return false;
                }
            }
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
            return true;
        }
    }
}
UserDao.java
package service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import util.DatabaseConnection;

import dao.LogDao;
import dao.MessageDao;
import model.Log;
import model.Message;

public class MessageService {
    // 插入客户留言和插入相应的日志信息
    public boolean save(Message message) {
        Connection conn = DatabaseConnection.getConnection();
        try {
            conn.setAutoCommit(false);
            MessageDao messageDao = new MessageDao();
            LogDao logDao = new LogDao();
            Log log = new Log("用户留言", new Date());
            messageDao.save(message);
            logDao.save(log);
            conn.commit();
            return true;
        } catch (Exception e) {
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 检索留言数据
    public List<Message> getMessageList() {
        MessageDao messageDao = new MessageDao();
        return messageDao.getMessageList();
    }

    // 删除留言数据和插入相应的日志信息
    public boolean removeMessage(int messageId) {
        Connection conn = DatabaseConnection.getConnection();
        try {
            conn.setAutoCommit(false);
            MessageDao messageDao = new MessageDao();
            LogDao logDao = new LogDao();
            Log log = new Log("删除留言", new Date());
            messageDao.remove(messageId);
            logDao.save(log);
            conn.commit();
            return true;
        } catch (Exception e) {
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}
MessageService.java
package service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import model.Log;
import model.News;
import util.DatabaseConnection;
import dao.LogDao;
import dao.NewsDao;

public class NewsService {
    public boolean save(News news) {
        Connection conn = DatabaseConnection.getConnection();
        try {
            conn.setAutoCommit(false);
            NewsDao newsDao = new NewsDao();
            LogDao logDao = new LogDao();
            Log log = new Log("发布新闻", new Date());
            newsDao.save(news);
            logDao.save(log);
            conn.commit();
            return true;
        } catch (Exception e) {
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public List<News> getNewsList() {
        NewsDao newsDao = new NewsDao();
        return newsDao.getNewsList();
    }
}
NewsService.java
package service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

import model.Log;
import model.User;
import util.DatabaseConnection;
import dao.LogDao;
import dao.UserDao;

public class UserService {
    public boolean save(User user) {
        Connection conn = DatabaseConnection.getConnection();
        UserDao userDao = new UserDao();
        if (userDao.check(user.getUserName())) {
            try {
                conn.setAutoCommit(false);
                LogDao logDao = new LogDao();
                Log log = new Log(user.getUserName()+"注册", new Date());
                userDao.save(user);
                logDao.save(log);
                conn.commit();
                return true;
            } catch (Exception e) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
                return false;
            } finally {
                try {
                    conn.setAutoCommit(true);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        } else {
            return false;
        }
    }

    public boolean log(User user) {
        UserDao userDao = new UserDao();
        if (userDao.check(user)) {
            LogDao logDao = new LogDao();
            Log log = new Log(user.getUserName() + "登录", new Date());
            try {
                logDao.save(log);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return true;
        } else {
            return false;
        }
    }
}
UserService.java

后记:很难说这样写到底好不好,但是在某些时候感觉用户需求并不是非常明确。在这样的情况下如果使用各种框架来搭建网站环境再编写功能代码反而会觉得多余。设计这个东西本来就是仁者见仁,智者见智的。个人感觉能满足对象的需求又略微扩充一点点弹性的设计才是最合适的设计思路。小微企业对互联网的需求并没有想象中的强烈,能够提供给他们简单方便的建站方式或许是帮助它们进入互联网的最好方法。

最后附上整个项目的目录结构和IDE版本,处于篇幅考虑没有提供junit的部分。

原文地址:https://www.cnblogs.com/learnhow/p/5098325.html