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