Java Web Project 技巧备忘录

1. 案例场景:

以下是一个n row × 2 col 的表,并且每一行可以独立作为一条link把parm pass去action或者jsp page。

     <logic:iterate id="row" name="fundTypeSearchResults">
      <html:link page="/fundTypeSearchResult.do?fundTypeCode=${row.fundTypeCode};fundTypeName=${row.fundTypeName}">
      <tr class ="tr1">
       <td align="left"><bean:write name="row" property="fundTypeCode"/></td>
       <td align="left"><bean:write name="row" property="fundTypeName"/></td>
      </tr>
      </html:link>
     </logic:iterate>

现在在禁止用button的情况下,想不用hard code的方法在url上把parm pass出去,而是通过actionForm把value pass到action,得到的效果跟以上相似。

Step 1

要把parm pass到actionForm必须通过submit,但是这个case因为要对所选取的其中一行(即一行中的2个parm fundTypeCode和fundTypeName)独立submit,其他行中的parm不需要pass,所以不能用submit button。

现在尝试通过JavaScript来对针对任何一行进行submit。

这段JavaScript的标准格式如下:
<a href="javascript:document.yourform.submit()"></a>

以上的 yourform 为你所 submit 的 form name,在struts 的 form 没有 name 这个attribute,但是其实际name就是actionForm的name。如本case,action name是fundTypeSearchResult,那么form name就是fundTypeSearchResultForm。

同时在测试时发现,a里面不能embed <tr>或<td>等,如<a href="XXX"><td><td/></a>是错误的。

所以现在运用的一个instance如下:

<td><a href="javascript:document.fundTypeSearchResultForm.submit()"><bean:write name="row" property="fundTypeCode"/></a></td>

可是也发现submit后不能得到相应选择的一行的parm,而只是get到第一行的parm,此问题到此未解决,待续。

2. <html:base />

就像struts的offical document那样说"This tag is useful"。

其实并不是一定好用,只不过是在需要用到相对路径却没有加上这个tag或者不使用相对路径却加上了这个tag,那就容易引致不能调用一些路径上的文件。

如以下的case:

  <link rel="stylesheet" type="text/css" href="../css/general.css" >
  <script type="text/javascript" language="javascript" src="../js/general.js" ></script>

如果没有加上<html:base />将没有办法使用到css和js。

3. Button Link

在struts中如果想利用button link到其他page,就需要在onclick上用到location.href。但是在struts中应该特别注意路径问题,因为可能你现在放置button link的page不是在root path而是在一个folder下,而且这个page是由action forward过来的,这时候path仍然是action的路径,即root path,就必须指定folder了。而且要注意在folder前不能有"/"号。

具体例子如下:

放置该段代码的是fundTypeEdit.jsp,fundTypeSearchResult这个action forward过来,而我们要通过button link到存在于fundInformation folder下的fundTypeSearch.jsp。

4. Case

现在在一个jsp page上有update和delete两个button,分别做update和delete两个operation,但是用同一个actionForm把parameter pass到同一个action,再有action作判断以决定做哪一个operation。问题是如何让action知道做什么operation呢?

在jsp page的update和delete button前可以定一个名叫method的hidden field,然后通过不同的button分别赋不同的值给method的value让actionForm去get。

所以在button onclick上可以利用EL来做赋值操作,例子如下:

      <html:hidden property="method"></html:hidden>
      <html:submit value="Update" οnclick="$('method').value = 'update'"></html:submit>
      <html:submit value="Delete" οnclick="$('method').value = 'delete'"></html:submit>

(注意:$('method')里的单引号不能少!)

该句表示将update/delete string赋值给在jsp page上名叫method的property。

Section - 5. 在Select下从Database获取options的Code

1. Abstract Template as following (red color represent you should amend it according to your need):

(1) JSP Page

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<jsp:useBean id="YourBean" class="fms.bean.YourBean"
 scope="session" />

<c:set var="attributes" value="${YourBean.yourBeanMethod}" />

//......

<html:select name="yourActionForm" property="attribute">
<html:option value="">--please select--</html:option>
<html:options collection="attributes" property="attribute" labelProperty="attribute"/>   
</html:select>

(2) JavaBean

 public Collection getYourBeanMethod()throws Exception
 {
  Statement stmt = conn.createStatement();
  ResultSet rst = stmt.executeQuery("select DBColumn from DBTable");
  Collection ret = new ArrayList();
  while(rst.next())
  {
   YourType temp = new YourType();
   temp.setAttribute(rst.getString("DBColumn "));
   ret.add(temp);
  }
  return ret;
 }

2. Application Example:

(1) fundHouseBean.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<jsp:useBean id="fundHouseBean" class="fms.bean.FundHouseBean"
 scope="session" />

<c:set var="countryRegionCodes" value="${fundHouseBean.countryRegionCodes}" />

//......

<html:select name="fundHouseAddForm" property="countryRegionCode">
<html:option value="">--please select--</html:option>
<html:options collection="countryRegionCodes" property="countryRegionCode" labelProperty="countryRegionCode"/>   
</html:select>

(2) FundHouseBean.java

 public Collection getCountryRegionCodes()throws Exception
 {
  Statement stmt = conn.createStatement();
  ResultSet rst = stmt.executeQuery("select CountryRegionCode from CountryRegion");
  Collection ret = new ArrayList();
  while(rst.next())
  {
   FundHouse temp = new FundHouse();
   temp.setCountryRegionCode(rst.getString("CountryRegionCode"));
   ret.add(temp);
  }
  return ret;
 }

Section 6 - 需要用到actionForm reset的一种情况

假设在fundHouseSearch.jsp上input,由fundHouseSearchForm填充和fundHouseSearchAction处理,但是当我们如果想把结果return到同一个page fundHouseSearch.jsp,因为struts会认为在同一个request,所以没有new一个actionForm,就会使得有部分在action中处理后不想显示在此Page的数据被get method填充到page上了。

所以必须在action中处理完数据后对actionForm reset,如本例这样写:
fundHouseSearchForm.reset(mapping, request);

 Section 7 - EL(表达语言)运用时获取request需要注意的区别

${param.fundTypeCode}

param在前的这种是用来获取url上的parameter的

${requestScope.fundTypeCode}

requestScope在前的这种事用来获取request中对象的

Section 8 - jsp page上切忌在不同控件使用相同名字而大小写不同的方式命名。

Section 9 - 用PrepareStatement进行DB操作的时候,?号需要与数据库的column数目对应,即使有些column你不需要进行操作。

Section 10 - 如用PrepareStatement进行data的insert,而再从database get回同一data时很容易会发现get不到值,这时通常的问题在于get值得时候要制定column name而当这个column name跟database上的不同,在insert时没有发现问题是因为用了index来指向database上的对应column,所以就算database上的column在design时写错也不会出现问题。要注意。

Section 11 - java.sql.Date 与 String之间的转换

由jsp page get回来的String date需要通过转换为java.sql.Date date才能与database交互,转换算法如下:

 public static java.sql.Date strToSQLDate(String strDate) {
  if(!DataValidater.isEmpty(strDate)){
   SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
   ParsePosition pos = new ParsePosition(0);
   java.util.Date utilDate = formatter.parse(strDate, pos);
   java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
   return sqlDate;
  }else{
   return null;
  }
 }

而在database get回来的java.sql.Date date可以简单地通过该class的toString method来进行转换,如下:

String date = rst.getDate("Date").toString()

 Section 12 - drop down list 的二级联动。

有两种思路:
1. 在onchange上利用JavaScript来submit到action做相应database retrieve operation,然后forward回到jsp page上display,优点是实现简单,缺点是每次点击drop down list中的不同选项都要读database,不但慢,而且增大了database的负载。
2. 在jsp page initialize的时候,用把所有相关数据从数据库中调到Array中,然后在jsp page中直接调用,优点是只读database一次,缺点是实现较繁琐(我还没有深入研究过),但如果一次读取的数量太多也会在initialization的时候出现过慢的情况。

所以我选择第1种思路来具体说明。

以下主要是对Fund House Name和Fund Name做二级联动,一个Fund House与Fund是N:1的关系,Fund Name是根据以上的Fund House Name来进行选择的。

<jsp:useBean id="fundHouseBean" class="fms.bean.FundHouseBean"
 scope="session" />
<jsp:useBean id="subFundBean" class="fms.bean.SubFundBean"
 scope="session" />
 
<c:set var="fundHouseENNames" value="${fundHouseBean.fundHouseENNames}" />
<c:set var="fundENNames" value="${subFundBean.fundENNames}" />

    <tr class = "tr1">
     <td align="left">Fund House Name:</td>
     <td align="left" colspan="2">
      <html:hidden property="method"/>
      <html:select property="fundHouseID" οnchange="dropDownListOnChange(trailerFeeAddForm,'onchange','method')" styleClass="select_general"  >
       <html:option value="">--please select--</html:option>
       <html:options collection="fundHouseENNames" property="fundHouseID" labelProperty="fundHouseENName"/>
      </html:select>
     </td>
    </tr>


    <logic:notPresent name="fundsOfFundHouse">
    <tr class = "tr1">
     <td align="left">Fund Name:</td>
     <td align="left" colspan="3">
      <html:select property="fundCode" styleClass="select_general"  >
       <html:option value="">--please select--</html:option>
       <html:options collection="fundENNames" property="fundCode" labelProperty="fundENName"/>
      </html:select>
     </td>
    </tr>
    </logic:notPresent>


    <logic:present name="fundsOfFundHouse">
    <tr class = "tr1">
     <td align="left">Fund Name:</td>
     <td align="left" colspan="3">
      <html:select property="fundCode" styleClass="select_general"  >
       <html:option value="">--please select--</html:option>
       <html:options collection="fundsOfFundHouse" property="fundCode" labelProperty="fundENName"/>
      </html:select>
     </td>
    </tr>
    </logic:present>

fundHouseENNames和fundENNames这些都是通过相应Bean的method对jsp page中的select option做initialization的,即从database中取出可以挑选的项,读者大可不必关注。而fundsOfFundHouse会在之后说。

<html:hidden property="method"/>是用来存储下submit所属的操作待send到action中进行相应判断的,因为一个page中可能有多个submit link或者button。

dropDownListOnChange(trailerFeeAddForm,'onchange','method')是一个JavaScript的custom function,具体Code有两个function组成,如下:
function setMethod(methodName,hiddenName)
{
 $(hiddenName).value = methodName ;
}

function dropDownListOnChange(form,methodName,hiddenName){
 setMethod(methodName,hiddenName);
 form.submit();
}

其作用就是把相应操作的名set到method这个property中,然后submit这个form。(使用的时候要特别注意哪些单引号的问题)

actionForm:

private String fundHouseID;

 public String getFundHouseID() {
  return fundHouseID;
 }

 public void setFundHouseID(String fundHouseID) {
  this.fundHouseID = fundHouseID;
 }

action:

Collection fundsOfFundHouse = subFundService.getFundsOfFundHouse(trailerFeeAddForm.getFundHouseID());

request.setAttribute("fundsOfFundHouse", fundsOfFundHouse);

带着从actionForm get回来的fundHouseID利用subFundService(它具体是什么不用关注)做相应的database retrieve operation,将与指定FundHouse旗下的Fund的FundCode和FundENName set到fundsOfFundHouse这个Collection中,然后forward回原来的jsp page,现在因为fundsOfFundHouse已经value了,所以以上的3大段jsp code中的第2 part被omit,由第3 part instead。最终在jsp page上Fund,可以select的就是根据指定FundHouse所retrieve出来的Fund。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值