一. 使用反射動態取出 Pojo 的屬性
這一招在一些特殊的場合下非常管用.比如說,用戶在第一個頁面,選擇了某個實體其中要顯示出來的幾個屬性,那個這個時候用反射是非常不錯的選擇,少了大量 if 語句:
Java代碼

- package com.leo.util;
-
- import java.lang.reflect.Method;
-
- public class HelloWorldBean {
-
- private String word;
-
- private String name;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getWord() {
- return word;
- }
-
- public void setWord(String word) {
- this.word = word;
- }
-
- public HelloWorldBean() {
- name = "superleo";
- word = "Hello World!!!";
- }
-
- public String getProperty(String name) throws Exception {
- if (name != null && !name.equals("")) {
- Character ch = name.charAt(0);
- name = Character.toUpperCase(ch) + name.substring(1, name.length());
- Class cls = Class.forName("com.leo.util.HelloWorldBean");
- Method meth = cls.getMethod("get" + name, null);
- Object retobj = meth.invoke(this, null);
- return (String) retobj;
-
- }
- throw new RuntimeException();
- }
-
- public static void main(String[] args) throws Exception {
- HelloWorldBean bean = new HelloWorldBean();
- bean.setName("superleo");
- bean.setWord("name");
- System.out.println(bean.getProperty("name"));
- System.out.println(bean.getProperty("word"));
- }
-
- }
package com.leo.util;
import java.lang.reflect.Method;
public class HelloWorldBean {
private String word;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public HelloWorldBean() {
name = "superleo";
word = "Hello World!!!";
}
public String getProperty(String name) throws Exception {
if (name != null && !name.equals("")) {
Character ch = name.charAt(0);
name = Character.toUpperCase(ch) + name.substring(1, name.length());
Class cls = Class.forName("com.leo.util.HelloWorldBean");
Method meth = cls.getMethod("get" + name, null);
Object retobj = meth.invoke(this, null);
return (String) retobj;
}
throw new RuntimeException();
}
public static void main(String[] args) throws Exception {
HelloWorldBean bean = new HelloWorldBean();
bean.setName("superleo");
bean.setWord("name");
System.out.println(bean.getProperty("name"));
System.out.println(bean.getProperty("word"));
}
}
OK ,假設我們在 HelloAction 使用了這個 HelloWorldBean ,并且運行后,跳轉到相應頁面,你可以這樣去取 HelloWorldBean 的 word 和 name 屬性了:
Html代碼

- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%@ taglib prefix="s" uri="/struts-tags"%>
- <html>
- <body>
- <h3>
- 正常方法:<s:property value="helloWorld.name" /> <br />
- <s:property value="helloWorld.word" /> <br />
- 反射方法:<s:property value="helloWorld.getProperty('name')" /> <br />
- <s:property value="helloWorld.getProperty('word')" />
- </h3>
- </body>
- </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
<h3>
正常方法:<s:property value="helloWorld.name" /> <br />
<s:property value="helloWorld.word" /> <br />
反射方法:<s:property value="helloWorld.getProperty('name')" /> <br />
<s:property value="helloWorld.getProperty('word')" />
</h3>
</body>
</html>
對于公共屬性,還可以將此方法移到父類。
用 iterator 迭代 Map 對象
這對顯示 Hibernate 多表連接的查詢結果非常管用。
以前,在使用 Hibernate 的時候,因為涉及到多個表查詢是很普遍的,每個表取一些字段,想顯示在頁面,比較好的辦法是新建一個 VO 對象,專門用來顯示查詢的結果.但缺點就是,如果這樣的查詢很多, VO 類會越來越多(如果不斷的往一個 VO 增加字段的話,那么這個 VO 也越來越大,構造函數會特別夸張),咱們來看一個例子:
Java代碼

- List list = session.createQuery("select new MyVO(a.name, b.name, c.id) from .....").list();
這樣返回的 List 直接就可以在頁面上用 iterator 標簽迭代了,但假如現在要取 10 呢?不僅 HQL 語句要修改,而且 MyVO 也要修改.下面是一種更好的做法:
Java代碼

- List list = session.createQuery("select new Map(a.name as fristName, b.name as secondName, c.id as id from .....").list();
這里改用 Map 了,注意每個屬性都用“ as ”重新啟了一個別名,這個非常重要,否則在頁面顯示時,很費勁.
現在來看頁面調用代碼:
Html代碼

- <s:iterator value="list" id="maps">
- <tr class="row1">
- <input type="checkbox" name="ids" value="<s:property value="#maps.get('id')" />" />
- <td align="center"><s:property value="#maps.get('fristName')" /></td>
- <td align="center"><s:property value="#maps.get('secondName')" /></td>
- </tr>
- </s:iterator>
<s:iterator value="list" id="maps">
<tr class="row1">
<input type="checkbox" name="ids" value="<s:property value="#maps.get('id')" />" />
<td align="center"><s:property value="#maps.get('fristName')" /></td>
<td align="center"><s:property value="#maps.get('secondName')" /></td>
</tr>
</s:iterator>
注意上面的頁面中 Map 的取值就是當時 hql 語句中“ as ”后的別名.
雖然相對于以往的 JSTL 來說,要寫的標簽代碼更多了,但強大的 OGNL 表達式也讓你在視圖層擁有更強大的靈活性與擴展性.
順序無關,如果你使用了 select new List(...) 也能達到類似效果,但因為 List 是有序的,所以在頁面顯示非常不靈活,不推薦使用.
用 if 標簽判斷漢字問題
這個問題具體原因不明,先看下面一段代碼:
Java代碼

- <s:if test="user.name == '程序'">
- ...
<s:if test="user.name == '程序'">
...
這樣就算 user.name 等于“程序”也是無法通過的,需要修改成以下代碼:
Html代碼

- <s:if test="user.name == "'程序"'">
- ...
<s:if test="user.name == "'程序"'">
...
如果“程序”是你系統的一個常量,更推薦的作法是:
Html代碼

- <s:if test="user.name == @com.leo.util.Constants@TYPE ">
- ...
<s:if test="user.name == @com.leo.util.Constants@TYPE ">
...
我不知道原因是不是因為版本問題?希望有知道的,回復一下.
用 iterator 雙重循環
這個也很常用,相信很多人都輕車熟路,那我們來回顧一下。假設 lists 裝的都是 Group 對象, Group 持有一個 List<User> 那個我們接下來可以:
Html代碼

- <ww:iterator value="lists" id="top">
- <ww:iterator value="users" id="sub">
- 組名:<s:property value="#top.name" />,成員名:<s:property value="#sub.name" />
- </ww:iterator>
- 應該組總數:<s:property value="users.size" />
- </ww:iterator>
<ww:iterator value="lists" id="top">
<ww:iterator value="users" id="sub">
組名:<s:property value="#top.name" />,成員名:<s:property value="#sub.name" />
</ww:iterator>
應該組總數:<s:property value="users.size" />
</ww:iterator>
上面的寫法有很多種,但效果都是一樣的,有興趣可以多看看 OGNL 。
還有一些沒有及時整理好,下次統一再給大家分享一下.