[学习笔记]ajax 动态加载的FAQ (frequently asked question)

本文介绍了一个基于Java和JSP实现的动态加载FAQ(常见问题解答)的案例。通过客户端JavaScript触发AJAX请求,从服务器端获取指定ID的FAQ详情并显示在网页上。服务器端使用MySQL数据库存储FAQ数据,并通过PreparedStatement执行SQL查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图为:

======================================================点击超级链接效果为==============

 

 

数据库设计

create table faq(
id int(11) not null auto_increment,

faq varchar(255)  not null,

detail varchar(255)  not null,

primary key (id));

插入以下数据

mysql> select * from faq;
+----+-----------+-----------------------+
| id | faq       | detail                |
+----+-----------+-----------------------+
|  1 | 常见问题1 | <p>问题详细内容</p>   |
|  2 | 常见问题2 | <p>问题二详细内容</p> |
|  3 | 常见问题3 | <p>问题三详细内容</p> |

 

 

 

cn.java.DB 则指的是连接的数据库

 

package cn.java;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


/**
 *
 * 
@author he
 
*/

public class DB {
    
    
    
static{
        
        
try{
      Class.forName(
"com.mysql.jdbc.Driver");
        }
catch(Exception e){
        e.getStackTrace();
        }

    }

/**
 * public static void getConnection()
 * 
 * 由于已经有了连接池DataPool
 * 则可以直接使用getDataPool()获得数据源ds
 * ds.getConnection();由于在建立连接池的时候
 * 采用的是mySql 用户名root,密码root都已经添加过了,所以没有必要再使用
 * getConnection(String url,String name,String password);来获得连接
 * 
 
*/

    
    
//获得连接
    public static Connection getConnection(){
            DataSource ds 
= null;
            Connection conn 
= null;
            String url
="jdbc:mysql://127.0.0.1/test";
            String name
="root";
            String password
="root";
        
try {
          
//  ds = getDataPool();
            
            conn
=DriverManager.getConnection(url,name,password);
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
       
        }

        
return conn;
       
    }

    
    
/**
 * 建立数据源名字为DataPool
 * 也就是所谓的连接池。
 
*/

    
private static DataSource getDataPool() throws NamingException {
        Context c 
= new InitialContext();
        
return (DataSource) c.lookup("java:comp/env/DataPool");
    }

    
/**
     * 创建Statement类的对象
     
*/

    
    
public static Statement getStmt(Connection conn){
           Statement stmt 
= null;
        
try {
           stmt 
= conn.createStatement();
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
        }

        
return stmt;
    
    }

    
/**
     * 查询语句的结果集
     
*/

    
public static ResultSet executeQuery(Statement stmt,String sql){
        ResultSet rs 
= null;
        
try {
             rs 
= stmt.executeQuery(sql);
         
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
        }

        
return rs;
    }

/**
 更新语句的执行
 *
 
*/

    
public static void executeUpdate(Statement stmt,String sql){
        
try {
            stmt.executeUpdate(sql);
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    
/** 
     * PreparedStatement prepareStatement(String sql,int autoGeneratedKeys)
     * 
     * 创建一个默认 PreparedStatement 对象,该对象能获取自动生成的键。
     * 
     * 获得可动态执行SQL语句的接口(带有自动生成键的)
     *
    
*/

    
public static PreparedStatement prepareKey(Connection conn,String sql,
            
int autoGeneratedKey){
         PreparedStatement pstmt 
= null;
        
try {
           
            pstmt 
= conn.prepareStatement(sql, autoGeneratedKey);
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
        }

        
return pstmt;
    }

    
/**
     * 获得PreparedStatement 对象
     
*/

    
public static  PreparedStatement prepareStmt(Connection conn,String sql){
        PreparedStatement pstmt 
= null;
        
try {
           
            pstmt 
= conn.prepareStatement(sql);
        }
 catch (SQLException ex) {
            Logger.getLogger(DB.
class.getName()).log(Level.SEVERE, null, ex);
        }

        
return pstmt;
        
    }

    
/**
     * 设置统一关闭方法
     
*/

     
public static void close(Connection conn, Statement stmt, ResultSet rs) {
        
try {

            
if (rs != null{
                rs.close();
                rs 
= null;
            }


            
if (stmt != null{
                stmt.close();
                stmt 
= null;
            }


            
if (conn != null{
                conn.close();
                conn 
= null;
            }


        }
 catch (SQLException e) {
            e.printStackTrace();
        }


    }

}

 

// 用户操作界面  index.jsp

 

 

<%@page contentType="text/plain; charset=UTF-8"%>
<%@page language="java" %>
<%@page import="java.sql.*"%>
<%@page import="cn.java.DB"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   
"http://www.w3.org/TR/html4/loose.dtd">

<html>
    
<head>
        
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        
<title>动态加载 FAQ</title>
        
<script type="text/javascript">
            
var xmlHttp; //用来保存xmlhttpRequest 对象的全局对象
            var currFaqId;//用来保存当前想要获取的FAQ编号
            //用于创建XMLHttpRequest 对象
            function createXmlHttp(){
        
//根据window.XMLHttpRequest 对象是否存在使用不同的创建方式
        if(window.XMLHttpRequest){
             xmlHttp
=new XMLHttpRequest();   //FireFox ,opera 等浏览器支持的创建方式 
        }
else{
             xmlHttp
=new ActiveObject("Microsoft.XMLHTTP");//IE 浏览器支持的创建方式
            }

       }

       
//获取FAQ信息的调用函数
       function loadFAQ(faqId){
       currFaqId
=faqId;
       
var currFaqDetail=getFaqDetailDiv(faqId); //获取对应的faqDetail节点
       //判断FAQ详细信息是否已存在,入伙不存在则从服务器获取
       if(currFaqDetail.style.display=="none"){
           currFaqDetail.style.display
="block";//设置div状态为“显示”
          if(currFaqDetail.innerHTML==""){
           createXmlHttp();
           xmlHttp.onreadystatechange
=loadFAQCallback;
           xmlHttp.open(
"GET","read_faq.jsp?faqId="+faqId,true);
           xmlHttp.send(
null);
     }
 
   }
else{
    currFaqDetail.style.display
="none"//设置div 状态为“隐藏”
}

   }

   
   
   
//获取faqId 信息的回调函数
   function  loadFAQCallback(){
   
if(xmlHttp.readyState==4){
//将FAQ 信息写入到对应的DIV
        getFaqDetailDiv(currFaqId).innerHTML=xmlHttp.responseText;

    }

}


function  getFaqDetailDiv(faqId){
return document.getElementById("faqDetail"+faqId);
}


  
</script>
    
</head>
    
<body>
        
        
<h1>FAQ (常见问题)</h1>
        
<%
        String sql
="select id,faq from faq order by id asc"//定义查询数据库SQL 语句
        Connection conn=null;
        PreparedStatement pstmt
=null;
        ResultSet rs
=null;
        
        
try{
       conn
= DB.getConnection();
        pstmt
=conn.prepareStatement(sql);
        rs
=pstmt.executeQuery();
        
while(rs.next()){
        
%>
        
        
<div>
            
<a href="#" onclick="loadFAQ(<%=rs.getInt(1)%>);return false;">
            
<%=rs.getString(2%>
            
</a>
            
</div>
            
<div id="faqDetail<%=rs.getInt(1)%>"  style="display:none"></div>
            
        
<% }

        
        }
catch(SQLException e){
        System.out.println(e.toString());
        }
finally{
        DB.close(conn, pstmt, rs);
        }

        
%>
    
</body>
</html>

 

//服务器端响应文件 read_faq.jsp

<%@page contentType="text/plain; charset=UTF-8"%>
<%@page language="java" %>
<%@page import="java.sql.*"%>
<%@page import="cn.java.DB"%>
<%

out.clear(); 
//清空当前的输出内容(空格和换行符)

String faqIdStr
=request.getParameter("faqId");

String faqDetail
=null;  //用于保存FAQ 详细信息
 if(faqIdStr!=null){
   
int faqId=Integer.parseInt(faqIdStr);
   String sql
="select detail from faq where id=?";
    Connection conn
=null;
        PreparedStatement pstmt
=null;
        ResultSet rs
=null;
        
        
try{
       conn
= DB.getConnection();
        pstmt
=conn.prepareStatement(sql);
        pstmt.setInt(
1,faqId);
        rs
=pstmt.executeQuery();
      
if(rs.next()){
   faqDetail
=rs.getString(1);
 }

        }
catch(SQLException e){
            System.out.println(e.toString());
            
        }
finally{
        DB.close(conn, pstmt, rs);
        }

 
 }


//根据faqDetail 是否包含正确内容 决定输出的信息
if(faqDetail!=null){
out.println(
"详细内容:"+faqDetail);
}
else{
out.println(
"无法获取FAQ 详细信息");
}

        
%>


+----+-----------+-----------------------+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值