JSP/Servlet 实现简单的留言板

                                         系  统  概  述

  一个简单的留言板所实现的功能有:用户注册、用户登录、查看留言信息和留言四个功能。在学习了JSP/Servlet后编写的

一个简单的实例,虽然简单,却拥有一个完整系统的必要功能,所以可以让自己初步了解使用JSP/Servlet技术开发系统的一般步骤。

  

系统功能简介:

  用户注册:当用户注册一个新用户时,就是向数据库user_table表中添加一条记录。

    当用户输入注册信息后,将用户的的注册信息提交到服务端负责处理注册信息的Servlet。当Servlet成功处理完用户的信息后,

客户端自动跳转到【登录界面】进行登录。

    用户登录:当用户输入用户名、密码和验证码时。系统将信息提交的处理登录信息的Servlet。Servlet则调用服务器控制器里

的方法来处理用户登录。当用户登录成功时,客户端自动跳转到【留言板】。

    留言板:调用数据库中的留言信息,显示在页面上。同时用户可以通过【留言】按钮,跳转到【留言】界面,留言功能和注册功能

类似,向数据库ly_table表中添加一条记录。

   

数据库的设计:

  对于该系统来说有两个表【user_table】和【ly_table】。

  【user_table】如下:

字段名 类型 含义
id int 用户id
username varchar(20) 用户名
password varchar(20) 密码

  【ly_table】如下:

字段名 类型 含义
id int 留言信息的id
userId int 用户的id
title varchar(25) 标题名字
date date 留言时间
connect text 留言类容

  

实现系统的基础类:

  实现在注册、登录系统中使用的一些重要的类:连接和操作数据库的DB类、存储用户的User类、

存储留言信息的LeaveMessageTable类和实现图形验证码的ValidationCode类。

  连接和操作数据库的DB类中具体包括如下方法:

        public User checkUser(String username , String password) :检查用户时候存在,存在就返回一个User对象,否则返回null 。

      public boolean checkValidationCode(HttpServletRequest request ,String validationCode) :检测验证码是否正确。

    public boolean addInfo(LeaveMessageTable ly) : 向数据库插入留言。

    public boolean insertUser(String username,String password) :向数据库存入用户。

    public ArrayList findLyInfo() : 从数据库中导出留言,返回一个ArrayList对象。

     private ResultSet execSQL(String sql , Object ...args)  : 执行SQL语句。

 

    在DB类的构造函数中连接数据库。这样有Servlet类创建DB对象时,便在创建过程中进行数据库的连接。

    

View Code
package com.cnblogs.jbelial.DBServlet;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import Common.Encrypter;
import Common.LeaveMessageTable; 
import Common.User;

public class DB{
    
//    定义数据库连接变量
    private Connection connection ;  
//    定义参数
    private String sql_driver = "com.mysql.jdbc.Driver" ; 
    private String sql_url = "jdbc:mysql://localhost:3306/web_ly_table" ; 
    private String sql_username = "root" ; 
    private String sql_password = "hezuoan" ; 
    
    public DB()
    {
        try
        {
               //建立数据库的连接
               Class.forName(sql_driver) ;
               connection = DriverManager.getConnection(sql_url,sql_username,sql_password) ; 
           }
        catch(Exception e)
        {
            e.printStackTrace() ; 
        }
    }
    
//    用于执行各种SQL语句的方法
    private ResultSet execSQL(String sql , Object ...args) 
            throws SQLException
    {
        PreparedStatement pstmt = connection.prepareStatement(sql) ;
//        为PreparedStatement对象设置SQL参数
        for (int i = 0 ; i < args.length ; ++ i)
        {
            pstmt.setObject(1 + i, args[i]) ; 
        }
//        运行
        pstmt.execute() ; 
        return  pstmt.getResultSet(); 
    }
//    核对用户输入的验证码是否正确
    public boolean checkValidationCode(HttpServletRequest request , 
            String validationCode)
    {
        String validationCodeSession = (String) request.getSession().getAttribute("validationCode") ; 
        if(validationCodeSession == null)
        {
//            给result.jsp设置信息
            request.setAttribute("info" , "验证码过期") ;
//            给login.jsp设置信息
            request.setAttribute("codeError", "验证码过期") ;
            return false ; 
        }
        if(!validationCode.equalsIgnoreCase(validationCodeSession))
        {
            request.setAttribute("info","验证码错误") ;
            request.setAttribute("codeError", "验证码错误") ;
            return false ; 
        }
        return true; 
    }
//    检查用户登录信息
    public User checkUser(String username , String password)
    {
        try
        {
            String sql = "select * from user_table where username = ? and  password = ?" ;
            ResultSet rs = execSQL(sql,username,password) ; 
            User user = new User() ; 
            while (rs.next())
            {    
                user.setId(rs.getInt("id")) ; 
                user.setUsername(rs.getString("username")) ; 
                user.setPassword(rs.getString("password")) ; 
                return user ;
            } 
            return null ;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null ; 
        }
    }
//    插入留言
    public boolean addInfo(LeaveMessageTable ly){
        try{
            String sql = "insert into ly_table(userId,data,title,content) values(?,?,?,?)" ; 
            execSQL(sql , ly.getUserId(), ly.getDate(),ly.getTitle(),ly.getContent());
            return true;
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
    }
//    插入用户
    public boolean insertUser(String username,String password){
        try{
            String sql = "insert into user_table(username,password) values(?,?)" ; 
            execSQL(sql ,username , password) ;  
            return true;
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
    }
//    获取留言信息。
    public ArrayList findLyInfo()
    {
         ArrayList arrayList = new ArrayList() ; 
         try 
         {
             String sql = "select * from ly_table" ; 
             ResultSet rs = execSQL(sql) ; 
             while(rs.next())
             {
                 LeaveMessageTable ly = new LeaveMessageTable() ; 
                 ly.setId(rs.getInt("id")) ; 
                 ly.setUserId(rs.getInt("userId")) ;
                 ly.setDate(rs.getDate("data")) ; 
                 ly.setTitle(rs.getString("title")) ;
                 ly.setContent(rs.getString("content")) ; 
                 arrayList.add(ly) ; 
             }
             return arrayList ; 
         }
         catch(Exception e)
         {
             e.printStackTrace() ; 
             return null ; 
         }
    }
//    获取用户名
    public String getUserName(int id)
    {
        String username = null;
        try{
            String sql = "select username from user_table where id = ?" ;
            ResultSet rs= execSQL(sql , new Object[]{id});
            while(rs.next()){
                 username=rs.getString(1);
            }
            return username;
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

  User类和LeaveMessageTable类:

  User类中则包含Id、用户名和密码三个属性。同时包含各个属性的set和get方法。

  

View Code
package Common;

public class User {
//    用户的id
    private int id ;
//    用户名
    private String username ;
//    用户密码
    private String password ;
    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 getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    

}

  

  LeaveMessageTable类:包含了如下属性Id、留言用户Id、留言标题、留言时间、留言类容属性。同时也包含了各个属性的

set和get方法。  

View Code
package Common;
import java.sql.Date;
public class LeaveMessageTable {
    private int id ;
    private int userId ; 
    private Date date ; 
    private String title ; 
    private String content ;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    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;
    }
    
}

  实现图形验证码:

  实现图形验证码大致分为5步上来完成:

  1、建立图形缓冲区; 

  2、在图形缓冲区用随机颜色填充背景。

  3、在图形缓冲区上输出验证码。

  4、将验证码保存在HttpSession对象中。

  5、向客户端输出图形验证码。

  通过ValidationCode类来实现验证码功能,该类也是Servlet类,在客户端只要像访问普通Servlet一样访问ValidationCode类即可。

  

View Code
package com.cnblogs.jbelial.Validation;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.* ; 
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@SuppressWarnings("serial")
public class ValidationCode extends HttpServlet
{
//    图形验证码的字符集合,系统通过随机从这些字符串中选择一些字符作为验证码
    private static String codeChars = 
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTYVWXYZ" ; 
//    返回一个随机颜色
    private static Color getRandomColor(int minColor , int maxColor)
    {
        Random random = new Random() ;
        if (minColor > 255)
            minColor = 255 ; 
        if (maxColor > 255)
            maxColor = 255 ; 
//        获取颜色的随机值
        int red = minColor + random.nextInt(maxColor - minColor) ; 
        int green = minColor + random.nextInt(maxColor - minColor) ; 
        int blue = minColor + random.nextInt(maxColor - minColor) ; 
        return new Color(red,green,blue) ;  
    }
    public void doGet (HttpServletRequest request ,
            HttpServletResponse response) throws IOException
    {
        
        
//       获取验证码集合的长度。
        int charsLength = codeChars.length() ; 
//        关闭浏览器缓冲区
        response.setHeader("ragma", "No-cache") ; 
        response.setHeader("Cache-Control", "no-cache") ;
        response.setDateHeader("Expires", 0) ; 
//        设置图片传送的格式。
        response.setContentType("image/jpeg");
        
//        设置图形验证码的长和宽度
        int width = 90 ;
        int height = 20 ;
//        建立图形缓冲区
        BufferedImage image = new BufferedImage(width , height,
                BufferedImage.TYPE_INT_RGB) ; 
//        获取用于输出文字的Graphics对象
        Graphics graphics = image.getGraphics() ; 
        
        Random random = new Random() ; 
        
//        设置要填充的颜色
        graphics.setColor(getRandomColor(180 , 250)) ; 
//        填充图形背景
        graphics.fillRect(0, 0, width, height) ; 
//        设置初始字体和颜色
        graphics.setFont(new Font("Time New Roman" , Font.ITALIC, height)) ; 
        graphics.setColor(getRandomColor(120,180)) ; 
        
//        保存验证码
        StringBuilder validationCode = new StringBuilder() ; 
//        验证码的随机字体
        String[] fontNames = {"Times New Roman" , "Book antiqua" , "Arial" } ;
//        随机生成验证码
        for (int i = 0 ; i < 4 ; ++ i)
        {
//            设置当前验证码字符的字体
            graphics.setFont(new Font(fontNames[random.nextInt(3)] , Font.ITALIC ,
                    height)) ; 
//            随机获得验证码的字符
            char codeChar = codeChars.charAt(random.nextInt(charsLength)) ;
            validationCode.append(codeChar) ; 
            graphics.setColor(getRandomColor(20,120)) ; 
//            在图形上输出验证码字符
            graphics.drawString(String.valueOf(codeChar), 16*i+random.nextInt(7), 
                    height - random.nextInt(6) ) ; 
        } 
//        获得Session对象,并设置Session对象为3分钟
        HttpSession session = request.getSession(); 
        session.setMaxInactiveInterval(5*60) ; 
//        将验证码放入session对象中.
        session.setAttribute("validationCode",validationCode.toString() ) ; 
        
        
//        关闭graphics对象。
        graphics.dispose() ;  
//        向客户端发送图形验证码
        ImageIO.write(image,"JPEG" ,response.getOutputStream()) ; 
        
    
        
    }
    public void doPost (HttpServletRequest request ,
            HttpServletResponse response) throws IOException
    {
            doGet(request , response) ; 
    }
    
}

  

 实现注册系统:

  包括一个register.jsp、result.jsp和RegisterServlet类。

  RegisterServlet类负责处理处理用户的提交的注册信息。

    RegisterServlet类在处理用户注册信息之前,创建DB类对象来连接数据库。然后通过调用DB类的方法来判断验证码是否正确和用户名是否被注册。

当一系列的判断都通过时,则向数据库中插入用户记录。

  RegisterServlet类的最后不管是否向数据库中插入用户记录,都会跳转到result.jsp页面。

  

View Code
package com.cnblogs.jbelial.Register;

import java.io.IOException; 

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

import Common.User;

import com.cnblogs.jbelial.DBServlet.DB;

public class RegisterServlet extends HttpServlet {

    /**
     * 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 
    {
//        设置字符集编码
        request.setCharacterEncoding("UTF-8") ; 
        response.setContentType("UTF-8");  
//        判断是否跳到【登录】
        if (request.getParameter("login") != null)
        {
            response.sendRedirect("login.jsp") ;
            return ; 
        }
        DB db = new DB() ; 
        String username  = null ;
//        设置result页面要跳转的页面
        String page = "login.jsp" ;
        try
        { 
//            获取界面的用户名和密码参数
            username = request.getParameter("username") ; 
            String password = request.getParameter("password") ;
            String validationCode = request.getParameter("validationCode") ; 
//            核对验证码
            if (!db.checkValidationCode(request, validationCode))  
                return ;   
            User user = db.checkUser(username,password) ; 
            if (user != null) 
            {
                request.setAttribute("info", username + "已被使用!") ;
                page = "register.jsp" ; 
            }
            else if (db.insertUser(username , password)) 
            {
//                定义result.jsp中使用的消息
                request.setAttribute("info" , "用户注册成功") ;
            } 
            request.setAttribute("page", page) ; 
        }
        catch(Exception e) { }
        finally
        { 
//            跳转到result.jsp 
            RequestDispatcher rd = request.getRequestDispatcher("/result.jsp") ; 
            rd.forward(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 {
        doGet(request,response) ; 
    }

}

  

  register.jsp则负责显示注册页面:

View Code
<%@ page language="java" pageEncoding="UTF-8"%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>用户注册</title>
    <script type="text/javaScript">
         function refresh()
         {
             var img = document.getElementById("imgValidationCode") ; 
             img.src = "ValidationCode"+Math.random() ; 
         }
         function checkRegister()
         {
             var username = document.getElementById("username") ;
             if(username.value == "" )
             {
                 alert("请输入用户名!") ; 
                 //把焦点放到username输入文本上
                 username.focus() ; 
                 return ;
             }
             var password = document.getElementById("password") ;
             if(password.value == "" )
             {
                 alert("请输入密码!");
                 password.focus() ;
                 return ; 
             }
             var re_password = document.getElementById("re_password") ;
             if(re_password.value != password.value)
             {
                 alert("输入的密码不一致!") ; 
                 re_password.focus() ; 
                 return ; 
             }
             var validationCode = document.getElementById("validationCode") ;
             if(validatoinCode.value == "")
             {
                 alert("请输入验证码!");
                 validatoinCode.focus() ;
                 return ;
             }
             register_form.submit() ; 
         }
     </script> 
  </head>
  
  <body> 
      <center>
          <h2>用户注册</h2>
          <form  name = "register_form" action = "RegisterServlet" method = "post">
              <table>
                  <tr>
                      <td>
                          用户名:
                      </td>
                      <td>
                          <input type = "text" id = "username" name = "username" 
                              size = "25">
                      </td>
                  </tr>
                  <tr>
                      <td>
                          密码:
                      </td>
                      <td>
                          <input type = "password" id = "password" name = "password"
                              size = "25">
                      </td>
                  </tr>
                  <tr>
                      <td>
                          再次输入密码:
                      </td>
                      <td>
                      <input type = "password" id = "re_password" name = "re_password"
                              size = "25">
                      </td>
                  </tr>
                  <tr>
                      <td>
                          验证码:
                      </td>
                      <td>
                        <input type = "text" id = "validationCode" name = "validationCode"
                            style = "60px;margin-top:10px"/>  
                        <img id = "imgValidationCode" src = "ValidationCode"/>
                        <input type = "button" value = "刷新"  onclick = "refresh()"/>
                    </td>
                  </tr>
              </table>
              <input type = "button" value = "注册" onclick = "checkRegister()"/>
              <input type = "submit" value = "登录" name = "login">
          </form>
      </center>
  </body>
</html>

  result.jsp页面则负责显示结果:

  

View Code
<%@ page language="java"  pageEncoding="UTF-8"%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
      <form name = "result_form" action = "${requestScope.page}" , method = "post"> 
        ${requestScope.info} 
            <input type = "submit" value = "确定" >  
      </form>
  </body>
</html>

  

 实现登录系统:

   登录系统和注册系统类似,包含login.jsp和LoginServlet类。

   LoginServlet类负责处理用户提交的登录信息。通过创建DB对象来连接数据库,再调用DB中的方法来判断用户提交的验证码和用户名、密码

的真确性,如果都正确则跳转到main.jsp,否则返回到login.jsp并显示提示消息;

   

View Code
package com.cnblogs.jbelial.Login;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
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 Common.User;

import com.cnblogs.jbelial.DBServlet.DB;

public class LoginServlet extends HttpServlet {

    /**
     * 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 {
 
//        设置字符集编码
        request.setCharacterEncoding("UTF-8") ; 
        response.setContentType("UTF-8");  
//        判断是否跳到【注册】
        if (request.getParameter("register") != null)
        {
            response.sendRedirect("register.jsp") ;
            return ; 
        }
        DB db = new DB() ;
//        设置跳转界面
        String page = "login.jsp" ;  
        String username = null ;
        try
        {
//            获取请求页面的参数
            username = request.getParameter("username") ; 
            String password = request.getParameter("password") ; 
            String validationCode = request.getParameter("validationCode") ; 
//            验证码检测
            if (!db.checkValidationCode(request, validationCode))
                    return ; 
            User user = db.checkUser(username,password) ; 
            if (user == null)
                request.setAttribute("userError", "用户名或密码错误") ; 
            if (user != null)
            {
//                如果根据检查,user不为空,表示用户名正确和密码正确,进行下一步操作。
                ArrayList arrayList = new ArrayList() ; 
                arrayList = db.findLyInfo() ; 
                request.setAttribute("arrayList", arrayList) ;
//                设置跳转到主界面
                page = "main.jsp" ;
                request.getSession().setAttribute("user", user) ; 
            }
    
            
        }
        catch(Exception e){}
        finally
        {
            request.setAttribute("username", username) ; 
            RequestDispatcher rd = request.getRequestDispatcher("/"+page) ; 
            rd.forward(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 {
        doGet(request,response) ; 
    }

}

    

   login.jsp则负责显示登录界面

View Code
<%@ page language="java" pageEncoding="UTF-8"%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>用户登录</title> 
  </head> 
     <script type="text/javaScript">
         function refresh()
         {
             var img = document.getElementById("imgValidationCode") ; 
             img.src = "ValidationCode" ; 
         }
         function checkLogin()
         {
             var username = document.getElementById("username_id"); 
             if (username.value == "" )
             {
                 alert("请输入用户名!") ;
                 username.focus() ; 
                 return ; 
             }
             var password = document.getElementById("password_id") ;
             if (password.value == "")
             {
                 alert("密码不能为空");
                 password.focus() ; 
                 return ;
             }
             var validationCode = document.getElementById("validationCode_id") ; 
             if ( validationCode.value == "")
             {
                 alert("验证吗不能为空") ;
                 validationCode.focus() ;
                return ; 
             }
             login_form.submit() ; 
         }
     </script> 
  <body>
      <center> 
          <h2>用户登录</h2>
          <form name = "login_form" action = "LoginServlet" method = "post" >
              <table>
                  <tr>
                      <td>
                           用户名:
                       </td>
                       <td>
                           <input type = "text" id = "username_id" value = "${requestScope.username}" name = "username"  
                              size = "25" />${requestScope.userError}
                      </td>
                  </tr>
                  <tr>
                      <td>
                          密  码:
                      </td>
                       <td>
                        <input type="password" id="password_id" name="password" size="25">
                    </td>
                </tr>
                <tr>
                    <td>
                        验证码:
                    </td>
                    <td>
                        <input type = "text" id = "validationCode_id" name = "validationCode"
                            style = "60px;margin-top:10px"/>  
                        <img id = "imgValidationCode" src = "ValidationCode"/>
                        <input type = "button" value = "刷新"  onclick = "refresh()"/>
                        ${requestScope.codeError}
                    </td>
                </tr> 
              </table>
              <input type = "button" value = "登录" onclick = "checkLogin()">
              <input type = "submit" value = "注册" name = "register">
          </form>
      </center>
  </body>
</html>

 

实现留言系统:

  留言系统包括负责显示用户留言的main.jsp页面、用户写留言的LeaveMessage.jsp页面和处理用户提交留言的addMessageServlet类 。

  addMessageServlet类就是把用户提交的留言信息提取出来,然后存入数据库。

  main.jsp则在用户登录后,自动跳转到显示留言的界面。 

留言板的源代码:MessageBoardSystem.rar

原文地址:https://www.cnblogs.com/jbelial/p/2444009.html