首页 > 编程 > Java > 正文

基于Servlet实现技术问答网站系统

2019-11-26 12:36:03
字体:
来源:转载
供稿:网友

这一篇博客将详细介绍一个基于Servlet的问答网站的实现,有详细的代码。

可能篇幅较长,以代码为主,有兴趣的童鞋看完可以尝试动手搭建一个属于自己的问答社区。

工具:Eclipse,数据库用到了MySQL,这次项目中未使用jsp,全部以Servlet注解的方式连接HTML和Servlet,JDK最好使用1.8,tomcat使用8.0。(注解方式为JDK1.5后的特性,最低要求1.5+,本项目使用JDK1.8)。

在这篇博客中可以学习到:

1,Servlet中关于注解的使用,本项目没有使用到传统的Servlet配置web.xml,全部使用注解的形式。

2,了解Font Awesome这一矢量图标库的使用,他基本提供了项目中所要使用到的所有图标,方便,快捷。

3,了解simditor这一富文本编辑器的使用,网站中直接嵌入富文本编辑器,再也不用为读取出来的文字格式不对发愁了。

4,关于项目中如何加入验证码,数据库查询之前先进行验证码验证。

5,关于MVC框架显示层――Velocity技术的使用。

先看一下大体项目图(由于主要做后台,前台可能略丑,大家可以自行找网站模板)

登录界面:


注册界面:


首页,展示了大家的提问:


解答界面,点击别人的提问后进入解答界面,使用了富文本编辑器。


我的解答界面,展示了我回答的历史:


我的提问界面,展示了我提问的所有问题:


提问界面:进入网站点击我要提问,加入当前页编辑问题:


下面介绍主要代码(代码中加入了详细注释,所以不再做说明)

主页列表Servlet:

@WebServlet( "/list.do" ) public class ListServlet extends HttpServlet {  private static final long serialVersionUID = 810339694607399128L;  @Override  protected void service( HttpServletRequest request , HttpServletResponse response )    throws ServletException, IOException {  String question=request.getParameter("quest");  System.out.println(question);  if(StringHelper.notEmpty(question)){   final String SQL = "SELECT id , title ,content, publish_time , publish_ip , user_id FROM t_topic where title =? " ;   ResultSet rs = JdbcHelper.query( SQL,question );    // 创建一个 List 对象,用来保存一批 Topic 对象   final List<Topic> topics = new ArrayList<>();   try {    // 每循环一次,光标下移一行,如果该行有数据返回 true    while( rs.next() ){     Topic t = new Topic(); // 创建对象     t.setId( rs.getInt( 1 ) ); // 将 结果集 中的 该行数据 封装到 t 对象的 id 属性中     t.setTitle( rs.getString( 2 ) );     t.setContent(rs.getString(3));     t.setPublishTime( rs.getTimestamp( 4 ));     t.setPublishIp( rs.getString( 5 ) );     User u = new User(); // 创建 一个 User 对象     u.setId( rs.getInt( 6 ) ); // 将 t_topic 表中的 user_id 放入到 User 对象的 id 属性中     t.setUser( u ); // 将 User 对象 设置到 Topic 对象上     /** 将 本次循环 创建的对象(已经封装数据) 添加到 List 集合中 */     topics.add( t );     }    } catch (SQLException e) {     e.printStackTrace();    }    JdbcHelper.release( rs ); // 关闭 结果集,释放相关的资源    /**** 为每个问题寻找提问者 ***********************************/    //for( int i = 0 ; i < topics.size() ; i++ ){    for( int i = 0 , len = topics.size() ; i < len ; i++ ){     Topic t = topics.get( i ) ; // 获得 题目     User u = t.getUser(); // 获得当前题目的User对象 ( 该对象中只有 id 没有其它数据 )     // 根据 用户对象的 id 来查询 用户的信息     String querySQL = "SELECT id , username , password FROM t_user WHERE id = ? " ;     ResultSet userRs = JdbcHelper.query( querySQL , u.getId() );     try {      if( userRs.next() ) { // 如果查询到用户信息       // 注意,这里应该使用 userRs       u.setUsername( userRs.getString( 2 ) ); // 将 username 列的值设置到 用户对象的 username 属性中       u.setPassword( userRs.getString( 3 )); // 将 password 列的值设置到 用户对象的 password 属性中      }     } catch (SQLException e) {      e.printStackTrace();     }     JdbcHelper.release( userRs ); // 关闭 结果集,释放相关的资源    }    ServletContext application = request.getServletContext();    /** 将这些数据保存到 application **/    application.setAttribute( "topics" , topics );    System.out.println( "问题列表: " + topics );    // 去 list.html 页面    response.sendRedirect( request.getContextPath() + "/list.html");   }else{    /**** 查询数据库中的所有问题 ***********************************/    final String SQL = "SELECT id , title ,content ,publish_time , publish_ip , user_id FROM t_topic ORDER BY publish_time DESC" ;    ResultSet rs = JdbcHelper.query( SQL );    // 创建一个 List 对象,用来保存一批 Topic 对象    final List<Topic> topics = new ArrayList<>();    try {     // 每循环一次,光标下移一行,如果该行有数据返回 true     while( rs.next() ){      Topic t = new Topic(); // 创建对象      t.setId( rs.getInt( 1 ) ); // 将 结果集 中的 该行数据 封装到 t 对象的 id 属性中      t.setTitle( rs.getString( 2 ) );      t.setContent(rs.getString(3));      t.setPublishTime( rs.getTimestamp( 4 ));      t.setPublishIp( rs.getString( 5 ) );      User u = new User(); // 创建 一个 User 对象      u.setId( rs.getInt( 6) ); // 将 t_topic 表中的 user_id 放入到 User 对象的 id 属性中      t.setUser( u ); // 将 User 对象 设置到 Topic 对象上      /** 将 本次循环 创建的对象(已经封装数据) 添加到 List 集合中 */      topics.add( t );     }    } catch (SQLException e) {     e.printStackTrace();    }    JdbcHelper.release( rs ); // 关闭 结果集,释放相关的资源    /**** 为每个问题寻找提问者 ***********************************/    //for( int i = 0 ; i < topics.size() ; i++ ){    for( int i = 0 , len = topics.size() ; i < len ; i++ ){     Topic t = topics.get( i ) ; // 获得 题目     User u = t.getUser(); // 获得当前题目的User对象 ( 该对象中只有 id 没有其它数据 )     // 根据 用户对象的 id 来查询 用户的信息     String querySQL = "SELECT id , username , password FROM t_user WHERE id = ? " ;     ResultSet userRs = JdbcHelper.query( querySQL , u.getId() );     try {      if( userRs.next() ) { // 如果查询到用户信息       // 注意,这里应该使用 userRs       u.setUsername( userRs.getString( 2 ) ); // 将 username 列的值设置到 用户对象的 username 属性中       u.setPassword( userRs.getString( 3 )); // 将 password 列的值设置到 用户对象的 password 属性中      }     } catch (SQLException e) {      e.printStackTrace();     }     JdbcHelper.release( userRs ); // 关闭 结果集,释放相关的资源    }    ServletContext application = request.getServletContext();    /** 将这些数据保存到 application **/    application.setAttribute( "topics" , topics );    System.out.println( "问题列表: " + topics );    // 去 list.html 页面    response.sendRedirect( request.getContextPath() + "/list.html");  }  } } 

主页列表显示界面代码:

<!DOCTYPE html> <html>  <head>   <meta charset="UTF-8">   <title>首页</title>   <link rel="stylesheet" href="$path/styles/general.css">   <link rel="stylesheet" href="$path/styles/cell.css">   <link rel="stylesheet" href="$path/styles/wen.css">  </head>  <body>     ## 登录状态栏 开始   <div class="login-status-container auto-height">     <span class="welcome cell-8">      ## 在 $ 之后 表达式之前使用 ! 表示 安静模式 ( 静默模式 )      <b>欢迎$!user.username来到爱问社区</b>     </span>     <span class="login-operation cell-4">      #if( $user )       <a href="$path/ask.html">提问</a>       <em>|</em>       <a href="$path/myQuestion.do">我的提问</a>       <em>|</em>       <a href="$path/logout.do">注销</a>      #else       <a href="$path/login.html">登录</a>       <em>|</em>       <a href="$path/regist.html">注册</a>      #end     </span>   </div> ## 登录状态栏 结束      ## 标志区域   <div class="brand-container auto-height">    <div class="cell-2">     <a href="$path"></a>    </div>    <div class="slogan cell-10">     <div>     爱问社区,这里可放logo     </div>    </div>   </div>      ## 列表区域   <div class="topic-list-container clear">    <!-- 问题列表的标题 -->    <div class="topic-list-header row clear">     <span class="topic-item-index cell-1">序号</span>     <span class="topic-item-title cell-5" style="text-align: left ;">标题</span>     <span class="topic-item-time cell-3">提问时间</span>     <span class="topic-item-user cell-2">提问者</span>     <span class="topic-item-operation cell-1">      #if( $user )       解答问题      #end     </span>    </div>      ## 问题列表开始      ## 每循环一次从 $topics 集合中取出一个 Topic 对象 放到 $topic 中      #foreach( $topic in $topics )          <div class="topic-item row clear odd">        <span class="topic-item-index cell-1">$topic.id</span>        <span class="topic-item-title cell-5" style="text-align: left ;">         <a href="$path/detail.do?id=$topic.id">$topic.title</a>        </span>        <span class="topic-item-time cell-3"> $topic.publishTime </span>        <span class="topic-item-user cell-2"> $topic.user.username</span>        <span class="topic-item-operation cell-1">         #if( $user )          <a href="$path/answer.do?id=$topic.id">解答</a>         #end        </span>      </div>              #end    ## 问题列表结束       </div>## 列表区域结束      <div class="line"></div>      <div class="container link-container">    <a href="$path/ask.html" >发起新问题</a>    |    <a href="$path/index.html" >返回首页</a>   </div>      <div class="container copyright-container">    © 2017 爱问社区版权所有   </div>    </body> </html> 

提问前台界面代码:

<!DOCTYPE html>  <html>  <head>   <meta charset="UTF-8">   <title>提问</title>   <link rel="stylesheet" href="$path/styles/general.css">   <link rel="stylesheet" href="$path/styles/cell.css">   <link rel="stylesheet" href="$path/styles/wen.css">   <link rel="stylesheet" href="$path/styles/btn.css">      <!-- 链接 simditor 的样式库 -->   <link rel="stylesheet" href="$path/simditor/styles/simditor.css" type="text/css">   <!-- 导入 simditor 的 JavaScript 库 -->   <script type="text/javascript" src="$path/simditor/scripts/jquery.min.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/module.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/hotkeys.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/uploader.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/simditor.min.js"></script>     </head>  <body>     ## 登录状态栏 开始   <div class="id="topnav" class="f_r">     <span class="welcome cell-8">      ## 在 $ 之后 表达式之前使用 ! 表示 安静模式 ( 静默模式 )      <b>欢迎$!user.username来到爱问社区</b>     </span>     <span class="login-operation cell-4">      #if( $user )       <a href="$path/ask.html">提问</a>       <em>|</em>       <a href="$path/myQuestion.do">我的提问</a>       <em>|</em>       <a href="$path/logout.do">注销</a>      #else       <a href="$path/login.html">登录</a>       <em>|</em>       <a href="$path/regist.html">注册</a>      #end     </span>   </div> ## 登录状态栏 结束      <div class="brand-container auto-height">    <div class="cell-2">     <a href="$path"></a>    </div>    <div class="slogan cell-10">     <div>     爱问社区,这里可以logo     </div>    </div>   </div>      <div class="container message-container">    <!-- 显示提示信息的地方 -->    #if( $askFail )     $askFail     $scope.remove( $session , 'askFail' )    #end   </div>      #if( $user )   <!-- 提问表单 提交给 ask.do 对应的 Servlet 处理 -->   <form action="$path/ask.do" method="post" >   <!-- 提问区域 开始 -->   <div class="container topic-ask-container clear shadow-outside auto-height" >    <!-- 问题的标题 和 提问按钮 -->    <div class="container title-container">     <div class="cell-11">      <input type="text" name="title" placeholder="请输入你要提问的问题的标题" class="u-ipt">     </div>     <div class="cell-1">      <input type="submit" value="提问" class="u-btn u-btn-c4">     </div>    </div>        <div class="line"></div>        <!-- 问题的内容 -->    <div>     <textarea name="content" id="contentEditor" ></textarea>     <script type="text/javascript" >      var editor = new Simditor( {       textarea : $('#contentEditor'),       placeholder : '请在这里输入问题的内容...',       toolbar : true      } );     </script>    </div>        <div class="line"></div>        <!-- 最底部的提问按钮 -->    <div class="container title-container">     <div class="cell-11" style="height: 1px ;"></div>     <div class="cell-1">      <input type="submit" value="提问" class="u-btn u-btn-c4">     </div>    </div>   </div> <!-- 提问区域 结束 -->   </form>   #else    <div style="text-align:center ; min-height: 400px ; line-height: 400px ;">     登录以后才能发起提问,请<a href="$path/login.html" >登录</a>    </div>   #end      <div class="line"></div>      <div class="container link-container">    <a href="$path/list.do" >问题列表</a>    |    <a href="$path/index.html" >返回首页</a>   </div>      <div class="container copyright-container">    © 2017 爱问社区版权所有   </div>     </body> </html> 

回答Servlet处理代码:

@WebServlet("/answer.do") public class AnswerServlet extends HttpServlet {   private static final long serialVersionUID = 8578962149437664830L;   @Override  protected void service(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {    // 从 请求中获得请求参数的值   String id = request.getParameter("id");    if (StringHelper.notEmpty(id)) {     try {     int topicId = Integer.parseInt(id); // 将字符串按照 十进制 解析问 int 类型数值      // 根据得到的 问题的 主键 查询数据库,得到 详细信息     final String SQL = "SELECT id , title , content , publish_time , publish_ip , user_id FROM t_topic WHERE id = ? ";      ResultSet rs = JdbcHelper.query(SQL, topicId);      Topic t = null;     int userId = -1;      if (rs.next()) { // 当 根据 问题的主键 获取到 问题信息时      t = new Topic(); // 创建 Topic 对象       t.setId(rs.getInt(1)); // 将 结果集 中的 该行数据 封装到 t 对象的 id 属性中      t.setTitle(rs.getString(2));      t.setContent(rs.getString(3));      t.setPublishTime(rs.getTimestamp(4));      t.setPublishIp(rs.getString(5));       userId = rs.getInt(6);     }      JdbcHelper.release(rs); // 关闭结果集      // 获得提问者     final String getUserSQL = "SELECT id , username , password FROM t_user WHERE id = ? ";     rs = JdbcHelper.query(getUserSQL, userId);     if (userId != -1 && rs.next()) {      User u = new User();      // 封装数据      u.setId(rs.getInt(1));      u.setUsername(rs.getString(2));      u.setPassword(rs.getString(3));      // 将获取到的用户数据设置到 Topic 对象的 user 属性中      t.setUser(u);     }      HttpSession session = request.getSession();     session.setAttribute("topic", t);      response.sendRedirect(request.getContextPath() + "/answer.html");      return; // 让方法立即结束    } catch (NumberFormatException e) {     e.printStackTrace();     // response.sendRedirect( request.getContextPath() + "/list.do" );    } catch (SQLException e) {     e.printStackTrace();     // response.sendRedirect( request.getContextPath() + "/list.do" );    }    } else {    // response.sendRedirect( request.getContextPath() + "/list.do" );   }    response.sendRedirect(request.getContextPath() + "/list.do");   }  } 

回答前台代码:

<!DOCTYPE html> <html>  <head>   <meta charset="UTF-8">   <title>解答: $topic.title</title>   <link rel="stylesheet" href="$path/styles/general.css">   <link rel="stylesheet" href="$path/styles/cell.css">   <link rel="stylesheet" href="$path/styles/wen.css">      <!-- 链接 simditor 的样式库 -->   <link rel="stylesheet" href="$path/simditor/styles/simditor.css" type="text/css">   <!-- 导入 simditor 的 JavaScript 库 -->   <script type="text/javascript" src="$path/simditor/scripts/jquery.min.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/module.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/hotkeys.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/uploader.js"></script>   <script type="text/javascript" src="$path/simditor/scripts/simditor.min.js"></script>     </head>  <body>     ## 登录状态栏 开始   <div class="login-status-container auto-height">     <span class="welcome cell-8">      ## 在 $ 之后 表达式之前使用 ! 表示 安静模式 ( 静默模式 )      <b>欢迎$!user.username来到爱问社区</b>     </span>     <span class="login-operation cell-4">      #if( $user )       <a href="$path/ask.html">提问</a>       <em>|</em>       <a href="">我的提问</a>       <em>|</em>       <a href="$path/logout.do">注销</a>      #else       <a href="$path/login.html">登录</a>       <em>|</em>       <a href="$path/regist.html">注册</a>      #end     </span>   </div> ## 登录状态栏 结束      ## 标志区域   <div class="brand-container auto-height">    <div class="logo cell-2">     <a href="$path"></a>    </div>    <div class="slogan cell-10">     <div>     解答问题     </div>    </div>   </div>       <div>     <h3>$topic.title</h3>     <div class="line"></div>     <div>      $topic.content     </div>     <div>      提问时间: $topic.publishTime / 提问者: $topic.user.username     </div>    </div>        <!-- 解答的内容 -->    <form action="$path/explain.do" method="post" >     <input type="hidden" name="id" value="$topic.id" >    <div>     <textarea name="content" id="contentEditor" ></textarea>     <script type="text/javascript" >      var editor = new Simditor( {       textarea : $('#contentEditor'),       placeholder : '请在这里输入问题的内容...',       toolbar : true      } );     </script>    </div>    <input type="submit" value="提交解答">    </form>            $scope.remove( $session , 'topic' );      <div class="line"></div>      <div class="container link-container">    <a href="$path/ask.html" >发起新问题</a>    |    <a href="$path/index.html" >返回首页</a>   </div>      <div class="container copyright-container">    © 2017 爱问社区版权所有   </div>    </body> </html> 

以下是使用simditor的方法,需要引入simditor中的css和js样式。simditor下载地址

<textarea name="content" id="contentEditor" ></textarea> <script type="text/javascript" >      var editor = new Simditor( {       textarea : $('#contentEditor'),       placeholder : '请在这里输入问题的内容...',       toolbar : true      } ); </script> 

解答问题Servlet处理,这里需要获取提问者,提问问题以及该问题的已有答案,已有答案回答者。

@WebServlet("/detail.do") public class DetailServlet extends HttpServlet {  private static final long serialVersionUID = -3202278077673657729L;  @Override  protected void service(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {  // 从 请求中获得请求参数的值  String id = request.getParameter("id");  if (StringHelper.notEmpty(id)) {   try {   int topicId = Integer.parseInt(id); // 将字符串按照 十进制 解析问 int 类型数值   // 根据得到的 问题的 主键 查询数据库,得到 详细信息   final String SQL = "SELECT id , title , content , publish_time , publish_ip , user_id FROM t_topic WHERE id = ? ";   ResultSet rs = JdbcHelper.query(SQL, topicId);   Topic t = null;   /*int userId = -1;*/   if (rs.next()) { // 当 根据 问题的主键 获取到 问题信息时    t = new Topic(); // 创建 Topic 对象    t.setId(rs.getInt(1)); // 将 结果集 中的 该行数据 封装到 t 对象的 id 属性中    t.setTitle(rs.getString(2));    t.setContent(rs.getString(3));    t.setPublishTime(rs.getTimestamp(4));    t.setPublishIp(rs.getString(5));    User user = new User();    user.setId(rs.getInt(6));    t.setUser(user);   }   JdbcHelper.release(rs); // 关闭结果集   // 获得提问者   final String getUserSQL = "SELECT id , username , password FROM t_user WHERE id = ? ";   rs = JdbcHelper.query(getUserSQL, t.getUser().getId());   if(rs.next())   {    User u = new User();    // 封装数据    u.setId(rs.getInt(1));    u.setUsername(rs.getString(2));    u.setPassword(rs.getString(3));    // 将获取到的用户数据设置到 Topic 对象的 user 属性中    t.setUser(u);    System.out.println("message username:" + rs.getString(2));   }   JdbcHelper.release(rs); // 关闭结果集   // 获得当前的问题的所有解答   String explainSQL = "SELECT id , content , explain_time , explain_ip , user_id from t_explain where topic_id = ? ";   rs = JdbcHelper.query(explainSQL, topicId);   @SuppressWarnings("unused")   int explainerId = -1;   List<Explain> explains = new ArrayList<>();   while (rs.next()) {    Explain e = new Explain();    e.setId(rs.getInt(1));    e.setContent(rs.getString(2));    e.setExplainTime(rs.getTimestamp(3));    e.setExplainIp(rs.getString(4));    User user=new User();    user.setId(rs.getInt(5));    e.setUser(user);    explains.add(e);    System.out.println("explain userID:" + rs.getInt(5));   }   // 获得解答者   List<Explain>explainList = new ArrayList();   for(int i=0;i<explains.size();i++)   {    Explain explain1 = explains.get(i);    final String getExplainerSQL = "SELECT id , username , password FROM t_user WHERE id = ? ";        rs = JdbcHelper.query(getExplainerSQL, explain1.getUser().getId());    if (rs.next()) {     User u = new User();     // 封装数据     u.setId(rs.getInt(1));     u.setUsername(rs.getString(2));     u.setPassword(rs.getString(3));     // 将获取到的用户数据设置到 Topic 对象的 user 属性中     explain1.setUser(u);     explainList.add(explain1);     System.out.println("explain username:" + rs.getString(2));    }    JdbcHelper.release(rs); // 关闭结果集    /*t.setExplains(explains); // 将解答设置到 Topic 对象上 */  }   t.setExplains(explainList);      /*** 为 所有的解答,获取解答者的详细信息 ***/   HttpSession session = request.getSession();   session.setAttribute("topic", t);   response.sendRedirect( request.getContextPath() + "/detail.html" );   return; // 让方法立即结束   } catch (NumberFormatException e) {   e.printStackTrace();    } catch (SQLException e) {   e.printStackTrace();    }  } else {  }  response.sendRedirect(request.getContextPath() + "/list.do");   }  } 

解答问题前台显示界面代码;

<!DOCTYPE html>  <html>  <head>   <meta charset="UTF-8">   <title>$topic.title</title>   <link rel="shortcut icon" href="$path/images/icon.png" type="image/png">   <link rel="stylesheet" href="$path/styles/general.css">   <link rel="stylesheet" href="$path/styles/cell.css">   <link rel="stylesheet" href="$path/styles/wen.css">  </head>  <body>     ## 登录状态栏 开始   <div class="login-status-container auto-height">     <span class="welcome cell-8">      ## 在 $ 之后 表达式之前使用 ! 表示 安静模式 ( 静默模式 )      <b>欢迎$!user.username来到问道</b>     </span>     <span class="login-operation cell-4">      #if( $user )       <a href="$path/ask.html">提问</a>       <em>|</em>       <a href="">我的提问</a>       <em>|</em>       <a href="$path/logout.do">注销</a>      #else       <a href="$path/login.html">登录</a>       <em>|</em>       <a href="$path/regist.html">注册</a>      #end     </span>   </div> ## 登录状态栏 结束      ## 标志区域   <div class="brand-container auto-height">    <div class="logo cell-2">     <a href="$path"></a>    </div>    <div class="slogan cell-10">     <div>     </div>    </div>   </div>      <div>    <h3>$topic.title</h3>    <div class="line"></div>    <div>     $topic.content    </div>    <div>     提问时间: $topic.publishTime / 提问者: $topic.user.username    </div>   </div>      <div>    #foreach( $ex in $topic.explains)     <div> $ex.content </div>     <div class="line"></div>    #end   </div>      $scope.remove( $session , 'topic' );      <div class="line"></div>      <div class="container link-container">    <a href="$path/ask.html" >发起新问题</a>    |    <a href="$path/index.html" >返回首页</a>   </div>      <div class="container copyright-container">    © 2017 爱问社区版权所有   </div>    </body> </html> 

我的解答Servlet处理代码:

@WebServlet("/myAnswer.do") public class MyAnswerServlet extends HttpServlet {   private static final long serialVersionUID = -3020889403557912216L;   @Override  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    HttpSession session = request.getSession();   User user = (User) session.getAttribute( "user" ); // 在登录时将 User 对象放入了 会话 中   Explain ex=null;   final List<Explain> exp = new ArrayList<>();   if( user != null ) {   int myid=user.getId();   final String SQL = "SELECT id ,content ,explain_time , explain_ip , user_id ,topic_id FROM t_explain WHERE user_id = ? ";   ResultSet rs = JdbcHelper.query(SQL, myid);   //Topic t=null;   //final List<Explain> explains = new ArrayList<>();   @SuppressWarnings("unused")   int topicId=-1;   try {    while( rs.next() )    {    ex=new Explain();    ex.setId(rs.getInt(1));    ex.setContent(rs.getString(2));    ex.setExplainTime(rs.getTimestamp( 3 ));    ex.setExplainIp(rs.getString(4));    ex.setUser(user);    Topic to=new Topic();    to.setId(rs.getInt(6));    ex.setTopic(to);    topicId=rs.getInt(6);    exp.add(ex);        }    JdbcHelper.release(rs); // 关闭结果集        for(int i = 0 , len = exp.size() ; i < len ; i++)    {    Explain explain=exp.get(i);    Topic tid=explain.getTopic();    final String tSQL = "SELECT id , title , content , publish_time , publish_ip , user_id FROM t_topic WHERE id = ? ";    ResultSet trs = JdbcHelper.query(tSQL, tid.getId());    while(trs.next())    {     Topic t=new Topic();     t.setId(1);     t.setTitle(trs.getString(2));     t.setContent(trs.getString(3));     t.setPublishTime(trs.getTimestamp(4));     t.setPublishIp(trs.getString(5));     ex.setTopic(t); //    explains.add(ex);     System.out.println( "我的tid: " + tid.getId());    }        JdbcHelper.release(trs); // 关闭结果集    }           } catch (SQLException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }         session.setAttribute("explains", exp);      System.out.println( "我的解答列表: " + exp );   System.out.println( "我的id: " + myid);   response.sendRedirect( request.getContextPath() + "/myAnswer.html");   }  }    } 

我的解答前台展示页面代码:

<!DOCTYPE html> <html> <head>  <meta charset="utf-8" />  <title>解答</title>  <link rel="stylesheet" href="$path/styles/top.css">   </head> <body> <div style="margin-left:320px;"> <nav id="topnav" class="f_r">  <ul>   <a href="$path/index.html"">首页</a> <a href="$path/myQuestion.do" >我的提问</a>   <a href="$path/ask.html" >提问</a> <a href="$path/logout.do">注销</a>  </ul>  </nav>  </div> #if( $user ) $user.username的所有回答: #end #foreach( $ex in $explains) <div class="blogs"> <ul>  <p>$ex.content</p>  <div class="content_time">   <p> 解答时间:<span class="dtime f_l"> $ex.explainTime</span></p>  </div>  <div class="line"></div> </ul> </div> #end  </body> </html> 

我的提问Servlet处理:

@WebServlet("/myQuestion.do") public class MyQuestionServlet extends HttpServlet {   private static final long serialVersionUID = -4110483126223561394L;   @Override  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    HttpSession session = request.getSession();   User user = (User) session.getAttribute( "user" ); // 在登录时将 User 对象放入了 会话 中   if( user != null ) {   int myid=user.getId();   final String SQL = "SELECT id , title , content, publish_time , publish_ip FROM t_topic WHERE user_id = ? ";   ResultSet rs = JdbcHelper.query(SQL, myid);   final List<Topic> qtopics = new ArrayList<>();   try {    while( rs.next() ){    Topic t=new Topic();    t.setId(rs.getInt(1));    t.setTitle(rs.getString(2));    t.setContent(rs.getString(3));    t.setPublishTime(rs.getTimestamp(4));    t.setPublishIp(rs.getString(5));    qtopics.add(t);            }   } catch (SQLException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }         session.setAttribute("qtopics", qtopics);      System.out.println( "我的提问列表: " + qtopics );   System.out.println( "我的id: " + myid);   response.sendRedirect( request.getContextPath() + "/myQuestion.html");   }  }    } 

我的提问展示代码:

<!DOCTYPE html> <html> <head>  <meta charset="utf-8" />  <title>$user.username的提问 </title>   <link rel="stylesheet" href="$path/styles/general.css">   <link rel="stylesheet" href="$path/styles/cell.css">   <link rel="stylesheet" href="$path/styles/wen.css">   <link rel="stylesheet" href="$path/styles/top.css"> </head> <body>   <div style="margin-left:320px;">    <ul>    #if($user)      <nav id="topnav" class="f_r">       <ul>        <a href="$path/index.html">首页</a>        <a href="$path/myAnswer.do" >我的解答</a>        <a href="$path/ask.html">提问</a>        <a href="$path/logout.do" >注销</a>       </ul>      </nav>      #else      <li class="presentation"><a href="$path/login.html" id="link" title="提问">登录</a></li>     <li class="presentation"><a href="$path/regist.do" id="tools" title="exit">注册</a></li>     #end    </ul> </div>  #if( $user )     $user.username的所有提问:     #end     #foreach( $qto in $qtopics)  <div class="blogs">   <ul>    <p>$qto.content</p>    <p class="autor"><span class="lm f_l"><a>提问者:$user.username</a></span> <span class="dtime f_l">$qto.publishTime</span></p>   </ul>      </div>   #end  </body> </html> 

验证码处理的Servlet代码:

@WebServlet(urlPatterns= { "/verify/login.do" , "/verify/regist.do" } ) public class VerifyCodeServlet extends HttpServlet {    private static final long serialVersionUID = 3398560501558431737L;   @Override  protected void service( HttpServletRequest request , HttpServletResponse response )    throws ServletException, IOException {      // 获得 当前请求 对应的 会话对象   HttpSession session = request.getSession();      // 从请求中获得 URI ( 统一资源标识符 )   String uri = request.getRequestURI();   System.out.println( "hello : " + uri );      final int width = 180 ; // 图片宽度   final int height = 40 ; // 图片高度   final String imgType = "jpeg" ; // 指定图片格式 (不是指MIME类型)   final OutputStream output = response.getOutputStream(); // 获得可以向客户端返回图片的输出流 (字节流)   // 创建验证码图片并返回图片上的字符串   String code = GraphicHelper.create( width, height, imgType, output );   System.out.println( "验证码内容: " + code );      // 建立 uri 和 相应的 验证码 的关联 ( 存储到当前会话对象的属性中 )   session.setAttribute( uri , code );      System.out.println( session.getAttribute( uri ) );     }  } 

注册前台界面,有验证码验证功能:

<!DOCTYPE html> <html> <head>  <meta charset="UTF-8">  <title>注册爱问社区</title>   <link rel="stylesheet" href="$path/styles/general.css">  <link rel="stylesheet" href="$path/styles/cell.css">  <link rel="stylesheet" href="$path/styles/form.css">   <link rel="stylesheet" href="$path/awesome/css/font-awesome.min.css">    <script type="text/javascript" src="$path/js/wen.js"></script>   <style type="text/css" >    .logo-container {    margin-top: 50px ;   }   .logo-container img {    width: 100px ;   }    .message-container {    height: 80px ;   }    .link-container {    height: 40px ;    line-height: 40px ;   }    .link-container a {    text-decoration: none ;   }   </style>  </head> <body>  <div class="container title-container" style="color:blue; margin-top:60px;">加入爱问社区,为您答疑解惑</div> <div class="container form-container">  <form action="$path/regist.do" method="post">   <div class="form"> <!-- 注册表单开始 -->     <div class="form-row">       <span class="cell-1">        <i class="fa fa-user"></i>       </span>       <span class="cell-11" style="text-align: left;">        <input type="text" name="username" placeholder="请输入用户名">       </span>    </div>     <div class="form-row">       <span class="cell-1">        <i class="fa fa-key"></i>       </span>       <span class="cell-11" style="text-align: left;">        <input type="password" name="password" placeholder="请输入密码">       </span>    </div>     <div class="form-row">       <span class="cell-1">        <i class="fa fa-keyboard-o"></i>       </span>       <span class="cell-11" style="text-align: left;">        <input type="password" name="confirm" placeholder="请确认密码">       </span>    </div>        <div class="form-row">       <span class="cell-7">        <input type="text" name="verifyCode" placeholder="请输入验证码">       </span>       <span class="cell-5" style="text-align: center;">        <img src="$path/verify/regist.do" onclick="myRefersh(this)">       </span>    </div>     <div class="form-row" style="border: none;">       <span class="cell-6" style="text-align: left">        <input type="reset" value="重置">       </span>       <span class="cell-6" style="text-align:right;">        <input type="submit" value="注册">       </span>    </div>    </div> <!-- 注册表单结束 -->  </form> </div> <div class="container message-container">  <!-- 显示提示信息的地方 -->  #if( $registFail )   $registFail   $scope.remove( $session , 'registFail' )  #end </div> <div class="container link-container">  <a href="$path/login.html" > 已注册爱问帐号,点击这里登录</a>  |  <a href="$path/index.html" >返回首页</a> </div> <div class="container copyright-container">  © 2017 爱问社区版权所有 </div>  </body> </html> 

Servlet处理注册,实现验证码验证:

@WebServlet("/regist.do") public class RegistServlet extends HttpServlet {   private static final long serialVersionUID = 7493633832455111617L;   @Override  protected void service( HttpServletRequest request , HttpServletResponse response )    throws ServletException, IOException {      // 获得来自 页面 表单上的数据   String verifyCode = request.getParameter( "verifyCode" ) ; // 获得由用户输入的那个验证码   String username = request.getParameter( "username" ) ;   String password = request.getParameter( "password" ) ;   String confirm = request.getParameter( "confirm" ) ;      System.out.println( "username : " + username );   System.out.println( "password : " + password );   System.out.println( "confirm : " + confirm );   System.out.println( "verifyCode : " + verifyCode );      HttpSession session = request.getSession();   // 获得 在 会话 中存储的那个 为登录进行验证的 验证码   final String code = (String)session.getAttribute( "/wendao/verify/regist.do" );   System.out.println( "session code : " + code );      // 比较验证码   if( StringHelper.equals( verifyCode , code ) ){    // 要保证 用户名 不为空 、密码不能为空 、两次输入的密码必须一致    if( StringHelper.notEmpty( username )      && StringHelper.notEmpty( password )      && StringHelper.equals( password , confirm) ) {     // 可以保存了     String SQL = "INSERT INTO t_user ( username , password ) VALUES ( ? , ? ) " ;     int n = JdbcHelper.insert( SQL , false , username , StringHelper.MD5(password));     if( n > 0 ) { // 如果 insert 返回 大于 0 的数字 , 则表示 插入成功      // 保存成功以后,应该去一个新的页面 ( 比如去 登录页面 )      response.sendRedirect( request.getContextPath() + "/login.html" );     } else {      // 回到注册页面去      session.setAttribute( "registFail" , "注册失败,可能是用户名被占用了" );      response.sendRedirect( request.getContextPath() + "/regist.html" );     }    } else {     // 回到注册页面去     session.setAttribute( "registFail" , "用户名或密码为空,或者密码不一致" );     response.sendRedirect( request.getContextPath() + "/regist.html" );    }   } else {    // 如果验证码不一致,设置提示信息后回到注册页面去    session.setAttribute( "registFail" , "验证码输入错误,请重新输入" );    response.sendRedirect( request.getContextPath() + "/regist.html" );   }     }    } 

登录Servlet处理代码:

@WebServlet("/login.do") public class LoginServlet extends HttpServlet {   private static final long serialVersionUID = 18854422651747352L;   @Override  protected void service( HttpServletRequest request , HttpServletResponse response )    throws ServletException, IOException {      // 获得来自 页面 表单上的数据   String username = request.getParameter( "username" ) ;   String password = StringHelper.MD5(request.getParameter( "password" )) ;      System.out.println( "username : " + username );   System.out.println( "password : " + password );      HttpSession session = request.getSession();           // 登录 : 根据 用户名 和 密码 从数据库中查询数据,如果都正确,就将这些数据放入到会话中,最后进入到指定页面( list.html )    String SQL = "SELECT id , username , password FROM t_user WHERE username = ? and password = ? " ;    ResultSet rs = JdbcHelper.query( SQL, username , password ) ;        try{     // 如果查询到数据,就包装到一个对象中     if( rs.next() ) {      User user = new User(); // 创建对象            // 封装数据      user.setId( rs.getInt( 1 ) );      user.setUsername( rs.getString( 2 ));      user.setPassword( rs.getString( 3 ) ) ;      //System.out.println("测试"+MD5.convertMD5(MD5.convertMD5(password)));      /** 将 User 对象 放入到 会话中 **/      session.setAttribute( "user" , user );      // 重定向到 list.do ( list.do 会先查询数据后 再 重定向到 list.html )      response.sendRedirect( request.getContextPath() + "/list.do" );     } else {      // 如果 用户名 或 密码 错误,重新返回到 登录页面       session.setAttribute( "loginFail" , "用户名或密码错误" );      response.sendRedirect( request.getContextPath() + "/login.html" );     }    } catch ( SQLException e ){     e.printStackTrace();    }  }  } 

登录前台展示界面代码;

<!DOCTYPE html> <html> <head>  <meta charset="UTF-8">  <title>登录</title>   <link rel="stylesheet" href="styles/general.css">  <link rel="stylesheet" href="styles/cell.css">  <link rel="stylesheet" href="styles/form.css">   <link rel="stylesheet" href="awesome/css/font-awesome.min.css">  <link rel="stylesheet" type="text/css" href="css/login.css">  <script type="text/javascript" src="js/wen.js"></script>  </head> <body>  <div class="logina-logo" style="height: 55px">    <div id="venusLogo"><p><span>爱问社区</span></p></div>   </div>   <div class="logina-main main clearfix">    <div class="tab-con">     <form action="$path/login.do" method="post">      <div id='login-error' class="error-tip"></div>      <table border="0" cellspacing="0" cellpadding="0">       <tbody>        <tr>         <th>账户</th>         <td width="245">          <input type="text" name="username" id="username" placeholder="昵称" />         <td>         </td>        </tr>        <tr>         <th>密码</th>         <td width="245">          <input type="password" name="password" id="password" placeholder="密码" />         </td>         <td>         </td>        </tr>        <tr>         <th></th>         <td width="245"><input class="confirm" type="submit" value="登 录"></td>         <td></td>        </tr>       </tbody>      </table>     </form>    </div>    <div class="reg">     <p>还没有账号?<br>赶快免费注册一个吧!</p>     <a class="reg-btn" href="regist.html">立即免费注册</a>    </div>   </div>   <div id="footer">    <div class="copyright">Copyright © 爱问社区 版权所有</div>   </div>  </body> </html> 

好啦,基本的代码就展示完了,还有比较通用的POJO类和jdbc连接数据库的类就不做展示了,贴上数据库SQL代码,需要的可以根据字段来写

DROP TABLE IF EXISTS `t_explain`; CREATE TABLE `t_explain` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `content` text,  `explain_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,  `explain_ip` varchar(50) DEFAULT NULL,  `user_id` int(8) DEFAULT NULL,  `topic_id` int(8) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `ex_id` (`user_id`),  KEY `t_id` (`topic_id`),  CONSTRAINT `ex_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`),  CONSTRAINT `t_id` FOREIGN KEY (`topic_id`) REFERENCES `t_topic` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;  -- ---------------------------- -- Table structure for t_topic -- ---------------------------- DROP TABLE IF EXISTS `t_topic`; CREATE TABLE `t_topic` (  `id` int(10) NOT NULL AUTO_INCREMENT,  `title` varchar(255) DEFAULT NULL,  `content` text,  `publish_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  `publish_ip` varchar(100) DEFAULT NULL,  `user_id` int(10) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `cid` (`user_id`),  CONSTRAINT `cid` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;  -- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` (  `id` int(10) NOT NULL AUTO_INCREMENT,  `username` varchar(20) NOT NULL,  `password` varchar(255) NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8; 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表