当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks

#

 

 

 

 

 

 

TeamBiz中Ajax的基本运用

 

 

 

 

 

 

 

作者:何杨

撰写日期:2012年2月23日

版本:1.03

更新日期:2012年2月28日

 

 

第一部分:功能说明

提供前台页面到后台程序的异步请求响应通道。

第二部分:核心组件

名称

路径

说明

Prototype1.6.0.3

teambiz\WebRoot\page\js\prototype-1.6.0.3.js

Prototype是一个有历史的JS类库,TeamBiz中主要使用了它的Ajax部分及$函数。

注意,Teambiz并非对Prototype产生依赖,Prototype为Teambiz提供的仅是Ajax.Rquest对象及$函数而已,因为teambiz已经包含了普适版本的$函数,因此换用别的JS框架并不困难。

AjaxAction

teambiz\src\com\ibm\heyang\action\base\AjaxAction.java

AjaxAction是所有响应Ajax异步请求的Action的基类,它主要提供以下四项功能:

1.设置Response;

2.将url中的请求参数解码后放入RequestParamMap对象中;

3.强制子类实现函数process;

4.当子类的process函数中出现异常时,接受异常并包装成XML传给前台页面。

RequestParamMap

teambiz\src\com\ibm\heyang\action\base\RequestParamMap.java

RequestParamMap内部包含一个哈希表,以键值对的方式存储前台URL中的参数及其值。

RequestParamMap对象的生成在于AjaxAction的getRequestParamMap函数中。

它主要提供以下功能:

1.将参数集约化,此举能简化后台函数的编写。

2.当后台函数使用其内部不存在的参数时,它能自主抛出一个异常,通过AjaxAction的包装传给前台,使得编写函数的程序员能快速进行错误定位。

3.对前台编写的参数进行UTF-8解码,此举与前台对URL进行两次UTF8编码配合,统一解决了非ASC码字符传送产生乱码的问题。

Ajax.Request

定义于prototype-1.6.0.3.js中

Prototype中定义的Ajax请求对象,其参数有四个,URL,请求方法,成功函数和失败函数。相对于传统方式,它的可控性更高。

 

第三部分:前台和后台的约定

考虑到代码解读和人工解读的双重便利性,TeamBiz采用XML而不是JSON作为前后台数据的载体,此XML采用了一些约定以规范化编码。

Ajax异步调用过程中,后台需要两组数据来说明响应细节,一个是状态,如果它的值是OK的话,说明已经取得了请求想要的数据,此时向前台传出的XML会类似如下格式:

<response>

<status>ok</status>

<node>

<a>a</a>

<b>b</b>

</node>

</response>

如果它的值是NG的话,说明后台能响应,但由于某种原因(用户未登录,用户缺乏权限,参数缺失,后台组件尚未就绪,异常抛出等,前二者需要程序员编码,后两者框架已经代为实现),不能传回请求想要的数据,此时向前台传出的XML会类似如下格式:

 

<response>

<status>ng</status>

<text>请登录后再来执行此操作</text>

</response>

 

后台进行如上约定后,前台就可以采用如下统一的格式来处理XHR响应:

new Ajax.Request(url,{    

           method:'get',    

           onSuccess: function(ajaxObj){   

                        // alert(ajaxObj.responseText);   // 这里不要随意删去,有时需要打开屏蔽以观察后台传来的XML文本                   

                var status=ajaxObj.responseXML.getElementsByTagName("status")[0].firstChild.data;

                                                                                               

                                                if(status=="ok"){

                                                            ....// 状态为ok时的处理

                                                }

                                                else{

                                                            ....// 状态为ng时的处理

                                                }

           },    

           onFailure: function(){

                                                ....// 后台没有响应时的处理

           }  

        }

);

 

第四部分:使用步骤

步骤

说明

参照

在前台编写向后台发出请求的JS函数。

在此函数需要进行三件事:

1.编写URL。

2.对URL进行UTF8编码。

3.会使用一个Ajax.Request对象向后台发出请求。

teambiz\WebRoot\page\js\common.js中fetchMenuFromBg函数。

在后台编写响应前端请求的Action

Action需要继承自AjaxAction。在其process函数中主要进行以下三件事:

1.权限验证。

2.使用后端组件取得前端想要的数据。

3.以XML方式将数据传回。

teambiz\src\com\ibm\heyang\action\menu\FetchMenuAction.java

struts-config.xml注册Action

由于完全不需要静态或动态的form,此Action格式很简单,仅包含path,type和scope三部分。

teambiz\WebRoot\WEB-INF\struts-config.xml中的

<action path="/FetchMenu" type="com.ibm.heyang.action.menu.FetchMenuAction" scope="request" >

</action>

 

第五部分:小结

TeamBiz中全部向后台的请求都是通过Ajax异步方式实现的,相对于传统方式,它有以下优势:

1.由于只需要提取必要的资源,因此占用资源少。

2.有多种状态,多个函数用来处理后台的响应,这使得控制更加多样化。

3.由于前台在请求时处于静止状态,因此无需刻意保存前台页面数据。

4.由于不需要编写form,forward等元素,使得控制文件编写简单方便。

posted @ 2012-02-29 10:31 何杨 阅读(209) | 评论 (0)编辑 收藏

posted @ 2012-02-29 10:30 何杨 阅读(177) | 评论 (0)编辑 收藏

 

 

 

 

 

 

Teambiz整体介绍

 

 

 

 

 

 

 

作者:何杨

撰写日期:2012年2月27日

版本:1.00

更新日期:  

 

 

第一部分:TeamBiz说明

TeamBiz是一个处理团队成员之间事务的Web程序,用户可以使用它给自己或者别人规定任务,完成给自己的任务或是跟踪分给他人的事务。

TeamBiz差异化的一点在于基本使用Ajax方式进行前后台交互,后台查询数据库后传回的是XML,前台进行解析并使用DOM进行页面操作。系统在前后台提供了一系列类来协助程序员完成常见编码任务,相信这能减轻程序员的负担并提高代码的一致性。

TeamBiz是一个框架性说明程序,在此程序的基础上还可以完成扩充,如菜单改写成树样式,后台增加更多的领域对象和服务类等。

TeamBiz遗憾的一点在于没有解决当领域对象及其对应的表数据增加时系统复杂度的同时增加,也许再引入一个或多个中间层次能将熵维持在一个能控制的限度内,如果你知道怎么去做,请写信告诉我。(heyanghy@cn.ibm.com,heyang78@gmail.com)

第二部分:TeamBiz使用的框架

名称

说明

Stuts1.3.8

Teambiz使用了Struts的控制层功能和Tile及极少数标签。

Spring2.5

Teambiz使用了Spring的IoC和JDBCTemplate。

Hibernate3.0

Teambiz使用Hibernate进行单个领域对象的创建和更新。

Prototype1.6.0.3

Teambiz使用了Prototype的Ajax.Request,$,window.load三部分。

 

第二部分:TeamBiz其它相关事项

名称

说明

数据库

MySql5.2,如果需要更换数据库,请修改teambiz\cfg\appctx-datasource.xml中数据源配置并检查Dao类中诸Sql是否能在新数据库中正常运行。

开发环境

MyEclipse9,将程序包导入即可运行。

 

posted @ 2012-02-29 10:25 何杨 阅读(275) | 评论 (0)编辑 收藏

通常,我们可以如下所示制作横向菜单:
#commonUsedDocumentContainerDiv ul{
    margin
:0px;
    padding
:0px;
    list-style-type
:none;
    vertical-align
:middle  ;
}

#commonUsedDocumentContainerDiv li a
{
    width
:130px;  
    height
:75px;
    line-height
:32px;
    
    font-family
:"宋体","Tahoma"; 
    font-size
:14px;   
    font-weight
:bold;           
    color
:#000000;
    
    text-decoration
:none;
    text-align
:left;  
    
    background
:#ffffff;
}

#commonUsedDocumentContainerDiv li a:hover
{
    width
:130px;  
    height
:75px;
    line-height
:32px;
    
    font-family
:"宋体","Tahoma"; 
    font-size
:14px;   
    font-weight
:bold;           
    color
:#0000ff;
    
    text-decoration
:none;
    text-align
:left;  
    
    background
:#ffffff;
}

这样做,在FF或是ie8以上的版本中,都没有问题,但是ie6有问题,具体上看来本来应该是一横排的菜单变成了阶梯状,一下子就难看了。

这是因为ie6对ul/li的解释方式所致,要解决这个问题也很简单,对li的样式也进行设置就行了,如下的粗体部分:
#commonUsedDocumentContainerDiv ul{
    margin
:0px;
    padding
:0px;
    list-style-type
:none;
    vertical-align
:middle  ;
}

#commonUsedDocumentContainerDiv li
{
    float
:left;
    display
:block;
    
    width
:130px;  
    height
:75px;
    
    background
:#ffffff;
}


#commonUsedDocumentContainerDiv li a
{
    width
:130px;  
    height
:75px;
    line-height
:32px;
    
    font-family
:"宋体","Tahoma"; 
    font-size
:14px;   
    font-weight
:bold;           
    color
:#000000;
    
    text-decoration
:none;
    text-align
:left;  
    
    background
:#ffffff;
}

#commonUsedDocumentContainerDiv li a:hover
{
    width
:130px;  
    height
:75px;
    line-height
:32px;
    
    font-family
:"宋体","Tahoma"; 
    font-size
:14px;   
    font-weight
:bold;           
    color
:#0000ff;
    
    text-decoration
:none;
    text-align
:left;  
    
    background
:#ffffff;
}

另外需要注意的是,li a和li a:hover中照样可以设置display:block,如果li a 或者li a:hover 有背景还非得如此不可,这和网上流传甚广的方案不一样,看来知识不能拿来就用,还需要自己尝试一下。
posted @ 2012-02-14 15:31 何杨 阅读(363) | 评论 (0)编辑 收藏

先看代码:
#contentContainer{
    margin-top
:10px;
    padding
:0px;
    border
:0px solid #336699;
    
    width
:100%;
    
    overflow-x
:hidden;
}

当div的宽度基本和浏览器可控宽度一致时,滚动条就会出现,最麻烦的是会出现两个,一个div的,一个浏览器的。

这时,可以如上所示,将超出部分隐藏,这样滚动条就不会出现了。

IE上效果是滚动条彻底没有,但是FF只是把滚动条置灰,两者还是有区别的。
posted @ 2012-02-14 15:19 何杨 阅读(664) | 评论 (0)编辑 收藏

#detailInstructionContentDiv{
    margin
:0px;
    padding-top
:10px;
    padding-left
:22px;

    border
:0px solid #336699;
    
    width
:150px;
    height
:230px;
    
    text-align
: left;
    
    font-family
:"宋体","Tahoma"; 
    font-size
: 12px;    
    font-weight
:normal;
    color
:#333333;
    
    white-space
:normal;
}

见以上粗体部分,比wordbreak之类的好用得多。
posted @ 2012-02-14 15:13 何杨 阅读(653) | 评论 (0)编辑 收藏

页面代码,其中粗体部分是需要你根据实际情况进行修改的,其它保持原状:
<%@ 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>
<title>标题</title>
<BODY>
<center><OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" WIDTH="1440" HEIGHT="772" CODEBASE="http://active.macromedia.com/flash5/cabs/swflash.cab#version=7,0,0,0">
<PARAM NAME=movie VALUE="1_1.swf">
<PARAM NAME=play VALUE=true>
<PARAM NAME=loop VALUE=false>
<PARAM NAME=wmode VALUE=transparent>
<PARAM NAME=quality VALUE=low>
<EMBED SRC="1_1.swf" WIDTH=1440 HEIGHT=772 quality=low loop=false wmode=transparent TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED>
</OBJECT></center>
<SCRIPT src='swf.js'></script>
</BODY>
</HTML>

导入的swf.js代码如下:
obj=document.getElementsByTagName('object');
for (var i=0; i<obj.length; ++i)
  obj[i].outerHTML
=obj[i].outerHTML;
posted @ 2012-02-13 11:04 何杨 阅读(1013) | 评论 (2)编辑 收藏

如果以如下方式打开新窗口:
<href="javascript:openWindow('swf/1_1.jsp','',1440,772);" >示例</a>

那么,原窗口会变成一个含有[Object]字符的窗口。

换用下面方式即可,注意下面粗体部分的void(0),它表示没有返回值:
<href="javascript:openWindow('swf/1_1.jsp','',1440,772);void(0);" >示例</a>

下面的openCenterWindow函数仅供参考:
function openWindow(url,windowName,width,height){
    
var left = 0;     
    
var top = 0;       
      
    
var wnd=window.open(url,windowName,"height="+height+",width="+width+",top="+top+",left="+left+",resizable=yes,scrollbars=yes,status=no,location=no,");
    
return wnd;
}
posted @ 2012-02-13 10:59 何杨 阅读(1132) | 评论 (1)编辑 收藏

说明:
1.下载http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.7-20101029.zip后,将poi-3.7目录下的jar包放入lib目录, 再将此工程载入Eclipse/MyEclipse即可。
2.界面中文本框供输出数据量用,在我的T410上测试数据量在3.5W~3.6W之间,再多就报java.lang.OutOfMemoryError错误。附带提一下输出数据量的问题,如果修饰单元格的代码越简单,那么能输出的数据就越多,反之数据就少了。
3.主要代码如下:

Sevlet代码:
package com.heyang.action;


import java.io.BufferedOutputStream;

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

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.heyang.service.DownloadService;

/**
 * POI下载的Servlet
 * 
@author heyang
 *
 
*/
public class DownloadServlet extends HttpServlet {
    
private static final long serialVersionUID = 56890894234786L;
    
    
public void doPost(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, java.io.IOException {
        String fileName
="download.xls";
        response.setHeader(
"Content-disposition""attachment; filename="+fileName);// 设定输出文件头   
        response.setContentType("application/msexcel");// 定义输出类型 
        
        
try{
            
int rowCount=Integer.parseInt(request.getParameter("rowCount"));
            
            
// 表头行
            String[] headers=new String[]{"更新ID","账期","基站编号","基站名称","站点状态","部门名称","站点类型","占用类型","预提(元)","未核销金额","上期未核销","开始月份","结束月份","上期抄表数","本期抄表数","电价","电量","本期报账(元)","补提(元)","预提汇总(元)","成本中心","专业","本期报账单号","基站类别","线损"};
            DownloadService service
=new DownloadService();

            HSSFWorkbook workbook
=service.generateWorkbook(rowCount, headers.length);

            ServletOutputStream out 
= response.getOutputStream();
            BufferedOutputStream bos 
= new BufferedOutputStream(out);        
            workbook.write(bos);
            bos.flush();
            bos.close();
            
        }
catch(Exception ex){
            ex.printStackTrace();
        }
        
        
return ;
    }
        
    
public void doGet(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, java.io.IOException {
        doPost(request, response);
    }
}

Service代码:
package com.heyang.service;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


/**
 * 下载服务类
 * 
 * 
@author heyang
 *
 
*/
public class DownloadService{
    
/**
     * 生成工作簿对象
     * 
@param rowCount
     * 
@param columnCount
     * 
@return
     
*/
    
public HSSFWorkbook generateWorkbook(int rowCount,int columnCount) throws Exception{
        HSSFWorkbook workbook 
= new HSSFWorkbook(); //产生工作簿对象
        HSSFSheet sheet = workbook.createSheet(); //产生工作表对象
        String value=null;
        
        HSSFRow row 
= null;
        HSSFCell cell 
= null;
        
        
for(int i=0;i<rowCount;i++){
            row 
= sheet.createRow(i);//创建一行
            
            
for(int j=0;j<columnCount;j++){
                value
=""+i+","+j;
                
                cell 
= row.createCell(j);
                cell.setCellValue(value);
                
                cell 
= null;
            }
            
            row 
= null;
        }
        
        row 
= null;
        cell 
= null;
        
        
return workbook;
    }
}

4.工程下载地址:
posted @ 2012-02-01 15:48 何杨 阅读(750) | 评论 (0)编辑 收藏

1.Select控件在页面上的写法:
<select id="monthSelectCbo">
    
<option value="01">01</option>
    
<option value="02">02</option>
    
<option value="03">03</option>
    
<option value="04">04</option>
    
<option value="05">05</option>
</select>

2.设定select控件的当前项:
可以用:
$(
"monthSelectCbo").value=month;
也可以用:
$(
"monthSelectCbo").selectedIndex=1;

3.取得select控件的当前内容:
var month= $("monthSelectCbo").value; 

4.取得select空间选择项的序号:
var selIndex=$("monthSelectCbo").selectedIndex;

5.清除select控件的所有原有值:
var myListbox=$("belongToCompanyCbo");

for(var i=myListbox.options.length-1;i>=0;i--){
    myListbox.remove(i);
}

6.使用JavaScript给Select控件设定值:
var newOption=new Option;
newOption.value
="Beijing";
newOption.text
="北京";
monthSelectCbo.add(newOption);
posted @ 2012-01-12 11:31 何杨 阅读(265) | 评论 (0)编辑 收藏

仅列出标题
共28页: First 上一页 5 6 7 8 9 10 11 12 13 下一页 Last