一. 使用反射動(dòng)態(tài)取出 Pojo 的屬性
這一招在一些特殊的場(chǎng)合下非常管用.比如說(shuō),用戶(hù)在第一個(gè)頁(yè)面,選擇了某個(gè)實(shí)體其中要顯示出來(lái)的幾個(gè)屬性,那個(gè)這個(gè)時(shí)候用反射是非常不錯的選擇,少了大量 if 語(yǔ)句:
- 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 使用了這個(gè) HelloWorldBean ,并且運行后,跳轉到相應頁(yè)面,你可以這樣去取 HelloWorldBean 的 word 和 name 屬性了:
- <%@ 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>
對于公共屬性,還可以將此方法移到父類(lèi)。
二. 用 iterator 迭代 Map 對象
這對顯示 Hibernate 多表連接的查詢(xún)結果非常管用。
以前,在使用 Hibernate 的時(shí)候,因為涉及到多個(gè)表查詢(xún)是很普遍的,每個(gè)表取一些字段,想顯示在頁(yè)面,比較好的辦法是新建一個(gè) VO 對象,專(zhuān)門(mén)用來(lái)顯示查詢(xún)的結果.但缺點(diǎn)就是,如果這樣的查詢(xún)很多, VO 類(lèi)會(huì )越來(lái)越多(如果不斷的往一個(gè) VO 增加字段的話(huà),那么這個(gè) VO 也越來(lái)越大,構造函數會(huì )特別夸張),咱們來(lái)看一個(gè)例子:
- List list = session.createQuery("select new MyVO(a.name, b.name, c.id) from .....").list();
List list = session.createQuery("select new MyVO(a.name, b.name, c.id) from .....").list();
這樣返回的 List 直接就可以在頁(yè)面上用 iterator 標簽迭代了,但假如現在要取 10 呢?不僅 HQL 語(yǔ)句要修改,而且 MyVO 也要修改.下面是一種更好的做法:
- List list = session.createQuery("select new Map(a.name as fristName, b.name as secondName, c.id as id from .....").list();
List list = session.createQuery("select new Map(a.name as fristName, b.name as secondName, c.id as id from .....").list();
這里改用 Map 了,注意每個(gè)屬性都用“ as ”重新啟了一個(gè)別名,這個(gè)非常重要,否則在頁(yè)面顯示時(shí),很費勁.
現在來(lái)看頁(yè)面調用代碼:
- <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>
注意上面的頁(yè)面中 Map 的取值就是當時(shí) hql 語(yǔ)句中“ as ”后的別名.
雖然相對于以往的 JSTL 來(lái)說(shuō),要寫(xiě)的標簽代碼更多了,但強大的 OGNL 表達式也讓你在視圖層擁有更強大的靈活性與擴展性.
順序無(wú)關(guān),如果你使用了 select new List(...) 也能達到類(lèi)似效果,但因為 List 是有序的,所以在頁(yè)面顯示非常不靈活,不推薦使用.
三. 用 if 標簽判斷漢字問(wèn)題
這個(gè)問(wèn)題具體原因不明,先看下面一段代碼:
- <s:if test="user.name == '程序'">
- ...
<s:if test="user.name == '程序'">...
這樣就算 user.name 等于“程序”也是無(wú)法通過(guò)的,需要修改成以下代碼:
- <s:if test="user.name == \'程序\'">
- ...
<s:if test="user.name == \'程序\'">...
如果“程序”是你系統的一個(gè)常量,更推薦的作法是:
- <s:if test="user.name == @com.leo.util.Constants@TYPE ">
- ...
<s:if test="user.name == @com.leo.util.Constants@TYPE ">...我不知道原因是不是因為版本問(wèn)題?希望有知道的,回復一下.
四. 用 iterator 雙重循環(huán)
這個(gè)也很常用,相信很多人都輕車(chē)熟路,那我們來(lái)回顧一下。假設 lists 裝的都是 Group 對象, Group 持有一個(gè) List<User> 那個(gè)我們接下來(lái)可以:
- <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>
上面的寫(xiě)法有很多種,但效果都是一樣的,有興趣可以多看看 OGNL 。
還有一些沒(méi)有及時(shí)整理好,下次統一再給大家分享一下.
聯(lián)系客服