Ajax实现全文检索和服务器端分页(原创)

    技术2022-05-18  14

    http://chaoji-liangbin.blog.163.com/blog/static/2523921220109189730488/

     

    定义的首页:index.jsp

    <%@ page language="java" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">  <head>    <title>Oracle全文检索</title>    <script type="text/javascript" src="../js/main.js" charset="UTF-8"></script>    <script type="text/javascript">     document.onkeydown = function(e){        if(!e) e = window.event;//火狐中是 window.event        if((e.keyCode || e.which) == 13){            document.getElementById("search").click();        }    }    </script>    <style type="text/css">     .mainnews{width: 600px;height:100px;text-align: left;}     .title{width:598px;height:30px;text-align: left;}     .abstract{width: 598px;height:68px;text-align: left;font-size: 15px;}     a:link,a:visited {font-size: 14px;text-decoration: none;}    </style>  </head>  <body>    <div style="text-align: center">     <div><input type="text" id="keyword" />   <input type="button" value="检索" οnclick="searchDocuments(1);" id="search" />   <input id="advcheckbox" type="checkbox" />高级检索</div>     <div><!-- 高级检索条件 --></div>     <br />     <br />     <div id="searchlist" style="width: 500px;text-align: center;">  </div>    </div>  </body></html>

     

    Ajax脚本:main.js

     function searchDocuments(pagenum)   {   var keyword=document.getElementById('keyword').value;   //alert(keyword);   document.getElementById("searchlist").innerHTML="正在查询中,请稍候....";      var http_request = false;      send_request("SearchAction.jsp?keyword="+keyword+"&pagenum="+pagenum);                   //向服务器发起XMLHTTP请求      function send_request(url)      {          //初始化,指定处理函数,发送请求的函数       http_request = false;       //开始初始化XMLHTTPRequest对象        if(window.ActiveXObject)       { //IE浏览器        try{         http_request = new ActiveXObject('Msxm12.XMLHTTP');         }catch(e)         {         try{          http_request = new ActiveXObject("Microsoft.XMLHTTP");         }catch(e)         {            alert(e);         }         }             //alert("IE");        }else if(window.XMLHttpRequest)         { //Mozilla浏览器          http_request = new XMLHttpRequest();         if(http_request.overrideMimeType)         {  //设置MIME类别          http_request.overrideMimeType('text/xml');         }        }         if(!http_request){ //有异常,创建对象实例失败        window.alert("不能创建XMLHTTPRequest对象");        return false;       }              http_request.onreadystatechange = processRequest;  //这里只是指向方法,并未执行方法

            url = encodeURI(url);      url = encodeURI(url);//两次,很关键         //确定发送请求的方式和URL以及是否执行以下代码       http_request.open("GET",url,true);      http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");       http_request.send(null);      }            //处理返回信息的函数      function processRequest(){       if(http_request.readyState == 4){  //判断对象状态        if(http_request.status==200){  //信息已经成功返回         var returnStr = http_request.responseText;          document.getElementById("searchlist").innerHTML=returnStr;        }else{         alert("你所请求的页面有异常");        }       }      }  }  

    Ajax服务器端(jsp页面):SearchAction.jsp

    <%@ page language="java" pageEncoding="UTF-8"%><%@page import="java.net.URLDecoder"%><%@page import="com.gdie.webapp.action.SearchAction"%><%@page import="java.util.ArrayList"%><%@page import="com.gdie.webapp.entry.DocNews"%><% response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); String keyword = URLDecoder.decode(request.getParameter("keyword"),"UTF-8").trim(); String[] keywords = keyword.trim().split(" "); String newkeyword = keywords[0]; if(keywords.length>1){  for(int i=1;i<keywords.length-1;i++){   newkeyword = newkeyword+" or "+keywords[i];  }  newkeyword = newkeyword+" or "+keywords[keywords.length-1]; }else {  newkeyword = keyword; } System.out.println("完整关键字:"+newkeyword); int pagenum = 1;  //当前页数 int newsnum = 10; //每页显示条数 int totalnum = 1;  //总记录数 int pages = 1;   //总页数 if(request.getParameter("pagenum")!=null){  pagenum = Integer.parseInt(request.getParameter("pagenum")); } SearchAction action = new SearchAction(); ArrayList<DocNews> list= action.search(newkeyword.trim(),pagenum,newsnum); totalnum = action.getTotalnum(); StringBuffer sb = new StringBuffer(""); for(int i=0;i<list.size();i++){  String abstractcontent = list.get(i).getAbstractcontent().trim();  int j=0;  for(int k=0;k<keywords.length;k++){   j = abstractcontent.indexOf(keywords[k]);   if(j!=-1) {    keyword = keywords[k];    break;   }  }  StringBuffer abstracthtml = new StringBuffer(abstractcontent.substring(0,j));  //System.out.println("前:"+abstractcontent.substring(0,j));  abstracthtml.append("<span style=/"color: red;/">"+keyword+"</span>");  //System.out.println("后:"+abstractcontent.substring(j+keyword.length()));  abstracthtml.append(abstractcontent.substring(j+keyword.length()));  sb.append("<div class=/"mainnews/">");  sb.append("<div class=/"title/"/"><a href='"+list.get(i).getUrl()+"' target=_blank>"+list.get(i).getTitle()+"</a></div>");  sb.append("<div class=/"abstract/">"+abstracthtml+"</div>");  sb.append("</div>"); } sb.append("<div>"); if(pagenum==1){  sb.append("上一页   "); }else {  sb.append("<a href=/"#/" οnclick=/"searchDocuments("+(pagenum-1)+");/" >上一页</a>   "); } if((list.size()%newsnum!=0&&pagenum==(totalnum/newsnum+1))||(totalnum%newsnum==0&&pagenum==(totalnum/newsnum))){  sb.append("下一页   "); }else {  sb.append("<a href=/"#/" οnclick=/"searchDocuments("+(pagenum+1)+");/" >下一页</a>   "); } if(totalnum%newsnum==0){  pages = totalnum/newsnum; }else {  pages = totalnum/newsnum +1 ; } sb.append("总共"+pages+"页  "+"跳到第"); sb.append("<select id=/"pageselect/" οnchange=/"searchDocuments(document.getElementById('pageselect').value);/">"); for(int i=1;i<=pages;i++){  if(i==pagenum){   sb.append("<option value=/""+i+"/" selected=/"selected/" >"+i+"</option>");  }else {   sb.append("<option value=/""+i+"/">"+i+"</option>");  } } sb.append("</select>页"); sb.append("</div>"); out.print(sb.toString());%>

     

    SearchAction.java:

    package com.gdie.webapp.action;

    import java.math.BigDecimal;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Types;import java.util.ArrayList;

    import oracle.sql.ARRAY;import oracle.sql.STRUCT;

    import com.gdie.webapp.common.DBPool;import com.gdie.webapp.entry.DocNews;

    public class SearchAction {// public ArrayList<DocNews> search(String keyword) {//  ArrayList<DocNews> list = new ArrayList<DocNews>();//  PreparedStatement ps;//  ResultSet rs;//  Connection conn;//  String sql = "Select * from T_DOCNEWS where contains(F_CONTENT,?)>0";//  DocNews docnews;//  try {//   conn = DBPool.getConnection();//   ps = conn.prepareStatement(sql);//   ps.setString(1, keyword);//   rs = ps.executeQuery();//   while (rs.next()) {//    docnews = new DocNews();//    docnews.setId(rs.getInt("F_ID"));//    docnews.setTitle(rs.getString("F_TITLE"));//    docnews.setUrl(rs.getString("F_URL"));//    list.add(docnews);//   }//   if (ps != null) {//    ps.close();//   }//   if (conn != null) {//    conn.close();//   }//  } catch (Exception e) {//   e.printStackTrace();//  }////  return list;// }

     private int totalnum = 0; public ArrayList<DocNews> search(String keyword) {  ArrayList<DocNews> list = new ArrayList<DocNews>();  Connection conn = null;  ResultSet rs = null;  CallableStatement stmt = null;  DocNews docnews;  try {   conn = DBPool.getConnection();   stmt = null;   String procName = new StringBuffer().append("{ call f_content_pro(?,?) } ").toString();   stmt = conn.prepareCall(procName);   stmt.setString(1, keyword);   stmt.registerOutParameter(2, Types.ARRAY, "F_CONTENT_ARR_RE");   stmt.execute();   ARRAY arr = (ARRAY) stmt.getArray(2);   rs = arr.getResultSet();   while (rs.next()) {    STRUCT struct = (STRUCT) rs.getObject(2);    Object[] obs = struct.getAttributes();    docnews = new DocNews();    docnews.setId(((BigDecimal)obs[0]).longValue());    docnews.setUrl((String)obs[1]);    docnews.setTitle((String)obs[2]);    docnews.setAbstractcontent((String)obs[3]);    list.add(docnews);   }   if (stmt != null) {    stmt.close();   }   if (conn != null) {    conn.close();   }  } catch (Exception e) {   e.printStackTrace();  }  return list; }   public ArrayList<DocNews> search(String keyword,int pagenum,int newsnum) {  //带有分页的搜索结果,关键字,当前页,每页显示条数  ArrayList<DocNews> list = new ArrayList<DocNews>();  Connection conn = null;  ResultSet rs = null;  CallableStatement stmt = null;  DocNews docnews;  try {   conn = DBPool.getConnection();   stmt = null;   String procName = new StringBuffer().append("{ call f_content_pro(?,?,?,?,?) } ").toString();   stmt = conn.prepareCall(procName);   stmt.setString(1, keyword);   stmt.setInt(2, pagenum);   stmt.setInt(3, newsnum);   stmt.registerOutParameter(4, Types.ARRAY, "F_CONTENT_ARR_RE");   stmt.registerOutParameter(5, Types.INTEGER);   stmt.execute();   ARRAY arr = (ARRAY) stmt.getArray(4);  //这里的3是对应参数中的列   totalnum = stmt.getInt(5);//   System.out.println("记录总数:"+totalnum);   rs = arr.getResultSet();   while (rs.next()) {    STRUCT struct = (STRUCT) rs.getObject(2);    Object[] obs = struct.getAttributes();    docnews = new DocNews();    docnews.setId(((BigDecimal)obs[0]).longValue());    docnews.setUrl((String)obs[1]);    docnews.setTitle((String)obs[2]);    docnews.setAbstractcontent((String)obs[3]);    list.add(docnews);   }   if (stmt != null) {    stmt.close();   }   if (conn != null) {    conn.close();   }  } catch (Exception e) {   e.printStackTrace();  }  return list; }  // public void callPrTest() {//  Connection conn = null;//  ResultSet rs = null;//  CallableStatement stmt = null;//  try {//   conn = DBPool.getConnection();//   stmt = null;//   String procName = new StringBuffer().append(//     "{ call test_array(?,?) } ").toString();//   stmt = conn.prepareCall(procName);//   // stmt.setObject(1, array, oracle.jdbc.OracleTypes.ARRAY);//   stmt.setString(1, "oracle");//   stmt.registerOutParameter(2, Types.ARRAY, "TEXT_ARR_RE");//   stmt.execute();//   ARRAY arr = (ARRAY) stmt.getArray(2);//   rs = arr.getResultSet();//   while (rs.next()) {//    STRUCT struct = (STRUCT) rs.getObject(2);//    Object[] obs = struct.getAttributes();//    System.out.println("id:" + obs[0] + " ..");//    System.out.println("字段内容:" + obs[1] + " ..");//    System.out.println("开始位置:" + obs[2] + " ..");//    System.out.println("字符长度:" + obs[3] + " ..");//   }//   if (stmt != null) {//    stmt.close();//   }//   if (conn != null) {//    conn.close();//   }//  } catch (Exception e) {//   e.printStackTrace();//  }// }

     public void callContentPRO() {  Connection conn = null;  ResultSet rs = null;  CallableStatement stmt = null;  try {   conn = DBPool.getConnection();   stmt = null;   String procName = new StringBuffer().append("{ call f_content_pro(?,?) } ").toString();   stmt = conn.prepareCall(procName);   // stmt.setObject(1, array, oracle.jdbc.OracleTypes.ARRAY);   stmt.setString(1, "拉蒙");   stmt.registerOutParameter(2, Types.ARRAY, "F_CONTENT_ARR_RE");   stmt.execute();   ARRAY arr = (ARRAY) stmt.getArray(2);   rs = arr.getResultSet();   while (rs.next()) {    STRUCT struct = (STRUCT) rs.getObject(2);    Object[] obs = struct.getAttributes();    System.out.println("id:" + obs[0] + " ..");    System.out.println("url:" + obs[1] + " ..");    System.out.println("标题:" + obs[2] + " ..");    System.out.println("动态摘要:" + obs[3] + " ..");   }   if (stmt != null) {    stmt.close();   }   if (conn != null) {    conn.close();   }  } catch (Exception e) {   e.printStackTrace();  } } public int getTotalnum() {  return totalnum; }

     public void setTotalnum(int totalnum) {  this.totalnum = totalnum; }

     public static void main(String[] args) {//  new SearchAction().callPrTest();//  new SearchAction().callContentPRO();  ArrayList<DocNews> list = new SearchAction().search("菲律宾",2,10);  for (DocNews docNews : list) {   System.out.println("id:"+docNews.getId());   System.out.println("URL:"+docNews.getUrl());   System.out.println("TITLE:"+docNews.getTitle());   System.out.println("content:"+docNews.getAbstractcontent().trim());   System.out.println("=====");  }  // ResultSet rs;  // Connection conn;  // String sql = "Select * from T_DOCNEWS where contains(F_CONTENT,?)>0";  // CallableStatement cstmt = null;  // try {  // conn = DBPool.getConnection();  // cstmt = conn.prepareCall("{call foo.text(?,?)}");  // cstmt.setString(1, "oracle");  // cstmt.registerOutParameter(2, Types.VARCHAR);  // cstmt.execute();  // String s = cstmt.getString(2);  // System.out.println(s);  // // rs = (ResultSet) cstmt.getObject(1);  // if (cstmt != null) {  // cstmt.close();  // }  // if (conn != null) {  // conn.close();  // }  // //  // // cstmt=conn.prepareCall("{call adddept(?,?)}");  // // cstmt.setInt(1,4);  // // cstmt.setString(2,"这是测试用的");  // // cstmt.executeUpdate();  // // if (cstmt != null) {  // // cstmt.close();  // // }  // // if (conn != null) {  // // conn.close();  // // }  // System.out.println("success");  // } catch (Exception e) {  // e.printStackTrace();  // } }}

    Oracle端的存储过程:

    create or replace procedure f_content_pro (keyword in varchar,pagenum in number,newsnum in number,v_cfjg out f_content_arr_re,totalnum out number) isv_restab ctx_doc.highlight_tab;beginDECLAREi number;s clob;startnum number;endnum number;--分页每页显示的条数,现在先定义为10条v_res_fun T_DOCNEWS%rowTYPE;cursor c_fun isselect *  from T_DOCNEWS where contains(F_CONTENT,keyword)>0 order by F_POSTEDTIME desc;BEGINselect count(*) into totalnum from T_DOCNEWS where contains(F_CONTENT,keyword)>0;i := 0;v_cfjg := f_content_arr_re();open c_fun;LOOPfetch c_funinto v_res_fun;EXIT WHEN c_fun%NOTFOUND or i>=(pagenum*newsnum);i := i + 1;if i>=((pagenum-1)*newsnum+1) thens := v_res_fun.F_CONTENT;v_cfjg.EXTEND;ctx_doc.highlight('f_content_index', v_res_fun.F_ID, keyword, v_restab, false);--只取第一个,没有loop循环startnum:=v_restab(1).offset;if v_restab(1).offset > 30 then   begin        startnum := v_restab(1).offset-30 ;   end;end if;if v_restab(1).offset <= 30 then   begin        startnum := 1 ;   end;end if;if length(s)-v_restab(1).offset > 30 then   begin        endnum := v_restab(1).offset+30 ;   end;end if;if length(s)-v_restab(1).offset <= 30 then   begin        endnum := length(s) ;   end;end if;v_cfjg(v_cfjg.count) := f_content_arr(v_res_fun.F_ID,v_res_fun.F_URL,v_res_fun.F_TITLE,substr(s,startnum,endnum-startnum));end if;END LOOP;end;EXCEPTIONWHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('TOO_MANY_ROWS');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE(sqlerrm);end f_content_pro;


    最新回复(0)