jquery中ajax 從前端到后端 完整過程解析


幾個原則:

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充分反映了面向對象的編程思想。

4、幾個推薦博客:

介紹(hascode()的作用)   http://www.cnblogs.com/dolphin0520/p/3681042.html

結論:1.hashCode方法的存在是為了減少equals方法的調用次數,從而提高程序效率。

   2.在設計一個類的時候為需要重寫equals方法,比如String類,但是千萬要注意,在重寫equals方法的同時,必須重寫hashCode方法。

介紹了字符串相似度算法(在DNA對比,網頁聚類等方面都有用武之地)http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2765633.html

經典的KMP算法 http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

結論:1.http://www.ruanyifeng.com/blog/algorithm/ 這是這個作者所有關於數學和算法的帖子,都相當精彩。

 

 

  

 

  

  

 

 

 


 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM