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/ 这是这个作者所有关于数学和算法的帖子,都相当精彩。

  

  

  

时间: 2024-10-13 15:51:01

jquery中ajax 从前端到后端 完整过程解析的相关文章

在jQuery中Ajax的Post提交中文乱码的解决方案(转)

引言: 在jQuery的Ajax POST请求中,进行请求,其中的中文在后台,显示为乱码,该如何解决呢? 问题的引入: var regid = $('#oregion').combobox('getValue'); //var sname = $('#sname').val(); var sname = encodeURI($('#sname').val(),"UTF-8"); if(regid!=""&&regid!='undefined'){ $

关于Jquery中ajax方法data参数用法的总结

jquery手册描述: data 发送到服务器的数据.将自动转换为请求字符串格式.GET 请求中将附加在 URL 后.查看 processData 选项说明以禁止此自动转换.必须为 Key/Value 格式.如果为数组,jQuery 将自动为不同值对应同一个名称.如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'. 示例: $.ajax({    type: "POST",    u

JQuery中Ajax详细参数使用案例

JQuery中Ajax详细参数使用案例 参考文档:http://www.jb51.net/shouce/jquery1.82/ 参考文档:http://jquery.cuishifeng.cn/jQuery.Ajax.html 注意事项 本案例演示测试了官方文档中不常用的参数使用方法 前端代码 function theFileUploadGai() {//执行上传 var zhi={ "a1":["你好啊","こんにちは","hello

JQuery中$.ajax()方法参数详解

url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 delete也可以使用,但仅部分浏览器支持. timeout: 要求为Number类型的参数,设置请求超时时间(毫秒).此设置将覆盖$.ajaxSetup()方法的全局设 置. async:要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求. 如果需要发送同步请求,请将此选项

jQuery中$.ajax()详解(转)

JQuery中$.ajax()方法参数详解     url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 delete也可以使用,但仅部分浏览器支持. timeout: 要求为Number类型的参数,设置请求超时时间(毫秒).此设置将覆盖$.ajaxSetup()方法的全局设 置. async:要求为Boolean类型的参数,默认设置为true,所有

jQuery中ajax的4种常用请求方式

jQuery中ajax的4种常用请求方式: 1.$.ajax()返回其创建的 XMLHttpRequest 对象. $.ajax() 只有一个参数:参数 key/value 对象,包含各配置及回调函数信息.详细参数选项见下. 如果你指定了 dataType 选项,请确保服务器返回正确的 MIME 信息,(如 xml 返回 "text/xml"). 实例: 保存数据到服务器,成功时显示信息. $.ajax({ type: "post", dataType: "

通过Jquery中Ajax获取json文件数据

1. JSON(JavaScript Object Notation): javaScript对象表示法: 是存储和交换文本信息的语法,比xml更小,更快,更易解析. 2. JSON基本书写格式 : 名称/值对. 例如: "Student":"Tom" Json值可以是: 数字(整数或浮点数) 字符串(在双引号中) 逻辑值(true或者false) 数组(在方括号中) 对象(在花括号中) null  例如(对象):{"name":"to

关于jQuery中$.ajax()跨域

今天研究了一些用jquery $.ajax跨域的方法,总结了一些注意事项如下: 首先,跨域JSONP不是AJAX.它不使用XMLHttpRequest.只不过是一个动态脚本元素加载JavaScript代码. Cross-domain JSONP isn't AJAX at all. It doesn't use XMLHttpRequest. It's nothing more than a dynamic script element that loads JavaScript code. Y

jQuery中ajax的使用与缓存问题的解决方法

jQuery中ajax的使用与缓存问题的解决方法 1:GET访问 浏览器 认为 是等幂的就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配]所以 第二次访问的时候 如果 URL字符串没变化 浏览器是 直接拿出了第一次访问的结果 POST则 认为是一个 变动性 访问 (浏览器 认为 POST的提交 必定是 有改变的) 防止 GET 的 等幂 访问 就在URL后面加上 ?+new Date();,[总之就是使每次访问的URL字符串不一样的] 设计WEB页面的时候 也应该遵守这个