1.get方式訪問瀏覽器時,常加參數緣由:
GET訪問瀏覽器是等冪的,就是一個相同的URL只有一個結果[相同是指整個URL字串完全符合],所以第二次訪問的時候如果 URL字串沒變化,瀏覽器是 直接拿出了第一次訪問的結果。POST則認為是一個變動性訪問 (瀏覽器認為POST的提交必定是有改變的)防止GET的等冪訪問就在URL後面加上?+new Date();[總之就是使每次訪問的URL字串不一樣的]。設計WEB頁面的時候也應該遵守這個原則。
2.ajax方式中的get和post的區別:
Get方式:
用get方式可傳送簡單資料,但大小一般限制在1KB下,資料追加到url中發送(http的header傳送),也就是說,瀏覽器 將各個表單欄位元素及其資料按照URL參數的格式附加在請求行中的資源路徑後面。另外最重要的一點是,它會被用戶端的瀏覽器緩衝起來,那麼,別人就可以從瀏覽器的記錄中,讀取到此客戶的資料,比如帳號和密碼等。因此,在某些情況下,get方法會帶來嚴重的安全性問題。總之,GET方式傳送資料量小,處理效率高,安全性低,會被緩衝,而POST反之。
Post方式:
當使用POST方式時,瀏覽器把各表單欄位元素及其資料作為HTTP訊息的實體內容發送給Web伺服器,而不是作為URL地址的參數進行傳遞,使用POST方式傳遞的資料量要比使用GET方式傳送的資料量大的多。
接下來,看代碼中我們的前台:
我們看到前台的代碼中有:
當後台收到前端的$.ajax( )中的路徑時(url: "/report/loadAssetsTransactionsByRegionTime"),我們在web.xml中配置了攔截器,這部分是由Struts2的核心控制器:StrutsPrepareAndExecuteFilter來完成的,它包括兩個部分StrutsPrepareFilter和StrutsExecuteFilter。
<filter>
<filter-name>struts-prepare</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
</filter>
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>
如上所示,是struts2核心控制器代碼在web.xml中的設定檔,映射路徑一般映射到"/*",再來看下面具體的攔截動作
<filter-mapping>
<filter-name>struts-prepare</filter-name>
<url-pattern>/main/*</url-pattern>
<url-pattern>/inspection/*</url-pattern>
<url-pattern>/report/*</url-pattern>
<url-pattern>/audit/*</url-pattern>
<url-pattern>/ajax/*</url-pattern>
<url-pattern>/location/*</url-pattern>
<url-pattern>/admin/*</url-pattern>
<url-pattern>/calculation/*</url-pattern>
<url-pattern>/conf/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/main/*</url-pattern>
<url-pattern>/inspection/*</url-pattern>
<url-pattern>/report/*</url-pattern>
<url-pattern>/audit/*</url-pattern>
<url-pattern>/ajax/*</url-pattern>
<url-pattern>/location/*</url-pattern>
<url-pattern>/admin/*</url-pattern>
<url-pattern>/calculation/*</url-pattern>
<url-pattern>/conf/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
struts中核心是Action和攔截器,struts2的action必須放在一個指定的包空間下定義。struts.xml檔案中package元素用於定義包配置。struts2架構有兩個核心設定檔,其中struts.xml檔案主要負責管理應用中的Action映射,及Action處理結果和實體資源之間的映射關係。除此之外,Struts2架構還包含了一個struts.properties檔案,該檔案主義了Struts2架構的大量常量屬性。但通常推薦也是在struts.xml檔案中來配置這些常量屬性。
<!-- 定義處理請求URL為dailyMonitoringAction的Action -->
<action name="loadAssetsTransactionsByRegionTime" class="dailyMonitoringAction" method="loadAssetsTransactionsByRegionTime">
<!-- 定義處理結果字串和資源之間的映射關係 ,該action中指定了返回的type為json-->
<result name="success" type="json">
<!-- 指定json返回的域 -->
<param name="includeProperties">*</param>
</result>
</action>
然後我們再看Action中,可以採用SpringMVC的方式來傳遞參數,也可以使用struts2的方式來傳遞參數,如下是使用SpringMVC的方式來傳遞資料。
@RequestMapping(value="/loadAssetsTransactionsByRegionTime", method=RequestMethod.GET)
public String loadAssetsTransactionsByRegionTime(String starttime, String endtime, HttpServletResponse response) {
String startTime = starttime;
String endTime = endtime;
lineVM = new LineChartVM();
lineVM.setTitle("Assets Transactions By Region");
lineVM.setyAxisName("Transactions");
Map<String, Map<String, Double>> assetRegionMap = dailyMonitoringService
.loadAssetRegionTransactionTime(startTime, endTime);
lineVM.setCategories(new ArrayList<String>(assetRegionMap.keySet()));
Map<String, List<Double>> seriesMap = pivotingMap(assetRegionMap, 0D);
List<ChartSerieVM> seriesList = new ArrayList<ChartSerieVM>();
for (String key : seriesMap.keySet()) {
ChartSerieVM chartSerieVM = new ChartSerieVM();
chartSerieVM.setName(key);
chartSerieVM.setData(seriesMap.get(key));
seriesList.add(chartSerieVM);
}
lineVM.setSeries(seriesList);
return SUCCESS;
}
或者,我們可以使用Struts2來解決這個問題,我們以http://127.0.0.1:8080/demo/index.jsp?name=aty&age=20為例,struts2的action中擷取請求參數值,總的來說有2種方式:第一種在action中定義同名變數,提供get/set方法
public class DemoAction
{
private String name;
private int age;
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return this.age;
}
public void setName(int age)
{
this.age = age;
}
}
又或者,使用手動擷取HttpServletRequest,然後調用request.getParameter()
public class DemoAction
{
public String execute()
{
HttpServletRequest request = ServletActionContext.getRequest();
String name = request.getParameter("name");
String age = request.getParameter("age");
}
}
這2種方式有什麼差別呢?很顯然是成員變數和局部變數的區別。我們知道一個action可以定義多個public方法,用來處理不同的前台請求。如 果同一個請求參數,會被多個方法使用,那麼就適合用第一種方式;如果一個請求參數,僅僅只會被一個方法使用,就適合使用第二種方式。原則就是:保證同一個 參數名稱在action代碼中只出現一次(避免重複),而且變數的作用範圍要儘可能的小(代碼內聚)。將http請求參數封裝到實體類的方式,可以參考struts2的模型驅動http://blog.csdn.net/li_tengfei/article/details/6098145。下面我們看下,如何將參數封裝到Map和List中。
public class DemoAction
{
private Map<string,string> requestMap = new HashMap<string,string>();
private List<user> requestList = new ArrayList<user>();
}</user></user></string,string></string,string>
js將參數封裝到list中
var params = {};
params["requestList[0].id"] = $("#person_id").attr("value");
params["requestList[0].username"] = "aty";
params["requestList[0].password"] = "123";
params["requestList[0].age"] = 25;
params["requestList[0].address"] = "";
$.post(url,params);
js將參數封裝到map
var params = {};
params["requestMap.id"] = $("#person_id").attr("value");
params["requestMap.username"] = "aty";
params["requestMap.password"] = "123";
params["requestMap.age"] = 25;
params["requestMap.address"] = "";
$.post(url,params);
可以看到使用Map接收http請求參數, 和使用實體類沒有差別,在js和java端的做法也都是相同的。
補充幾個知識點:
1、springMVC和struts2的對比 (參考:http://blog.csdn.net/gstormspire/article/details/8239182)
我們採用struts2時採用的傳統的設定檔的方式,並沒有使用傳說中的零配置。spring3 mvc可以認為已經100%零配置了(除了配置spring mvc-servlet.xml外)。
第一,機制:spring mvc的入口是servlet,而struts2是filter(這裡要指出,filter和servlet是不同的。以前認為filter是 servlet的一種特殊),這樣就導致了二者的機制不同,這裡就牽涉到servlet和filter的區別了。
第二,效能:spring會稍微比struts快。spring mvc是基於方法的設計,而sturts是基於類,每次發一次請求都會執行個體一個action,每個action都會被注入屬性,而spring基於方法, 粒度更細,但要小心把握像在servlet控制資料一樣。spring3 mvc是方法層級的攔截,攔截到方法後根據參數上的註解,把request資料注入進去,在spring3 mvc中,一個方法對應一個request上下文。而struts2架構是類層級的攔截,每次來了請求就建立一個Action,然後調用setter getter方法把request中的資料注入;struts2實際上是通過setter getter方法與request打交道的;struts2中,一個Action對象對應一個request上下文。
第三,參數傳遞:struts是在接受參數的時候,可以用屬性來接受參數,這就說明參數是讓多個方法共用的。
第四,設計思想上:struts更加符合oop的編程思想, spring就比較謹慎,在servlet上擴充。
第五,spring mvc是方法層級的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現restful url。struts2是類層級的攔截,一個類對應一個request上下文;實現restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共用,這也就無法用註解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response資料,請求資料通過參數擷取,處理結果通過ModelMap交回給架構方法之間不共用變數,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變數是共用的,這不會影響程式運行,卻給我們編碼,讀程式時帶來麻煩。
故,總結如下:“struts2是類層級的攔截, 一個類對應一個request上下文,springmvc是方法層級的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上 spring3 mvc就容易實現restful url 。而struts2的架構實現起來要費勁,因為struts2 action的一個方法可以對應一個url。而其類屬性卻被所有方法共用,這也就無法用註解或其他方式標識其所屬方法了。spring3mvc的方法之間基本上獨立的,獨享request response資料,請求資料通過參數擷取,處理結果通過ModelMap交回給架構。方法之間不共用變數,而struts2搞的就比較亂,雖然方法之間也是獨立的,但其所有Action變數是共用的。這不會影響程式運行,卻給我們編碼 讀程式時帶來麻煩。由於Struts2需要針對每個Request進行封裝,把Request,Session等Servlet生命週期的變數封裝成一個一個Map,供給每個Action使用,並保證安全執行緒。所以在原則上,是比較耗費記憶體的。
2、JSTL在項目中的使用:JSTL(JSP Standard Tag Library,JSP標準標籤庫),是一個不斷完善的開放原始碼的JSP標籤庫。
3、java中Map介面的使用:map介面按照<key,value>的索引值對方式組合,key是索引,本身也是對象,這點是區別於數組的。1,2,3,4...(數組的索引只能是下標)使用的時候,一般選擇的是Map介面的子類,而不直接使用Map介面。(Collection容器中包含Set和List介面,Set中又包含HashSet,List中包含LinkedList和ArrayList;單獨的Map介面中只有HashMap)。
Java 中某些最常用的類。 最常用的集合類是List 和 介面Map。 List 的具體實現包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構建、儲存和操作任何類型對象的元素列表。 List 適用於按數值索引訪問元素的情形,其中的資料有順序且可以重複。而Set中資料無順序且不可以重複。
先來看我們的Object類中的兩個方法在Map介面中的覆蓋實現:equals(obj)方法,用於比較指定對象與此Map的等價性;hascode()方法,返回此Map的雜湊嗎。(那麼問題來了,java中使用hashcode()方法有什麼用呢?使用hascode()方法用於比較兩個對象是否相等,當兩個對象的hascode()值不相等的時候,那麼兩個對象肯定不相等;如果兩個對象的hascode()方法相等,再進一步比較equals()方法,由於hascode()的值是int,比較它們速度回更快,所以可以提升比較的時候的效率);
每個java對象都有一個唯一的標識,object類中的hash方法就是直接返回對象的這個內部id號,與string的hash方法是不同的,object的hash方法能夠用來區分不同的對象.因為原始的object對象沒有任何有意義的值可用來計算雜湊。唯一的id充分反映了物件導向的編程思想。