`
wlh269
  • 浏览: 447533 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

drp手记

阅读更多
----------------v1.0---------------
1、用户添加
2、用户查询
3、用户修改
4、用户删除
5、用户登录
6、filter解决字符集问题
7、Ajax应用
----------------v1.1---------------
1、分销商树的读取:client_tree.jsp
	
	<%=ClientManager.getInstance().getClientTreeString()%>

2.分步骤的写出树形结构:
第一步:1. 用加号“+”表示非叶子节点,用减号“-”表示叶子节点 
/**  
     * 递归读取分销商树  
     *   
     * 1. 用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
     * @param conn  
     * @param id   
     * @param level 控制层次的  
     */  
 private void read(Connection conn, int id, int level) {   
        level++;   
      String sql="select * from t_client where pid=?";   
        PreparedStatement pstmt=null;   
        ResultSet rs=null;   
      try {   
        pstmt=conn.prepareStatement(sql);   
        pstmt.setInt(1,id );   
        rs=pstmt.executeQuery();   
        while(rs.next()){   
            for(int i=0;i<level-1;i++){   
                sbTree.append("&nbsp;&nbsp;&nbsp;");   
            }   
            if("N".equals(rs.getString("is_leaf"))){   
                sbTree.append("+"+rs.getString("name"))   
                      .append("<br>");   
            read(conn,rs.getInt("id"),level);   
            }else{   
                sbTree.append("-"+rs.getString("name"))   
                       .append("<br>");   
            }   
        }   
           
    } catch (SQLException e) {   
        e.printStackTrace();   
    }finally{   
        DB.close(rs);   
        DB.close(conn);   
    }   
    }   
       
}  


第二步:加上<div>嵌套,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
/**  
 * 递归读取分销商树  
 *   
 * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
 * 2.加上<div>嵌套,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
 * @param conn  
 * @param id   
 * @param level 控制层次的  
 * @throws SQLException   
 */  
private void read(Connection conn, int id, int level) throws SQLException {   
    level++;   
  String sql="select * from t_client where pid=?";   
    PreparedStatement pstmt=null;   
    ResultSet rs=null;   
  try {   
    pstmt=conn.prepareStatement(sql);   
    pstmt.setInt(1,id );   
    rs=pstmt.executeQuery();   
    while(rs.next()){   
        sbTree.append("<div>");   
        for(int i=0;i<level-1;i++){   
            sbTree.append("<img src=\"../images/white.gif\" />");   
        }   
        if("N".equals(rs.getString("is_leaf"))){   
            sbTree.append("<img src=\"../images/plus.gif\"/>")   
                   .append("<img src=\" ../images/closedfold.gif\"/>")   
                   .append(rs.getString("name"));   
             //递归       
             sbTree.append("<div>");   
                read(conn,rs.getInt("id"),level);   
             sbTree.append("</div>");   
  
        }else{   
            sbTree.append("<img src=\"../images/minus.gif\"/>")   
                  .append("<img src=\" ../images/openfold.gif\"/>")   
                  .append(rs.getString("name"));   
        }   
        sbTree.append("</div>");   
    }   
       
} finally{   
    DB.close(rs);   
    DB.close(pstmt);   
}   
}   
  
第三步:在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;


/**  
     * 递归读取分销商树  
     *   
     * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
     * 2.加上<div>,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
     * 3.在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;  
     *   
     * @param conn  
     * @param id   
     * @param level 控制层次的  
     * @throws SQLException   
     */  
    private void read(Connection conn, int id, int level) throws SQLException {   
        level++;   
      String sql="select * from t_client where pid=?";   
        PreparedStatement pstmt=null;   
        ResultSet rs=null;   
      try {   
        pstmt=conn.prepareStatement(sql);   
        pstmt.setInt(1,id );   
        rs=pstmt.executeQuery();   
        while(rs.next()){   
            sbTree.append("<div >");   
            for(int i=0;i<level-1;i++){   
                sbTree.append("<img src=\"../images/white.gif\" />");   
            }   
            if("N".equals(rs.getString("is_leaf"))){   
                sbTree.append("<img id=\"img"+rs.getInt("id")+"\" src=\"../images/plus.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                       .append("<img id=\"im"+rs.getInt("id")+"\" src=\" ../images/closedfold.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                       .append(rs.getString("name"));   
                 //递归       
                 sbTree.append("<div style=\"display:none;\" id=\"div"+rs.getInt("id")+"\">");   
                    read(conn,rs.getInt("id"),level);   
                 sbTree.append("</div>");   
  
            }else{   
                sbTree.append("<img src=\"../images/minus.gif\"/>")   
                      .append("<img src=\" ../images/openfold.gif\"/>")   
                      .append(rs.getString("name"));   
            }   
            sbTree.append("</div>");   
        }   
           
    } finally{   
        DB.close(rs);   
        DB.close(pstmt);   
    }   
    }   
      

/第四步:在文字上添加链接,使得在某个地方显示对应的内容  
    Java代码 
  /**  
 
 
 * 递归读取分销商树  
 *   
 * 1.用加号“+”表示非叶子节点,用减号“-”表示叶子节点  
 * 2.加上<div>,将加号“+”,减号“-”改为图片,然后在其后面加上打开或者关闭的文件夹图片,  
 * 3.在图片"+"和"-"上添加鼠标事件,使树能实现收缩和关闭同时图片也做改变;在图片"打开的文件夹"和"关闭的文件夹"上添加鼠标事件;  
 * 4.在文字上添加链接,使得在某个地方显示对应的内容  
 *   
 * @param conn  
 * @param id   
 * @param level 控制层次的  
 * @throws SQLException   
 */  
private void read(Connection conn, int id, int level) throws SQLException {   
    level++;   
  String sql="select * from t_client where pid=?";   
    PreparedStatement pstmt=null;   
    ResultSet rs=null;   
  try {   
    pstmt=conn.prepareStatement(sql);   
    pstmt.setInt(1,id );   
    rs=pstmt.executeQuery();   
    while(rs.next()){   
        sbTree.append("<div >");   
        for(int i=0;i<level-1;i++){   
            sbTree.append("<img src=\"../images/white.gif\" />");   
        }   
        if("N".equals(rs.getString("is_leaf"))){   
            sbTree.append("<img id=\"img"+rs.getInt("id")+"\" src=\"../images/plus.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                   .append("<img id=\"im"+rs.getInt("id")+"\" src=\" ../images/closedfold.gif\" onClick=\"display("+rs.getInt("id")+");\" />")    
                   .append("<a href=\"client_node_crud.html?id="+rs.getInt("id")+"\" target=\"clientDispAreaFrame\">"+rs.getString("name")+"</a>");   
               
             //递归       
             sbTree.append("<div style=\"display:none;\" id=\"div"+rs.getInt("id")+"\">");   
                read(conn,rs.getInt("id"),level);   
             sbTree.append("</div>");   
  
        }else{   
            sbTree.append("<img src=\"../images/minus.gif\"/>")   
                  .append("<img src=\" ../images/openfold.gif\"/>");   
            //叶子节点分2类:一类是分销商,一类是区域   
            if ("Y".equals(rs.getString("is_client"))) {   
                sbTree.append("<a href=\"client_crud.html?id=" + rs.getInt("id") + "\" target=\"clientDispAreaFrame\">" + rs.getString("name") + "</a>");   
            }else {   
                sbTree.append("<a href=\"client_node_crud.html?id=" + rs.getInt("id") +  "\" target=\"clientDispAreaFrame\">" + rs.getString("name") + "</a>");   
            }      
        }   
        sbTree.append("</div>");   
    }   
       
} finally{   
    DB.close(rs);   
    DB.close(pstmt);   
}   
}   




----------------v1.2---------------
1、树节点的查询
----------------v1.3---------------
添加分销商
添加区域
修改区域
删除区域(递归删除)
修改分销商
查看分销商
删除分销商(递归删除)



----遇到unable to load class xxx的错误时候,是jsp编译成的class文件不存在
   解决方法:重新启动web服务
----接收的字符串参数如果是为null,则无法进行格式转换:
例:--错 误: 
        int id = Integer.parseInt(request.getParameter("id"));//如果接收到的字符串为空字符串,则无法进行格式转换
    --正确修改:
	    int id = 0;
		if (request.getParameter("id") != null) { //非空判断
			id = Integer.parseInt(request.getParameter("id")); //进行格式转换
		}
----接收的字符串参数如果是为null,则无法进行equals判断:
例:client_modify.jsp	
    --错误: 
     
    List clientLevelList = DataDictManager.getInstance().getClientLevelList();
	for (Iterator iter = clientLevelList.iterator(); iter.hasNext();) {
		ClientLevel cl = (ClientLevel)iter.next();
		String selectStr = "";
		
		//cl是从数据字典查上来的分销商等级,不为空,但是client.getClientLevel().getId()可能为空,所以应该进行非空判断
		if ( cl.getId().equals(client.getClientLevel().getId())) {
			selectStr = "selected";
	     }
	 }
	--正确:
	      //非空判断client.getClientLevel().getId()!=null 

	   	if (client.getClientLevel().getId()!=null && cl.getId().equals(client.getClientLevel().getId())) {
			selectStr = "selected";
	     }	
----刷新框架:在删除分销商和区域之后刷新左边树形展示的框架,
    即在右边子框架clientDispAreaFrame所包含的页面中写代码,实现刷新左边clientTreeFrame所包含的页面client_tree.jsp
    <frameset rows="*" cols="267,*" framespacing="0" frameborder="yes" border="1">
		<frame src="client_tree.jsp" name="clientTreeFrame"scrolling="scroll" id="clientTreeFrame" />
		<frame src="client_display_area.html" name="clientDispAreaFrame" id="clientDispAreaFrame" />
	</frameset>	   							
  例如:删除区域页面client_node_crud.jsp,调用删除代码删除节点成功之后调用刷新代码刷新左边的树;
      备注:其实刷新的目的,就是重新查询数据库,重新展示这棵树,因为刚才做了删除节点操作
  <%
      	if (command != null && "delete".equals(command)) {
		ClientManager.getInstance().deleteTreeNodeById(id);//删除节点代码
		
		//输出刷新树的js
		out.print ("<script>");
        out.print("parent.clientTreeFrame.location.href='client_tree.jsp'");//刷新
        out.print("</script>");
		out.print("删除成功!");
	}
%>
   

----定时刷新某个页面,例如每一分钟刷新一个页面:
   setTimeout("self.location.reload();",1000);//将代码放到<script type="text/javascript">...</script>块内即可。

----刷新本页:
  out.print("<script>window.location.href=window.location.href;</script>")

----刷新父页:
out.print("<script>opener.location.href=opener.location.href;</script>")

----转到指定页:
out.print("<script>window.location.href='yourpage.jsp';</script>")



1. 添加分销商:
	   client_add.jsp 
	   DataDictManager.java (查分销商等级列表)
	   ClientIdValidateServlet.java(Ajax验证涉及的servlet)
2、添加区域:client_node_add.jsp
3、修改区域:client_node_modify.jsp
4. 删除区域:client_node_crud.jsp?command=delete&id=<%=id%>	
    删除区域节点时,得同时删除下面的分销商和区域等子节点;
    ==具体步骤:
	   a>.如果是mySQL,则需要将事务的自动提交设置为false ,conn.setAutoCommit(false);
	   b>.通过当前节点的id得到当前节点对象client,先递归删除子节点,然后删除该节点;
	   c>.提交设置为false,所以在执行删除节点的sql之后,没有真正删除节点,
	      --通过client.getPid(),然后得到父节点对象,检查该父亲是否还有孩子(也就是该节是否有兄弟节点);
	      --如果没有孩子节点,则将父节点的属性is_leaf设置为true;
	      --如果有孩子节点,则将父节点的属性is_leaf不变,还是false;
	   d>.事务提交:conn.commit();
	   
	   
	 /**
	 * 递归删除树节点
	 * @param conn
	 * @param id
	 * @throws SQLException
	 */
	private void recursionDeleteTreeNodeById(Connection conn, int id) 
	throws SQLException {
		String sql = "select * from t_client where pid=?";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, id);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				if ("N".equals(rs.getString("is_leaf"))) {
					recursionDeleteTreeNodeById(conn, rs.getInt("id"));
				}
				//删除子节点
				deleteTreeNodeById(conn, rs.getInt("id"));
			}
			//删除自身
			deleteTreeNodeById(conn, id);
		}finally {
			DB.close(rs);
			DB.close(pstmt);
		}
	}



1.修改分销商:client_modify.jsp
2.查看分销商:client_detail.jsp
3.删除分销商:client_crud.jsp?command=delete&id=<%=id%>

 ========drp1.4 递归删除子节点================

 删除区域节点时,得同时删除下面的分销商和区域等子节点;
    ==具体步骤:
	   a>.如果是mySQL,则需要将事务的自动提交设置为false ,conn.setAutoCommit(false);
	   b>.通过当前节点的id得到当前节点对象client,先递归删除子节点,然后删除该节点;
	   c>.提交设置为false,所以在执行删除节点的sql之后,没有真正删除节点,
	      --通过client.getPid(),然后得到父节点对象,检查该父亲是否还有孩子(也就是该节是否有兄弟节点);
	      --如果没有孩子节点,则将父节点的属性is_leaf设置为true;
	      --如果有孩子节点,则将父节点的属性is_leaf不变,还是false;
	   d>.事务提交:conn.commit();
	   
	   
	 /**
	 * 递归删除树节点
	 * @param conn
	 * @param id
	 * @throws SQLException
	 */
	private void recursionDeleteTreeNodeById(Connection conn, int id) 
	throws SQLException {
		String sql = "select * from t_client where pid=?";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, id);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				if ("N".equals(rs.getString("is_leaf"))) {
					recursionDeleteTreeNodeById(conn, rs.getInt("id"));
				}
				//删除子节点
				deleteTreeNodeById(conn, rs.getInt("id"));
			}
			//删除自身
			deleteTreeNodeById(conn, id);
		}finally {
			DB.close(rs);
			DB.close(pstmt);
		}
	}

----------------v1.5---------------

1、修改密码
	 a>.输入旧密码,当鼠标离开之后onblur,通过ajax验证输入的旧密码是否正确(其中需要从session中取出当前用户,得到当前用户的密码)
	 b>.提交输入的新密码
	 c>.调用业务逻辑方法对当前用户进行密码修改;
	 d>.移除session中user,
	 f>.修改User对象,然后再放入session中;
 
2、会计核算期间维护


  ----------------v1.6添加物料-------------
 1.添加代码
 2.添加物料后返回到初始化页面:out.println("<script type=\"text/javascript\">history.go(-2)</script>");


物料维护
步骤:
a.添加dao层:添加com.bjsxt.drp.database.dao 给出dao层接口,然后给出MySQL和Oracle的具体的实现;
b.添加工厂类:com.bjsxt.drp.database.factory.ItemDao4MySqlFactory 
			和com.bjsxt.drp.database.factory.ItemDao4OracleFactory
			分别生产ItemDao4MySqlImpl和ItemDao4OracleImpl
			
c.添加分页类:PageModel
   页面大小,pageSize
   当前页号,pageNo
   总页数,  getTotalPages()
   下一页, getNextPageNo()
   上一页, getNextPageNo()
   首  页, getTopPageNo()
   末  页, getBottomPageNo()
d.添加ItemManager.java物料管理
e.添加DataDictManager.java , ItemCategory.java
f.添加AppException.java

----------------v1.7---------------
1、根据id查询物料
 当查询框clientIdOrName内输入物料编号或者物料名称后,表单自身提交给自身,
  同时接收查询字符串queryStr,再次查询数据库得到相应的PageModel,然后展示页面即可!

--------v1.8-物料分页查询--------

a.添加分页类:PageModel

   页面大小,pageSize
   当前页号,pageNo
   总页数,  getTotalPages()
   下一页, getNextPageNo()
   上一页, getNextPageNo()
   首  页, getTopPageNo()
   末  页, getBottomPageNo()
b.ItemManager.java物料管理类
 --根据条件分页查询:
      PageModel pageModel = ItemManager.getInstance().findAllItem(pageNo, pageSize, queryStr);
       其中,页面编号pageNo,查询字符串queryStr是变化的,pageSize是可以不变的
      
  --重点查询语句:select a.item_no, a.item_name, a.spec, a.pattern, a.category as category_id, 
                (select b.name from t_data_dict b where a.category=b.id) as category_name,
                a.unit as unit_id, (select c.name from t_data_dict c where a.unit=c.id) as unit_name
          from t_items a 
          order by a.item_no
          limit 0,3
  
  
----------------v1.9---------------
1、采用动态代理为Dao层加入日志
 ItemDao4MySqlFactory.java 
 LogHandler.java
 
 
 ----------------v2.0文件上传---------------
1、通过<init-param>配置保存上传文件的目录,该目录也是加载图片的目录
   <servlet>
		<servlet-name>FileUpload</servlet-name>
		<servlet-class>com.bjsxt.drp.util.servlet.FileUpload</servlet-class>
		<init-param>
			<param-name>upload_path</param-name>
			<param-value>C:\\workspace\\drp2.7\\WebRoot\\images\\item\</param-value>
		</init-param>
	</servlet>  	
	
	<servlet-mapping>
		<servlet-name>FileUpload</servlet-name>
		<url-pattern>/servlet/FileUpload</url-pattern>
	</servlet-mapping>
	
2.上传代码,参考: FileUpLoad.java

----------------v2.1---------------
1、物料修改
 重点1:选中一条记录之后进行修改,如何用js判断选中了一条记录
   function modifyItem() {
	 var count=0;
	 var j=0;
	 for(var i=0;i<document.getElementsByName("selectFlag").length;i++){
		  if(document.getElementsByName("selectFlag")[i].checked){
		     j=i;  //最后一个被选中复选框的下标
		   count++; //选中的个数
		  }
	  
	 }
	 if(count==0){
	  alert("请选择需要修改的物料!");
	 return ;
	 }
	 
	 if(count>1){
	  alert("一次只能修改一个物料!");
	  return ;
	 }
	 window.self.location = "item_modify.jsp?itemNo=" + document.getElementsByName("selectFlag")[j].value;
	}
重点2:
  如果有下拉列表,则要有一个默认选中状态;
   <td>
	<select name="unit" class="select1" id="unit">
		<% 
		for(Iterator unitIter= itemUnitList.iterator();unitIter.hasNext();  ){
		   ItemUnit iu= (ItemUnit)unitIter.next();
		   String selected="";
		   if(iu.getId().equals(item.getUnit().getId() )){
		     selected="selected";
		   }
		%>
			<option value="盒" value="<%=iu.getId() %>" <%=selected%>><!--默认选中-->
				<%=iu.getName() %>
			</option>
		<%} %>	
	</select>
</td>

2、物料删除

	function deleteItem() {
	    var count=0;
		for(var i=0;i<document.getElementsByName("selectFlag").length;i++){
		  if(document.getElementsByName("selectFlag")[i].checked){
		   count++;
		  }
		 }
		  if(count<=0){
		   alert("请选择需要删除的物料!");
		   return;
		  }
		  if(window.confirm("确认删除吗?")){
		    with(document.getElementById("itemForm")){
		     action="item_maint.jsp?command=delete&clientIdOrName=<%=queryStr%>"
		     method="post";
		     submit();
		    
		    }
		  
		  
		  }
	  
	 }
	
	


3、物料详细信息
重点:查询SQL
 select a.item_no, a.item_name, a.spec, a.pattern, a.category as category_id,
      (select b.name from t_data_dict b where a.category=b.id) as category_name,
			a.unit as unit_id, 
			(select c.name from t_data_dict c where a.unit=c.id) as unit_name 
 from t_items a 
 where a.item_no=?



----------------v2.2---------------
1、流向单添加
2、重点:采用JDK动态代理为FlowCardManager接口添加事务管理,
         参考:FlowCardManagerFactory.java,TransactionHandler.java
3、流向单查询
4、流向单删除
5、流向单送审
6、流向单明细查询

---------------------------------------------------------------------------------------------------------
      采用 ThreadLocal封装Connection(解决线程安全)参见:ConnectionManager.java :
     DrpUtil.java 
     ErrorInfo.java
     TransactionHandler.java
1、流向单添加
  
   a.ClientManager.java添加查找所有分销商,返回分页模型PageModel:
       --public PageModel findAllClient(int pageNo, int pageSize, String queryStr);
       
   b.用js添加一行表格:flow_card_add.jsp
    function addOneLineOnClick() {
		var row=tblFlowCardDetail.insertRow(tblFlowCardDetail.rows.length);
		var col = row.insertCell(0);
		col.innerHTML = "<input readonly=\"true\" maxLength=6 size=6 name=aimId><input type=button  value =...   name=btnSelectAimClient index=\""+ rowIndex +"\" onclick=\"selectAimClient(this.index)\">";
		col = row.insertCell(1);
		col.innerHTML = "<tr><input id=aimName name=aimName size=25 maxlength=25 readonly=\"true\">";
		col = row.insertCell(2);
		col.innerHTML = "<input readonly=\"true\" maxLength=6 size=6 name=itemNo><input type=button  value =...   name=btnSelectItem index=\""+ rowIndex +"\" onclick=\"selectItem(this.index)\">";
		col = row.insertCell(3);
		col.innerHTML = "<input id=itemName name=itemName size=25 maxlength=25 readonly=\"true\">";		
		col = row.insertCell(4);
		col.innerHTML = "<input id=spec name=spec size=10 maxlength=10 readonly=\"true\">";
		col = row.insertCell(5);
		col.innerHTML = "<input id=pattern name=pattern size=10 maxlength=10 readonly=\"true\">";
		col = row.insertCell(6);
		col.innerHTML = "<input id=unit name=unit size=4 maxlength=4 readonly=\"true\">";
		col = row.insertCell(7);
		col.innerHTML = "<input id=qty name=qty size=6 maxlength=6>";
		col = row.insertCell(8);
		col.innerHTML = "<input type='button' value='删除' id=btnDeleteLine name=btnDeleteLine onclick=\"return DeleteRow('row" + rowIndex + "')\"></tr>";
		row.setAttribute("id", "row" + rowIndex);
		//row.setAttribute("name", "row" + rowIndex);
		rowIndex++;
	}
	--------------------------------------------------------------------------------
	//选择需方客户窗口:aim_client_select.jsp
	
	  function selectAimClient(index) {
		window.open('aim_client_select.jsp?index=' + index, '请选择需方客户', 'width=700, height=400, scrollbars=no');
    }   
    
   //在子窗口aim_client_select.jsp中选择需方客户后将其添加到父窗口flow_card_add.jsp中
    function doubleclick(aimId, aimName) {
		var rowLength = window.opener.document.all.tblFlowCardDetail.rows.length
		if (rowLength == 2) {
			window.opener.document.all.aimId.value = aimId;
			window.opener.document.all.aimName.value = aimName;
		} else {
			window.opener.document.all.aimId[<%=index%>].value = aimId;
			window.opener.document.all.aimName[<%=index%>].value = aimName;
		}
		window.close();
	}

   -----------------------------------------------------------
     //选择物料窗口
    function selectItem(index) {
		window.open('item_select.jsp?index=' + index, '请选择物料', 'width=700, height=400, scrollbars=no');
    } 
  
   //在子窗口item_select.jsp中选择一个物料之后将其添加到父窗口flow_card_add.jsp中
    function doubleclick(itemNo, itemName, spec, pattern, unit) {
		var rowLength = window.opener.document.all.tblFlowCardDetail.rows.length;
		if (rowLength == 2) {
			window.opener.document.all.itemNo.value = itemNo;
			window.opener.document.all.itemName.value = itemName;
			window.opener.document.all.spec.value = spec;
			window.opener.document.all.pattern.value = pattern;
			window.opener.document.all.unit.value = unit;
		}else {
			window.opener.document.all.itemNo[<%=index%>].value = itemNo;
			window.opener.document.all.itemName[<%=index%>].value = itemName;
			window.opener.document.all.spec[<%=index%>].value = spec;
			window.opener.document.all.pattern[<%=index%>].value = pattern;
			window.opener.document.all.unit[<%=index%>].value = unit;
		}
		window.close();
	}
    
   
   
2、DRP采用JDK动态代理为FlowCardManager接口添加事务管理 
   一个业务逻辑类ManagerImpl的方法A中可能要包含DAO层类DaoImpl中多个的方法B,C,...的调用;
   在业务逻辑类ManagerImpl上通过JDK动态代理添加事务,动态代理的职能如下:
    a. 假如在指定的add*,delete*,modify*,方法执行前打开连接;
    b. 将事务的自动提交设置为false;
    c. 业务逻辑方法执行(其中多次调用DAO层的方法B,C,....,)
    			多次调用DAO层的方法B,C,....,其中得注意2点:
    			 1.我们使用的ConnectionManager.getConnection();得到的是一个放入ThreadLocal的连接,也就是同一线程共同使用的一个连接,
    			   因为在A方法中调用方法B,C...所以B,C得到的数据库连接都是同一个连接
    			 2.Dao方法B,C...的执行只是执行SQL语句,并没有提交事务,也没有关闭连接...以及失败的回滚等,这些操作都由A方法执行完毕后,由动态代理来做;
    e. 出错的情况下,让事务回滚;
    f. 最后关闭连接;
    如果想理解上面的这些话,请这么做:
    1.在ConnectionManager.java 的方法public static Connection getConnection() 中的下面一句上设断点
         Connection conn = (Connection)connectionHolder.get();
    2.启动web服务;
    3.点击分销商库存管理中的流向单维护,会执行业务逻辑方法findAllFlowCard,
         其中包括2个DAO层方法的调用findAllFlowCard和addFlowCardDetail
    4.F6--可一观察到动态代理和业务逻辑方法和dao层方法的执行流程,以及ThreadLocal的Connection的创建次数(就一次)
    
     事务加入请参见:FlowCardManagerFactory.java
	     /**
		 * 创建FlowCardManager,动态加入事务
		 * @return
		 */
      public FlowCardManager createFlowCardManager() {
		FlowCardManager flowCardManager = new FlowCardManagerImpl(this.flowCardDao);
		TransactionHandler transactionHandler = new TransactionHandler();//动态加入事务
		return (FlowCardManager)transactionHandler.newProxyObject(flowCardManager);
	}
	
	
	
	
3、流向单查询
   a.双击子窗口窗口的某一行记录;将子窗口中某条记录的值传递到父窗口;然后关闭子窗口;父窗口显示刚才选择的信息;
    //双击单选钮
	function doubleclick(clientId, clientName) {
		window.opener.document.getElementById("clientId").value = clientId;	//给父窗口的元素赋值
		window.opener.document.getElementById("clientName").value = clientName;	//给父窗口的元素赋值
		window.close(); //关闭当前窗口
	}
   
4、流向单删除
5、流向单送审
6、流向单明细查询


----------------v2.4---------------
1、Jfreechart的使用
2、采用Ajax实现html下拉列表联动

----------------v2.5---------------
1、验证码的生成
----------------v2.6---------------
1、采用filter解决session为空

----------------v2.7---------------
1、<context-param>  测试test_context_param.jsp
2、taglib           测试test_tag.jsp
3、Listener
4、tomcat连接池配置   DB.java

5.web.xml配置错误处理:
  
 类型一:自定义异常处理
   <error-page>
   	<exception-type>com.bjsxt.drp.exceptions.AppException</exception-type>
   	<location>/error.jsp</location>
   </error-page>
    1.定义异常类AppException.java,通过super(msg);将异常信息传到父类RuntimeException中,
    public class AppException extends RuntimeException {
	
	private int errorCode;
	
	public AppException(String msg) {
		super(msg);
	}
	public AppException(int errorCode) {
		this.errorCode = errorCode;
	}
	public int getErrorCode() {
		return errorCode;
	}
	
}  
   2.在使用的地方向上抛出异常
     例如:
      try {
			..............
		} catch (SQLException e) {
			throw new AppException("删除物料失败");
		} finally {
			...............
		}
   3.根据web.xml文件配置,抛出异常com.bjsxt.drp.exceptions.AppException后转向error.jsp页面 
   4.在错误处理页面error.jsp中通过以下代码得到错误信息
     <%=exception.getMessage()%>
	(注意:错误页面开头部分要注明是错误页面:<%@ page isErrorPage="true" %> )
	
类型二:错误码处理
1.	<!--如果错误码是404或者500则转向error.jsp页面 ,做相应处理 -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/http_error.jsp</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/http_error.jsp</location>
  </error-page>
  
  2.http_error.jsp
  
    <%
        //得到错误码request.getAttribute("javax.servlet.error.status_code")
		Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
		if (statusCode.intValue() == 404) {
			response.sendRedirect(request.getContextPath() + "/404.html");
		}else if (statusCode.intValue() == 500) {
			response.sendRedirect(request.getContextPath() + "/500.html");
		}		
	 %>
  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics