Struts2與XML
在AJAX非同步請求時,通常需要伺服器端返回針對此次請求的一個快速響應
此時非同步請求的Action會返回一個我們所需要的特定格式的檔案供用戶端使用
一般是純文字、XML、JSON等,然後再進一步處理該檔案,而不會重新整理整個頁面
若Action返回JSP的話,那麼肯定會導致整個頁面都重新整理,這樣是不符合要求的
我們可以使用JQuery在頁面進行非同步請求,向伺服器端發送請求,並構造Table
JQurey簡介
JQuery是目前使用最多的AJAX架構
我們可以在www.google.com/trends中輸入jquery,dojo,dwr,yui,gwt查看它們的使用趨勢
JQuery官網為http://jquery.com
Struts2的JQuery外掛程式中提供了有關JQuery架構的標籤,我們可以便捷的使用這些標籤
可以在http://code.google.com/p/struts2-jquery/downloads/list下載struts2-jquery-plugin-2.1.0.jar
它裡面已經包含了jquery-1.4.2.js檔案,所以前台的頁面中就沒有必要再引用jQuery原始碼檔案了
下面是在Struts2中使用JQuery進行非同步請求的demo
首先是xmlTest.jsp頁面
<%@ page pageEncoding="UTF-8"%></p><p><script type="text/javascript" src="JQuery/jquery-1.4.2.js"></script></p><p><script type="text/javascript"><br />/*<br />$(function(){<br />$("#btn").click(function(){<br />$.ajax({<br />type: "POST", //請求的類型<br />url: "getXmlAction.action", //訪問的伺服器資源<br />dataType: "xml", //可以是xml、json、html等,預設為html<br />data: {name: $("#name").val()}, //發送請求時,攜帶的參數<br />success: function(returnedData){ //調用成功時執行的回調,它會接收一個參數,即伺服器端回傳過來的資料值<br />// TODO ...<br />}<br />});<br />});<br />});<br />*/</p><p> function getInfo(){<br /> /*$.post()中需要接收三個參數。。。這裡也可以用$.get()*/<br /> //GET本身是作為請求URL的一部分進行發送的,而POST請求是作為請求體的一部分進行發送的,這是HTTP協議來決定的<br /> //第一個參數是請求的資源。這裡的getXmlAction對應著struts.xml裡面<action>的name值<br /> //第二個參數是向所請求的資源上附帶的參數資訊。本例中的參數只有一個,即使用者所選擇的name值<br /> //--------該頁面請求的時候,會向伺服器端發送一個名字為name,值為$("#name").val()的資訊<br /> //第三個參數是一個function(),它裡面又有兩個參數,其中returnedData表示伺服器端所返回的資料<br /> //---------而status表示的是返回的狀態,它的值是一個字串,例如【200 OK】就表示【success】<br />$.post("getXmlAction.action",<br />{name: $("#name").val()},<br />function(returnedData, status){<br />if("success" == status){<br />//alert(returnedData);</p><p>//從伺服器端擷取資料。首先把returnedData封裝成一個JQuery對象,然後調用find()獲得常值內容<br />var id = $(returnedData).find("id").text();<br />var name = $(returnedData).find("name").text();<br />var age = $(returnedData).find("age").text();<br />var address = $(returnedData).find("address").text();</p><p>//構造HTML表格。其中<th>預設就是置中加粗的<br />var html = "<table width='60%' border='6' align='center'><tr><th>id</th><th>name</th><th>age</th><th>address</th></tr><tr align='center'><td>" + id + "</td><td>" + name + "</td><td>"+ age + "</td><td>" + address + "</td></tr></table>";</p><p>//刪掉<body>中的<table>,這裡也可以寫成【$("body table").remove();】實現同樣的刪除<table>的功能<br />//如果在append(html)之前沒有刪除表格的話,在頁面中再次點擊按鈕發送請求時,會在頁面中又一次的輸出表格<br />//我們可以將這行代碼注釋掉,查看效果<br />$("body table:eq(0)").remove();</p><p>//將動態構造的表格添加到<body>中<br />$("#theBody").append(html);<br />}<br />}<br />);<br /> }<br /></script></p><p><body id="theBody"><br /><select id="name"><br /><option value="zhangsan" selected="selected">zhangsan</option><br /><option value="lisi">lisi</option><br /></select><br /><!-- 由於是非同步請求,不需要重新整理頁面,所以button便可,無需submit --><br /><input type="button" id="btn" value="getInfo" onclick="getInfo();"><br /></body>
下面是struts.xml檔案
<?xml version="1.0" encoding="UTF-8" ?><br /><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"><br /><struts><br /><package name="JQuery" extends="struts-default"><br /><action name="getXmlAction"class="com.jadyer.action.GetXmlAction"/><br /></package><br /></struts>
然後是一個JavaBean類
package com.jadyer.bean;</p><p>public class Person {<br />private int id;<br />private String name;<br />private int age;<br />private String address;</p><p>/*--四個屬性對應的getter和setter略--*/<br />}
最後是Struts2中的用來處理前台請求的Action
package com.jadyer.action;</p><p>import java.io.PrintWriter;</p><p>import javax.servlet.http.HttpServletResponse;</p><p>import org.apache.struts2.ServletActionContext;<br />import org.dom4j.Document;<br />import org.dom4j.DocumentHelper;<br />import org.dom4j.Element;<br />import org.dom4j.io.OutputFormat;<br />import org.dom4j.io.XMLWriter;</p><p>import com.jadyer.bean.Person;<br />import com.opensymphony.xwork2.ActionSupport;</p><p>public class GetXmlAction extends ActionSupport {<br />private static final long serialVersionUID = -4464143649688180599L;</p><p>private String name;<br />//它與xmlTest.jsp中的$.post()裡面的第一個參數的name是一致的<br />public String getName() {<br />return name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}</p><p>/**<br /> * 這裡暫不涉及資料庫操作,僅僅通過資料的類比來完成非同步請求的操作<br /> */<br />@Override<br />public String execute() throws Exception {<br />/**<br /> * 首先構建2個用於提供資料的Person對象<br /> */<br />// zhangsan<br />Person person1 = new Person();<br />person1.setId(1);<br />person1.setName("zhangsan");<br />person1.setAge(20);<br />person1.setAddress("shanghai");<br />// lisi<br />Person person2 = new Person();<br />person2.setId(2);<br />person2.setName("lisi");<br />person2.setAge(30);<br />person2.setAddress("tianjin");</p><p>/**<br /> * 接下來就是使用Dom4J構造XML文檔<br /> * <users><br /> * <user><br /> * <id>1</id><br /> * <name>zhangsan</name><br /> * <age>20</age><br /> * <address>shanghai</address><br /> * </user><br /> * </users><br /> */<br />// Document對象代表整個xml文檔<br />Document document = DocumentHelper.createDocument();</p><p>// rootElement代表文檔根項目<br />Element rootElement = document.addElement("users");</p><p>// 增加一個注釋<br />rootElement.addComment("This is a comment!");</p><p>// 增加一個<user>標籤<br />Element userElement = rootElement.addElement("user");</p><p>// 設定不同的<user>下面的子標籤<br />Element idElement = userElement.addElement("id");<br />Element nameElement = userElement.addElement("name");<br />Element ageElement = userElement.addElement("age");<br />Element addressElement = userElement.addElement("address");</p><p>// 為各個子標籤填儲值。根據使用者輸入資訊的不同來決定標籤值內容的不同<br />if ("zhangsan".equals(this.name)) {<br />idElement.setText(person1.getId() + "");<br />nameElement.setText(person1.getName());<br />ageElement.setText(person1.getAge() + "");<br />addressElement.setText(person1.getAddress());<br />} else if("lisi".equals(this.name)) {<br />idElement.setText(person2.getId() + "");<br />nameElement.setText(person2.getName());<br />ageElement.setText(person2.getAge() + "");<br />addressElement.setText(person2.getAddress());<br />}</p><p>/**<br /> * 將XML文檔返回給使用者<br /> * 如果這裡return SUCCESS的話,則會導致當前頁面重新整理<br /> * 哪怕返回的是當前頁面,也會導致其重新整理,而重新請求一次<br /> */<br />HttpServletResponse response = ServletActionContext.getResponse();<br />// 設定回應標頭的資訊。這裡設定的【text/xml】是非常非常重要的<br />response.setContentType("text/xml; charset=UTF-8");<br />// 取消瀏覽器緩衝。因為非同步重新整理的時候,經常會出現緩衝的情況,影響我們的開發<br />response.setHeader("Cache-Control", "no-cache");</p><p>// 藉助HttpServletResponse的協助,來獲得一個PrintWriter對象<br />// 然後將XML檔案寫到Writer對象裡面,發送給用戶端<br />PrintWriter out = response.getWriter();</p><p>// 設定輸出格式以及編碼。這點與jdom是一樣的<br />OutputFormat format = OutputFormat.createPrettyPrint();<br />format.setEncoding("UTF-8");</p><p>// 通過org.dom4j.io.XMLWriter來進行輸出<br />XMLWriter writer = new XMLWriter(out, format);<br />writer.write(document); //將document所代表的XML文本輸出到【XMLWriter(out, format)】中的out對象中</p><p>out.flush(); // 清空流<br />out.close(); // 關閉流</p><p>// 這雷根本就不需要返回任何東西,但該方法要求返回一個String,所以這裡return null<br />// 而內容的輸出則通過Servlet來實現,這是向頁面返回自訂文本【包括JSON、XML、純文字】的一種比較好的方式<br />// 由於這裡返回的是null,所以struts.xml裡面的<action>中便無需定義<result><br />return null;<br />}<br />}