Spring框架

来源:互联网 发布:横县教研室网络硬盘 编辑:程序博客网 时间:2024/06/06 00:18

什么是spring:

  是一个开源的、用来简化企业级应用开发的框架。
  简化:spring对很多常用的API做了封装(比如,使用spring jdbc来访问数据库,就不再需要获得连接与关闭连接)。
  解耦:spring可以帮我们管理对象及对象之间的关系,这样一来,软件的可维护性会大大提高。
  集成:spring可以将其它的一些框架(比如quartz)集成进来。

Spring容器:

Spring容器是什么:

  spring框架中的一个重要的模块,用来管理对象。

如何启动Spring容器:

  step1. 导入spring框架相关的jar文件。

  step2. 添加spring的配置文件。

  step3. 启动spring容器:ApplicationContext ac =new ClassPathXmlApplicationContext(“applicationContext.xml”);

Javabean的条件:

  - 类的类型是public;

  - 有完整的包结构;

  - 类实现了序列化接口;

  - 类有无参构造器;

  - 属性有对应的get/set方法;

spring将所有被容器管理的Java类称之为一个Javabean。

利用容器创建对象的三种方式:

  1. 无参构造器(重点):   

   - 配置文件:

[html] view plain copy
  1. <!-- 利用无参构造器:创建一个bean实例。   
  2.     id属性:要求唯一;   
  3.     class属性:要写完整的类名;  
  4.  -->  
  5. <bean id="hb" class="first.HelloBean" />  
   -  启动Spring容器:
[java] view plain copy
  1. //配置文件名称可以改,位置也可以改变。  
  2. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//启动Spring容器  
  3. System.out.println(ac);  
  4.           
  5. //getBean方法:通知容器,依据id,获取对应的bean实例。  
  6. HelloBean hb = ac.getBean("hb",HelloBean.class);  
  7. System.out.println(hb);  

  注意:该类必须带有无参构造器。 

2. 静态工厂方法(了解):

[html] view plain copy
  1. <!-- 利用静态工厂方法:创建一个bean实例。  
  2.     factory-method属性:指定要调用的静态方法。  
  3. -->  
  4. <bean id="cal1" class="java.util.Calendar" factory-method="getInstance" />  

  3. 实例工厂方法(了解):

[html] view plain copy
  1. <!-- 利用实例工厂方法:创建一个bean实例。  
  2.      factory-bean属性:一个bean实例的id;  
  3.      factory-method属性: 要调用的方法。  
  4.  -->  
  5. <bean id="time1" factory-bean="cal1" factory-method="getTime" />  

作用域:

  - 默认情况下,容器对于某个bean的配置,只会创建一个实例;

  - 可以通过scope属性来指定作用域。

[html] view plain copy
  1. <!-- scope属性:指定作用域。  
  2.      默认值为singleton(单例);  
  3.      如果值为prototype(原型),每getBean一次;会创建一个新的对象。  
  4. -->  
  5. <bean id="eb" class="other.ExampleBean" scope="prototype" />  
[java] view plain copy
  1. //启动spring容器  
  2. ApplicationContext ac = new ClassPathXmlApplicationContext("app2.xml");  
  3. //通过容器获得一个bean实例  
  4. ExampleBean eb1 = ac.getBean("eb",ExampleBean.class);  
  5. ExampleBean eb2 = ac.getBean("eb",ExampleBean.class);  
  6. //若scope属性值为prototype,输出flase;若scope属性值为singleton,输出true          
  7. System.out.println(eb1 == eb2);  

延迟加载:

  - 默认情况下,容器启动之后,会将所用作用域为singleton的bean创建好。

  - 可以设置lazy-init属性为true,表示延迟加载(即容器启动之后,不会立即创建作用域为singleton的实例)。

[html] view plain copy
  1. <!-- scope属性:指定作用域。  
  2.      默认值为singleton(单例);  
  3.      如果值为prototype(原型),每getBean一次,会创建一个新的对象。  
  4.      lazy-init属性:值为true,表示延迟加载。  
  5. -->  
  6. <bean id="eb" class="other.ExampleBean" scope="singleton" lazy-init="true"/>  
生命周期相关的几个方法:

  - 初始化方法:init-method属性指定。

  - 销毁方法:destroy-method属性指定

  - 注:销毁方法只针对scope=singleton有效。

[html] view plain copy
  1. <!-- init-method属性:指定初始化方法。  
  2.      容器创建相应的bean实例之后,会立即调用该实例的初始化方法。  
  3.      destroy-method属性:指定销毁方法。容器在删除bean实例之前,会立即调用该实例的销毁方法。  
  4.      注:销毁方法只针对"scope=singleton"有效。  
  5. -->  
  6. <bean id="mb" class="other.MessageBean"   
  7.     init-method="init" destroy-method="destroy" scope="prototype" />  

IOC(Inversion Of Controller)控制反转:

什么是IOC:

  对象之间的依赖关系由容器来建立。

DI(Dependency Injection)依赖注入:

  容器通过调用对象的构造器或者set方法来建立对象之间的依赖关系;

  注:IOC是目标,DI是手段。

依赖注入的方式:

   1. set方式:

       - 有无参构造器;

       - 有对应的set方法。


[html] view plain copy
  1. <!-- 调用set方法来建立依赖关系。  
  2.      property的name属性:指定要注入的bean的属性名称;  
  3.      ref属性:指定要注入的bean的id。   
  4.  -->  
  5. <bean id="b1" class="ioc.B"/>  
  6. <bean id="a" class="ioc.A">  
  7.    <property name="b" ref="b1"/>  
  8. </bean>  

   2. 构造器方式:

       - 有相应的带参的构造器。 

[html] view plain copy
  1. <!-- 构造器方式注入。  
  2.     index属性:指定要注入的参数的下标,下标从0开始。  
  3.  -->  
  4. <bean id="b1" class="ioc2.B"/>  
  5. <bean id="a" class="ioc2.A">  
  6.     <constructor-arg index="0" ref="b1"/>  
  7. </bean>  
自动装配:

  容器默认情况下,禁止自动装配。使用autowire属性来进行自动装配(如果要使用自动装配,优先考虑byName)。autowire的取值:

    - byName:查找id等于属性名的bean,然后调用set方法完成注入。 如果找不到对应的bean,会注入null;

    - byType:查找与属性类型一致的bean,然后调用set方法完成注入。如果找不到对应的bean,会注入null。 找到多个,会报错;

    - constructor:与byType类似,只是调用构造器来完成注入。

[html] view plain copy
  1. <bean id="wt" class="autowire.Waiter"/>  
  2. <!-- byName: 查找id等于属性名的bean,然后调用set方法完成注入。如果找不到对应的bean,会注入null。  
  3.      注意:a.有无参构造器;b.有set方法  
  4.  -->  
  5. <bean id="rest" class="autowire.Restaurant" autowire="byName"/>  
  6.   
  7. <!-- byType:查找与属性类型一致的bean,然后调用set方法完成注入。如果找不到对应的bean,会注入null。找到多个,会报错。  
  8.      注意:a.有无参构造器;b.有set方法  
  9.  -->  
  10. <bean id="rest" class="autowire.Restaurant" autowire="byType"/>   
  11.   
  12. <!-- constructor:与byType类似,只是调用构造器来完成注入。 -->  
  13. <bean id="rest" class="autowire.Restaurant" autowire="constructor"/>  
注入基本类型的值:

  使用value属性来赋值 ,会将字符串自动转换成相应的数值类型。

注入集合类型的值:

  List . Set . Map . Properties。

[java] view plain copy
  1. //实体类属性  
  2. private String name;  
  3. private int age;  
  4. private List<String> cities;  
  5. private Set<String> interest;  
  6. private Map<String,Double> score;  
  7. private Properties db;  
[html] view plain copy
  1. <!-- 注入基本类型的值  
  2.      注入集合类型的值  
  3.  -->  
  4. <bean id="eb" class="basic.ExampleBean">  
  5.        <property name="name" value="汪小帅"/>  
  6.        <property name="age" value="22"/>  
  7.        <property name="cities">  
  8.       <list>  
  9.         <value>合肥</value>  
  10.         <value>杭州</value>  
  11.         <value>舟山</value>  
  12.         <!-- 允许重复元素 -->  
  13.         <value>舟山</value>  
  14.       </list>  
  15.         </property>  
  16.     <property name="interest">  
  17.        <set>  
  18.         <value>音乐</value>  
  19.         <value>阅读</value>  
  20.         <value>编程</value>  
  21.         <!-- 不允许重复元素 -->  
  22.         <value>编程</value>  
  23.        </set>  
  24.     </property>  
  25.     <property name="score">  
  26.        <map>  
  27.         <entry key="english" value="90.5"/>  
  28.         <entry key="math" value="99"/>  
  29.         </map>  
  30.     </property>  
  31.     <property name="db">  
  32.         <props>  
  33.         <prop key="username">yuanxin</prop>  
  34.         <prop key="password">123456</prop>  
  35.         </props>  
  36.     </property>  
  37. </bean>  
将集合类型当做一个bean来配置:

[html] view plain copy
  1. <!-- 将集合类型的值当做一个bean来配置。  
  2.      命名空间(namespace):为了区分同名元素而在元素前面添加的前缀。  
  3.  -->  
  4. <util:list id="citiesBean">  
  5.     <value>北京</value>  
  6.     <value>武汉</value>  
  7.     <value>重庆</value>  
  8. </util:list>  
  9. <util:set id="interestBean">  
  10.     <value>台球</value>  
  11.     <value>钓鱼</value>  
  12.     <value>做饭</value>  
  13. </util:set>  
  14. <util:map id="scoreBean">  
  15.     <entry key="english" value="80"/>  
  16.     <entry key="math" value="90"/>  
  17. </util:map>  
  18. <util:properties id="dbBean">  
  19.     <prop key="username">Tom</prop>  
  20.     <prop key="password">1234</prop>  
  21. </util:properties>  
  22. <bean id="eb2" class="basic.ExampleBean">  
  23.     <property name="cities" ref="citiesBean"/>  
  24.     <property name="interest" ref="interestBean"/>  
  25.     <property name="score" ref="scoreBean"/>  
  26.     <property name="db" ref="dbBean"/>  
  27. </bean>  
  28.        
  29. <!-- 读取location指定位置的文件的内容。classpath:是spring框架内部的约定。 -->  
  30. <util:properties id="config" location="classpath:config.properties"/>  
Spring表达式:

  读取bean或者集合的属性值, 语法类似el表达式。

[html] view plain copy
  1. <!-- 使用spring表达式读取其它的bean的属性值。  
  2.     #{eb.name}:读取id等于eb的bean的name属性值。  
  3.     #{eb.cities[0]}:读取id等于eb的bean的cities属性值(cities是一个List,读取的是下标等于0的元素的值)。  
  4.     #{eb.score.math}:读取id等于eb的bean的score属性值(score是一个Map,读取的是key等于math的value值)。  
  5.     #{config.pagesize}:读取id等于config的bean的pagesize属性值(pagesize是properties中的key)。  
  6.  -->  
  7. <bean id="sb" class="basic.SomeBean">  
  8.     <property name="name" value="#{eb.name}"/>  
  9.     <property name="city" value="#{eb.cities[0]}"/>  
  10.     <property name="score" value="#{eb.score.math}"/>  
  11.     <property name="pageSize" value="#{config.pagesize}"/>  
  12. </bean>  
使用注解简化配置文件:

  1. 什么是组件扫描:

   spring容器启动之后,会扫描指定的包及其子包下面的的所有的类,如果该类有特定的注解,则spring容器会将其纳入容器进行管理。也就是说,相当于在配置文件当中,添加了一个bean的配置。

  2. 如何使用组件扫描:

     step1. 在配置文件当中,添加<context:component-scan base-package="annotation"/>;

     step2. 在类名前,添加注解:

          a. Component 通用;

          b. Service 业务层;

          c. Repository 持久层;

          d. Controller 控制层。

     注意:以上注解,只有语义上的差异,是等价的。

  3. 两个注解:

    a. @Lazy(true): 延迟加载;

    b. @Scope("prototype"):指定作用域,默认值是singleton。

  4. 生命周期相关的注解:

    a. @PostConstruct: 指定初始化方;

    b. @PreDestroy: 指定销毁方法。

  5. 依赖注入相关的注解:

    a. Autowired和Qualifier支持set方式注入和构造器注入;

    b. Resource 只支持set方式注入。

    注意:

       - @Autowired和@Qualifier也可以加到属性前面。等介于加到set方法前面;

       - 默认情况下,容器会按照byType的方式进行注入,有可能找到多个符合要求的bean。建议使用@Qualifier来指定要注入的bean的id。

[java] view plain copy
  1. @Autowired  
  2. public Bar(@Qualifier("wt") Waiter wt) {  
  3.    System.out.println("Bar的有参构造器...");  
  4.    this.wt = wt;  
  5. }  
[java] view plain copy
  1. //name属性指定注入的bean的id。  
  2. @Resource(name="wt")  
  3. public void setWt(Waiter wt) {  
  4.     System.out.println("School的setWt方法...");  
  5.     this.wt = wt;  
  6. }  

Servlet MVC:


Spring MVC:


 1. spring mvc是什么:

   是一个mvc框架,便于开发基于mvc架构的web应用程序。

 2. 五大核心组件:

   a. DispatcherServlet (前端控制器)

   b. HandlerMapping (处理映射

   c. Controller (处理器)

   d. ModelAndView (处理结果)

   e. ViewResolver (视图解析器)

  工作过程:请求先发送给DispatcherServlet,DispatcherServlet会依据HandlerMapping的指示调用对应的Controller来处理。Controller将处理结果封装成ModelAndView并返回给DispatcherServlet。DispatcherServlet会依据ViewResolver的解析,调用对应的视图对象(比如jsp),生成最终的页面。


 3. 编程步骤:

  step1. 导包(spring-webmvc);
  step2. 添加spring配置文件(空白的配置文件);
  step3. 配置DispatcherServlet(web.xml);

[html] view plain copy
  1. <servlet>  
  2.   <servlet-name>action</servlet-name>  
  3.   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.   <!-- DispatcherServlet的初始化方法会启动spring容器,所以需要告诉它spring配置文件的位置。   
  5.      注意:默认情况下,如果没有配置contextConfigLocation(即没有指定spring配置文件的位置),则会查找/WEB-INF/servletname-servlet.xml。-->  
  6.   <init-param>  
  7.     <param-name>contextConfigLocation</param-name>  
  8.     <param-value>classpath:app.xml</param-value>  
  9.   </init-param>  
  10.   <load-on-startup>1</load-on-startup>  
  11. </servlet>  
  12. <servlet-mapping>  
  13.   <servlet-name>action</servlet-name>  
  14.   <url-pattern>*.do</url-pattern>  
  15. </servlet-mapping>  
  step4. 写Controller(业务逻辑);

[java] view plain copy
  1. /** 处理器:处理业务逻辑 */  
  2. public class HelloController implements Controller{  
  3.     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  4.         System.out.println("HelloController的handleRequest方法...");  
  5.         /* 
  6.          * ModelAndView有两个构造器。 
  7.          *  1. ModelAndView(String viewName):viewName是视图名。 
  8.          *  2. ModelAndView(String viewName,Map data):data是数据。 
  9.          */  
  10.         return new ModelAndView("hello");  
  11.     }  
  12. }  
  step5. 写jsp;
  step6. 在spring配置文件当中,添加HandlerMapping,ViewResolver的配置信息。

[html] view plain copy
  1. <!-- 配置HandlerMapping。 设置请求路径与处理器的对应关系。 -->  
  2. <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  3.   <property name="mappings">  
  4.     <props>  
  5.     <prop key="/hello.do">helloController</prop>  
  6.     </props>  
  7.   </property>  
  8. </bean>  
  9. <!-- 配置处理器。 -->  
  10. <bean id="helloController" class="controller.HelloController" />  
  11. <!-- 配置视图解析器。 负责将视图名解析成真正的视图对象,比如 将"hello"解析成hello.jsp。 -->  
  12. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  13.   <property name="prefix" value="/WEB-INF/" />  
  14.   <property name="suffix" value=".jsp" />  
  15. </bean>  

分层结构:


基于注解的MVC应用:

 编程步骤:

   step1. 导包
   step2. 添加spring配置文件(空白的配置文件)
   step3. 配置DispatcherServlet(web.xml)
   step4. 写Controller(业务逻辑)
       注意: 

          a. 不用实现Controller接口。

          b. 可以添加多个处理方法。

          c. 处理方法的名称可以自定义,方法的返回值可以是 ModelAndView,也可以是String。

          d. 在类名前,添加@Controller注解。

          e. 可以在类名前或者处理方法前面添加@RequestMapping注解。 该注解的作用相当于HandlerMapping。
   step5. 写jsp
   step6. 在spring配置文件当中,添加ViewResolver的配置信息。

   注意:

     - 添加组件扫描(component-scan base-package)。 

     - 添加mvc注解扫描(annotation-driven)。

[html] view plain copy
  1. <!-- 配置组件扫描。 容器才会扫描类名前的四个注解: @Component,@Controller,@Service,@Repository。 -->  
  2. <context:component-scan base-package="controller" />  
  3. <!-- 配置mvc注解扫描。 容器才会扫描mvc相关的注解,比如 @RequestMapping。 -->  
  4. <mvc:annotation-driven />  
  5. <!-- 配置视图解析器。 负责将视图名解析成真正的视图对象,比如 将"hello"解析成hello.jsp。 -->  
  6. <beanclassbeanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  7.     <property name="prefix" value="/WEB-INF/" />  
  8.     <property name="suffix" value=".jsp" />  
  9. </bean>  
获取请求参数:

 login.jsp页面:

[html] view plain copy
  1. <%@page pageEncoding="utf-8" contentType="text/html; charset=utf-8" %>  
  2. <html>  
  3.   <head></head>  
  4.   <body style="font-size:30px;">  
  5.      <form action="login.do" method="post">  
  6.     用户名:<input name="username"/><br/>  
  7.     密码:<input name="pwd" type="password"/><br/>  
  8.     <input type="submit" value="登录"/>  
  9.      </form>  
  10.   </body>  
  11. </html>  

请求参数封装成一个Javabean:

[java] view plain copy
  1. /** 
  2.  * 将请求参数封装成一个Javabean。 
  3.  * 该类有如下要求: 
  4.  * a. 类的属性与请求参数名保持一致(名称一样,类型一致) 
  5.  * b. 这些属性应该提供相应的get/set方法。 
  6.  */  
  7. public class User {  
  8.     private String username;  
  9.     private String pwd;  
  10.   
  11.         //此处为属性个get/set方法(省略)...  
  12.   
  13. }  

index.jsp页面:

[html] view plain copy
  1. <h1>Login success.</h1>  
  2. <h1>Welcome ${username}</h1>  
  3. <h1>Welcome ${user.username}</h1>  

方式一:通过request

  在处理方法里面,添加request作为方法的入参即可。
  注: 前端控制器会将request对象作为参数传进来。

[java] view plain copy
  1. @RequestMapping("/login.do")  
  2. /* 
  3.  * 读取请求参数值的第一种方式: 
  4.  * 在处理方法里面,添加request作为方法的入参即可。前端控制器会将request对象作为参数传进来。 
  5. */  
  6. public String login(HttpServletRequest request){  
  7.     String username = request.getParameter("username");  
  8.     String pwd = request.getParameter("pwd");  
  9.     System.out.println("username:" + username + " pwd:" + pwd);  
  10.     return "index";  
  11. }  

方式二:入参与请求参一致

  将处理方法的入参与请求参数名保持一致。
  注: 如果不一致,可以使用@RequestParam(请求参数名)。

[java] view plain copy
  1. @RequestMapping("/login2.do")  
  2. /* 
  3.  * 读取请求参数值的第二种方式: 
  4.  * 将处理方法的入参与请求参数名保持一致。 
  5.  * 注:如果不一致,可以使用@RequestParam(请求参数名)。 
  6.  */  
  7. public String login2(String username,@RequestParam("pwd") String pwd1){  
  8.     System.out.println("username:" + username + " pwd:" + pwd1);  
  9.     return "index";  
  10. }  

方式三:Javabean方式

  将请求参数封装成一个javabean。 

  注: 该类有如下要求:
   a. 类的属性与请求参数名保持一致 (名称一样,类型一致)
   b. 这些属性应该提供相应的get/set方法。

[java] view plain copy
  1. @RequestMapping("/login3.do")  
  2. /* 
  3.  * 读取请求参数值的第三种方式: 
  4.  * 将请求参数封装成一个javabean。 
  5.  */  
  6. public String login3(User user){  
  7.     System.out.println("username:" + user.getUsername() + " pwd:" + user.getPwd());  
  8.     return "index";  
  9. }  
向页面传值:

 方式一:通过ModelAndView

   a.处理方法的返回值类型设置为ModelAndView。
   b.将处理结果添加到Map对象里面。
   c.构造ModelAndView对象。

[java] view plain copy
  1. @RequestMapping("/login4.do")  
  2. /* 
  3.  * 向页面传值的第一种方式:通过ModelAndView。 
  4.  * 将处理方法的返回值类型设置为ModelAndView。 
  5. */  
  6. public ModelAndView login4(User user){  
  7.     System.out.println(user.getUsername() + ":" + user.getPwd());  
  8.     /* 
  9.      * ModelAndView(String viewName,Map data); 
  10.      * viewName:视图名。 
  11.      * data:处理结果。 
  12.     */  
  13.     //将处理结果封装成一个Map对象。  
  14.     Map<String,Object> data = new HashMap<String,Object>();  
  15.     //相当于执行了request.setAttribute  
  16.     data.put("username", user.getUsername());  
  17.     data.put("user", user);  
  18.     ModelAndView mav = new ModelAndView("index",data);  
  19.     return mav;  
  20. }  

 方式二: 通过ModelMap

   a.要将ModelMap对象作为方法的入参。

   b.将处理结果添加到ModelMap。

[java] view plain copy
  1. @RequestMapping("/login5.do")  
  2. /* 
  3.  * 向页面传值的第二种方式: 
  4.  * 通过ModelMap对象。要将ModelMap对象作为方法的入参。 
  5. */  
  6. public String login5(User user,ModelMap mm){  
  7.     System.out.println(user.getUsername() + ":" + user.getPwd());  
  8.     //将处理结果添加到ModelMap。  
  9.     //相当于request.setAttribute  
  10.     mm.addAttribute("user", user);  
  11.     return "index";  
  12. }  

 方式三: 通过request

   a.将Http ServletRequest作为方法的入参。

   b. 将参数的值设置到request中。

[java] view plain copy
  1. @RequestMapping("/login6.do")  
  2. /* 
  3.  * 向页面传值的第三种方式:使用request。 
  4. */  
  5. public String login6(HttpServletRequest request){  
  6.     String username = request.getParameter("username");  
  7.     request.setAttribute("username", username);  
  8.     return "index";  
  9. }  

 方式四:通过session

   a.将HttpSession作为方法的入参。

   b.将参数封装的对象存入session。

[java] view plain copy
  1. @RequestMapping("/login7.do")  
  2. /* 
  3.  * 向页面传值的第四种方式:使用session。 
  4. */  
  5. public String login7(User user,HttpSession session){  
  6.     System.out.println(user.getUsername());  
  7.     session.setAttribute("user", user);  
  8.     return "index";  
  9. }  
重定向:
 1. 处理方法的返回值是String:

     return "redirect:toIndex.do";

[java] view plain copy
  1. @RequestMapping("/login8.do")  
  2. /* 
  3.  * 重定向的第一种方式: 
  4.  * 如果处理方法的返回值是String,则在重定向地址前添加"redirect:"作为前缀。 
  5. */  
  6. public String login8(User user){  
  7.     System.out.println(user.getUsername());  
  8.     return "redirect:toIndex.do";  
  9. }  

 2. 处理方法的返回值是ModelAndView:

     RedirectView rv = newRedirectView("toIndex.do");
     ModelAndView mav = new ModelAndView(rv);

[java] view plain copy
  1. @RequestMapping("/login9.do")  
  2. /* 
  3.  * 重定向的第二种方式: 
  4.  * 如果处理方法的返回值是ModelAndView。 
  5. */  
  6. public ModelAndView login9(User user){  
  7.     RedirectView rv = new RedirectView("toIndex.do");  
  8.     ModelAndView mav = new ModelAndView(rv);  
  9.     return mav;  
  10. }  

中文参数值如何处理:

 只需要配置springmvc提供的一个过滤器(CharacterEncodingFilter)。

   a.表单必须以post方式提交。
   b.表单所在的页面的编码与配置文件中的编码一致。

[html] view plain copy
  1. <filter>  
  2.    <filter-name>encodingFilter</filter-name>  
  3.    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  4.    <init-param>  
  5.     <param-name>encoding</param-name>  
  6.     <param-value>UTF-8</param-value>  
  7.    </init-param>  
  8. </filter>  
  9. <filter-mapping>  
  10.    <filter-name>encodingFilter</filter-name>  
  11.    <url-pattern>/*</url-pattern>  
  12. </filter-mapping>  

拦截器:

什么是拦截器:

 是springmvc提供的一个组件,前端控制器会先调用拦截器 ,然后再调用处理器。

如何编写一个拦截器:

 step1, 写一个java类,实现HandlerInterceptor接口。
 step2, 将拦截处理逻辑写在对应的方法里。
    preHandle方法: 前端控制器先调用拦截器的preHandle方法,再调用处理器的处理方法。如果该方法的返回值为true,表示继续向后调用。
    postHandle方法:处理器的方法已经执行完毕,在将ModelAndView返回给前端控制器之前执行该方法。所以,可以在该方法里面修改 ModelAndView。
    afterCompletion方法:最后执行的方法。
 step3,配置拦截器(spring配置文件)。

[html] view plain copy
  1. <!-- 配置拦截器:  
  2.      配置拦截器可以在interceptors下面配置多个拦截器, 拦截器的执行的先后顺序由配置的先后顺序来决定。   
  3.      注意:如果要拦截多层路径,比如"/abc/hello2.do",应该使用 /**。  
  4.  -->  
  5. <mvc:interceptors>  
  6.    <mvc:interceptor>  
  7.     <mvc:mapping path="/**"/>  
  8.     <!-- 排除登录相关的请求 -->  
  9.     <mvc:exclude-mapping path="/toLogin.do"/>  
  10.     <mvc:exclude-mapping path="/login.do"/>  
  11.     <bean class="com.tarena.oss.interceptors.SessionInterceptor"/>  
  12.    </mvc:interceptor>  
  13. </mvc:interceptors>  

让Spring来处理异常:

方式一:配置简单异常处理器

    只适合简单的异常处理。

[html] view plain copy
  1. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">   
  2.    <property name="exceptionMappings">   
  3.     <props>   
  4.        <prop key="java.lang.NumberFormatException">error1</prop>   
  5.        <prop key="java.lang.StringIndexOutOfBoundsException">error2</prop>   
  6.     </props>   
  7.    </property>   
  8. </bean>  

方式二:使用@ExceptionHandler  

    step1. 添加一个异常处理方法,该方法需要使用@ExceptionHander 修饰。
    step2.在异常处理方法内部,依据异常类型分别采取不同的处理。

[java] view plain copy
  1. @ExceptionHandler  
  2. /* 
  3.  * 这是一个异常处理方法,用来处理其它方法所抛出的异常。 
  4.  * ex:其它方法所抛出的异常。 
  5.  */  
  6. public String execute(HttpServletRequest request,Exception ex){  
  7.    //依据异常类型,分别做不同的处理。  
  8.    if(ex instanceof NumberFormatException){  
  9.     request.setAttribute("msg","请输入数字");  
  10.     return "error2";  
  11.    }else if(ex instanceof StringIndexOutOfBoundsException){  
  12.     request.setAttribute("msg","数组越界");  
  13.     return "error2";  
  14.    }  
  15.    return "error3";  
  16. }  
Spring jdbc

Spring jdbc 是什么:

  spring对jdbc API的简单的封装,使用spring jdbc 访问数据库,代码会比直接使用jdbc要简洁。

编程步骤:

  step1. 导包 (springjdbc相关的jar文件)
     spring-webmvc,Oracle driver,dbcp,spring-jdbc,junit
  step2. 添加spring配置文件,配置JdbcTemplate。

     注:jdbcTemplate提供了很多常用的数据库操作方法。

[html] view plain copy
  1. <!-- 配置文件 -->  
  2.       
  3. <!-- 读取db.properties文件的内容 -->  
  4. <util:properties id="jdbc" location="classpath:db.properties" />  
  5. <!-- 配置DataSource -->  
  6. <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  7.    <property name="driverClassName" value="#{jdbc.driver}" />  
  8.    <property name="url" value="#{jdbc.url}" />  
  9.    <property name="username" value="#{jdbc.user}" />  
  10.    <property name="password" value="#{jdbc.pwd}" />  
  11. </bean>  
  12. <!-- 配置JdbcTemplate -->  
  13. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  14.    <property name="dataSource" ref="ds"/>  
  15. </bean>  
  step3. 调用jdbcTempate提供的方法来访问数据库。

[java] view plain copy
  1. /** 
  2.  * jdbc的增删改查操作  
  3.  */  
  4. @Repository("empDAO")  
  5. public class EmpDAOJdbcImpl implements EmpDAO {  
  6.     @Resource(name="jdbcTemplate")  
  7.     //注入jdbcTempate对象。  
  8.     private JdbcTemplate jt;  
  9.       
  10.     /** 
  11.      * jdbcTempate会将底层的异常统一转换成RuntimeException,然后抛出。 
  12.      */  
  13.     public void save(Emp emp) {  
  14.         jt.update("INSERT INTO emp VALUES(emp_seq.nextval,?,?)",   
  15.         new Object[]{emp.getName(),emp.getAge()});  
  16.     }  
  17.       
  18.     public List<Emp> findAll() {  
  19.         List<Emp> emps = new ArrayList<Emp>();  
  20.         String sql = "SELECT * FROM emp";  
  21.         emps = jt.query(sql, new EmpRowMapper());  
  22.         return emps;  
  23.     }  
  24.       
  25.     /** 
  26.      * queryForObject方法:如果找不到记录,会抛出异常。 
  27.      */  
  28.     public Emp findById(int id) {  
  29.         Emp emp = null;  
  30.         String sql = "SELECT * FROM emp WHERE id=?";  
  31.         Object[] params = new Object[]{id};  
  32.         List<Emp> emps = jt.query(sql, params,new EmpRowMapper());  
  33.         if(emps != null && emps.size() > 0){  
  34.             emp = emps.get(0);  
  35.         }  
  36.         return emp;  
  37.     }  
  38.   
  39.     public void update(Emp emp) {  
  40.         String sql = "UPDATE emp "  
  41.                 + "SET name=?,age=? "  
  42.                 + "WHERE id=?";  
  43.         Object[] params = new Object[]{  
  44.                 emp.getName(),  
  45.                 emp.getAge(),  
  46.                 emp.getId()  
  47.             };  
  48.         jt.update(sql, params);  
  49.     }  
  50.   
  51.     public void delete(int id) {  
  52.         String sql = "DELETE FROM emp WHERE id=?";  
  53.         Object[] params = new Object[]{id};  
  54.         jt.update(sql, params);  
  55.     }  
  56.   
  57.     //获得总的记录数  
  58.     public int getTotal() {  
  59.         String sql = "SELECT count(*) FROM emp";  
  60.         return jt.queryForObject(sql, Integer.class);  
  61.     }  
  62.       
  63.     /* 
  64.      * 写一个内部类,该类的作用是将ResultSet转换成相应的实体对象。 
  65.      */  
  66.     class EmpRowMapper implements RowMapper<Emp> {  
  67.         /* 
  68.          * rs:要遍历的ResultSet。 
  69.          * index:第几条记录。 
  70.          */  
  71.         public Emp mapRow(ResultSet rs,int index) throws SQLException {  
  72.             Emp emp = new Emp();  
  73.             emp.setName(rs.getString("name"));  
  74.             emp.setAge(rs.getInt("age"));  
  75.             emp.setId(rs.getInt("id"));  
  76.             return emp;  
  77.         }  
  78.     }  
  79. }  

MyBatis:

什么是MyBatis:

  是一个开源的持久层框架,它对jdbc做了简单的封装。

如何使用MyBatis:

  step1. 导包。
  step2. 添加配置文件。
   注:配置文件主要提供以下信息
     a.数据库的连接信息。
     b.映射文件的位置。

[html] view plain copy
  1. <!-- 数据库的连接信息 -->   
  2. <configuration>  
  3.    <environments default="environment">  
  4.     <environment id="environment">  
  5.         <transactionManager type="JDBC" />  
  6.         <dataSource type="POOLED">  
  7.             <property name="driver" value="oracle.jdbc.OracleDriver" />  
  8.             <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />  
  9.             <property name="username" value="yuanxin" />  
  10.             <property name="password" value="123456" />  
  11.         </dataSource>  
  12.     </environment>  
  13.    </environments>  
  14.    <!-- 指定映射文件的位置 -->  
  15.    <mappers>  
  16.     <mapper resource="entity/EmpMapper.xml" />  
  17.    </mappers>  
  18. </configuration>  

  step3. 实体类。
   注:实体类的属性名一定要与表的字段名一致。原因:mybatis将查询出来的一条记录存放到一个Map对象里面,key是字段名, value是字段值。接下来,mybatis会依据字段名,调用实体对象对应的 set方法,完成赋值。注意:如果属性名与字段名不一致,可以在写sql时, 为字段名指定别名。
  step4. 写一个映射文件(sql语句)。

[html] view plain copy
  1. <mapper namespace="dao.EmpDAO">  
  2.     <!-- 插入记录。  
  3.          id属性:要求唯一。  
  4.          parameterType:要写完整的实体类类名。  
  5.      -->  
  6.     <insert id="save" parameterType="entity.Emp">  
  7.         INSERT INTO emp   
  8.         VALUES(emp_seq.nextval,#{name},#{age})  
  9.     </insert>  
  10.       
  11.     <!-- 查询记录。  
  12.          resultType属性:查询出来的记录要转换成相应的对象的类型。  
  13.      -->  
  14.      <select id="findAll" resultType="entity.Emp">  
  15.         SELECT * FROM emp  
  16.      </select>  
  17.        
  18.      <!-- 查询。  
  19.           parameterType:如果参数值是一个整数,官方用法是 java.lang.Integer,可以简写为"int"。  
  20.       -->  
  21.      <select id="findById"   
  22.         parameterType="int" resultType="entity.Emp">  
  23.         SELECT * FROM emp WHERE id = #{id1}  
  24.      </select>  
  25.        
  26.       
  27.     <!-- 返回Map类型的查询结果。java.util.Map 可以简写为map。 -->  
  28.     <select id="findById2" parameterType="int" resultType="map">  
  29.         SELECT * FROM emp WHERE id = #{id1}  
  30.     </select>  
  31. </mapper>  
   注:修改配置文件,将映射文件添加进来。
  step5. 使用MyBatis提供的API来访问数据库。
   添加: insert方法 
   查询(返回类型为List): selectList方法
   查询(返回单个对象): selectOne方法
   修改:update方法
   删除:delete方法
   注:这些方法都需要提供要操作的sql的id,id应该按照映射文件的设置来写,可以在id前添加相应的命名空间(比如test.findAll)。

[html] view plain copy
  1. public class TestCase {  
  2.       
  3.     private SqlSession session;  
  4.       
  5.     @Before  
  6.     //初始化方法。junit会在测试方法运行之前,先运行初始化方法。  
  7.     public void init(){  
  8.         SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();  
  9.         //创建SqlSessionFactory对象。  
  10.         SqlSessionFactory ssf = ssfb.build(TestCase.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));  
  11.         session = ssf.openSession();  
  12.     }  
  13.       
  14.     @Test  
  15.     public void test1(){  
  16.         Emp emp = new Emp();  
  17.         emp.setName("King");  
  18.         emp.setAge(20);  
  19.         /*  
  20.          * insert方法:插入记录。  
  21.          * 第一个参数是要执行的sql的id(id是在映射文件当中设置的),第二个参数是要插入的对象。  
  22.          */  
  23.         session.insert("save", emp);  
  24.         //要提交事务  
  25.         session.commit();  
  26.         //关闭(会关闭connection)  
  27.         session.close();  
  28.     }  
  29.       
  30.     @Test  
  31.     //测试查询(查询所有记录)  
  32.     public void test2(){  
  33.         List<Emp> emps = session.selectList("findAll");  
  34.         System.out.println(emps);  
  35.         session.close();  
  36.     }  
  37.       
  38.     @Test  
  39.     //测试查询(查询一条记录)  
  40.     public void test3(){  
  41.         Emp emp = session.selectOne("findById", 21);  
  42.         System.out.println(emp);  
  43.         session.close();  
  44.     }  
  45.       
  46.     @Test  
  47.     //修改记录  
  48.     public void test4(){  
  49.         Emp emp = session.selectOne("findById", 21);  
  50.         emp.setAge(emp.getAge() * 3);  
  51.         session.update("update", emp);  
  52.         session.commit();  
  53.         session.close();  
  54.     }  
  55.       
  56.     @Test  
  57.     //测试删除  
  58.     public void test5(){  
  59.         session.delete("delete", 21);  
  60.         session.commit();  
  61.         session.close();  
  62.     }  
  63.       
  64.     @Test  
  65.     //测试查询结果为map  
  66.     public void test6(){  
  67.         Map map = session.selectOne("findById2", 23);  
  68.         //oracle数据库默认会将字段名变成大写形式。  
  69.         System.out.println(map.get("NAME"));  
  70.         session.close();  
  71.     }  
  72. }  

工作原理:


使用Mapper映射器:

  mybatis会按照DAO接口(或者叫Mapper接口)定义,生成相应的DAO实现对象。
  注:
   a. 接口中的方法的名字与映射文件中的sqlId要一致。
   b. 接口中的方法的返回值类型、参数类型要与映射文件一致。
   c. 映射文件的命名空间要等于Mapper接口的完整的名字。
   d. 调用SqlSession提供的getMapper方法获得DAO实现对象。

[java] view plain copy
  1. public class TestCase2 {  
  2.       
  3.     private SqlSession session;  
  4.   
  5.     @Before  
  6.     public void init(){  
  7.         SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();  
  8.         SqlSessionFactory ssf = ssfb.build(TestCase.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));  
  9.         session = ssf.openSession();  
  10.     }  
  11.       
  12.     @Test  
  13.     public void test1(){  
  14.         //getMapper方法会按照Mapper接口要求,返回一个实现了该接口要求的对象。  
  15.         EmpDAO dao = session.getMapper(EmpDAO.class);  
  16.         System.out.println(dao.getClass().getName());  
  17.         Emp emp = new Emp();  
  18.         emp.setName("Eric");  
  19.         emp.setAge(22);  
  20.         dao.save(emp);  
  21.         //对于添加、修改、删除仍然需要提交事务。  
  22.         session.commit();  
  23.         session.close();  
  24.     }  
  25.       
  26.     @Test  
  27.     public void test2(){  
  28.         EmpDAO dao = session.getMapper(EmpDAO.class);  
  29.         List<Emp> emps = dao.findAll();  
  30.         System.out.println(emps);  
  31.         session.close();  
  32.     }  
  33.       
  34.     @Test  
  35.     public void test3(){  
  36.         EmpDAO dao = session.getMapper(EmpDAO.class);  
  37.         Emp2 emp2 = dao.findById3(22);  
  38.         System.out.println(emp2);  
  39.         session.close();  
  40.     }  
  41.       
  42. }  

使用resultMap解决实体类的属性名与表的字段名不一致的情况:

  step1.在映射文件当中,使用resultMap元素配置实体类的属性名与表的字段名的对应关系。

[html] view plain copy
  1. <!--使用resultMap来解决实体类的属性名与表的字段名不一致的情况。   
  2.     type属性:实体类的名字。   
  3.     property属性:实体类的属性名。   
  4.     column属性:表的字段名。   
  5.     注:如果属性名与字段名一样,就不用写了。 -->  
  6. <resultMap type="entity.Emp2" id="empRM">  
  7.    <result property="empNo" column="id" />  
  8.    <result property="eName" column="name" />  
  9. </resultMap>  
  10. <select id="findById3" parameterType="int" resultMap="empRM">  
  11.    SELECT *  
  12.    FROM emp WHERE id = #{id1}  
  13. </select>  

  step2.在Mapper接口当中,声明相应的接口方法。

[java] view plain copy
  1. public void save(Emp emp);  
  2. public List<Emp> findAll();  
  3. public Emp findById(int id);  
  4. public void update(Emp emp);  
  5. public void delete(int id);  
  6. public Map findById2(int id);  
  7. //属性名与表的字段名不一致的方法     
  8. public Emp2 findById3(int id);  

  step3.调用SqlSession.getMapper方法。

Spring集成MyBatis:

编程步骤:

 step1. 导包。

   包:spring mvc(3.2.8),spring jdbc(3.2.8) dbcp(1.4),oracle driver(ojdbc14),junit(4.12), mybatis(3.2.5),mybatis-spring(1.2.2)
 step2.配置文件。
   注:只需要spring配置文件(mybatis的配置文件中的配置信息放到了spring的配置文件里面)。
 step3.实体类
 step4.映射文件
 step5.Mapper接口
 step6.修改spring配置文件,添加:
  a.SqlSessionFactoryBean
     负责创建SqlSessionFactory对象。需要为该对象注入DataSource,映射文件的位置。

  b.MapperScannerConfigurer
     负责生成符合Mapper接口要求的对象,并将这些对象添加 到spring容器里面(对象的id是Mapper接口名首字母小写)。
     注: 可以为该对象设置annotationClass属性,其作用是,只扫描 带有特定注解的Mapper接口。

[html] view plain copy
  1. <!-- 读取db.properties文件的内容 -->  
  2. <util:properties id="jdbc" location="classpath:db.properties" />  
  3. <!-- 配置DataSource -->  
  4. <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  5.     <property name="driverClassName" value="#{jdbc.driver}" />  
  6.     <property name="url" value="#{jdbc.url}" />  
  7.     <property name="username" value="#{jdbc.user}" />  
  8.     <property name="password" value="#{jdbc.pwd}" />  
  9. </bean>  
  10. <!-- 配置SqlSessionFactoryBean -->  
  11. <bean class="org.mybatis.spring.SqlSessionFactoryBean">  
  12.     <!-- 注入DataSource -->  
  13.     <property name="dataSource" ref="ds" />  
  14.     <!-- 注入映射文件的位置信息 -->  
  15.     <property name="mapperLocations" value="classpath:entity/*.xml" />  
  16. </bean>  
  17. <!-- 配置MapperScannerConfigurer。 扫描指定包下面的所有的Mapper接口, 创建符合Mapper接口要求的对象,并且   
  18.      会将创建好的对象放到spring容器里面。 -->  
  19. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
  20.     <!-- 注入要扫描的包名 -->  
  21.     <property name="basePackage" value="dao" />  
  22. </bean>  
[java] view plain copy
  1. //测试类  
  2. public class TestCase {  
  3.       
  4.     private ApplicationContext ac = null;  
  5.       
  6.     @Before  
  7.     //@Before修饰的方法会在测试方法执行前先执行。  
  8.     public void init(){  
  9.         //启动spring容器。  
  10.         ac = new ClassPathXmlApplicationContext("app.xml");  
  11.     }  
  12.       
  13.     @Test  
  14.     public void test1(){  
  15.         //通过容器得到一个DAO对象。  
  16.         //bean的id是Mapper接口首字母小写。  
  17.         EmpDAO dao = ac.getBean("empDAO",EmpDAO.class);  
  18.         Emp emp = new Emp();  
  19.         emp.setName("kitty");  
  20.         emp.setAge(19);  
  21.         dao.save(emp);  
  22.     }  
  23. }  

使用SqlSessionTemplate:

 编程步骤:前面5步同上。
 step6.修改spring配置文件,添加:
  a.SqlSessionFactoryBean
     负责创建SqlSessionFactory对象。需要为该对象注入DataSource,映射文件的位置。
  b.配置SqlSessionTemplate

  c.配置组件扫描
 step7.写一个DAO类,注入SqlSessionTemplate。
   注:调用SqlSessionTempate方法即可。(类似于JdbcTemplate)。

[html] view plain copy
  1. <!-- 读取db.properties文件的内容 -->  
  2. <util:properties id="jdbc" location="classpath:db.properties" />  
  3. <!-- 配置DataSource -->  
  4. <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  5.     <property name="driverClassName" value="#{jdbc.driver}" />  
  6.     <property name="url" value="#{jdbc.url}" />  
  7.     <property name="username" value="#{jdbc.user}" />  
  8.     <property name="password" value="#{jdbc.pwd}" />  
  9. </bean>  
  10. <!-- 配置SqlSessionFactoryBean -->  
  11. <bean id="ssfb" class="org.mybatis.spring.SqlSessionFactoryBean">  
  12.     <!-- 注入DataSource -->  
  13.     <property name="dataSource" ref="ds" />  
  14.     <!-- 注入映射文件的位置信息 -->  
  15.     <property name="mapperLocations" value="classpath:entity/*.xml" />  
  16. </bean>  
  17. <!-- 配置SqlSessionTemplate -->  
  18. <bean id="sst" class="org.mybatis.spring.SqlSessionTemplate">  
  19.     <constructor-arg index="0" ref="ssfb" />  
  20. </bean>  
  21. <!-- 配置组件扫描 -->  
  22. <context:component-scan base-package="dao" />  
[java] view plain copy
  1. /** 
  2.  * 使用MyBatis提供的SqlSessionTemplate来访问数据库。 
  3.  */  
  4. @Repository("empDAO")  
  5. public class EmpDAOMybatisImpl implements EmpDAO {  
  6.       
  7.     @Resource(name="sst")  
  8.     //Resource注解来自于javaee(javax.annotation)  
  9.     private SqlSessionTemplate sst;  
  10.       
  11.     public void save(Emp emp) {  
  12.         sst.insert("save", emp);  
  13.     }  
  14.   
  15.     public List<Emp> findAll() {  
  16.         return sst.selectList("findAll");  
  17.     }  
  18.   
  19.     public Emp findById(int id) {  
  20.         return sst.selectOne("findById", id);  
  21.     }  
  22.   
  23.     public void update(Emp emp) {  
  24.         sst.update("update", emp);  
  25.     }  
  26.   
  27.     public void delete(int id) {  
  28.         sst.delete("delete", id);  
  29.     }  
  30.   
  31.     public Emp2 findById3(int id) {  
  32.         return sst.selectOne("findById3",id);  
  33.     }  
  34. }  
登录(Spring+MyBatis):

 step1. 导包
 spring mvc,mybatis,mybatis-spring, driver,dbcp,junit,spring-jdbc
 step2. 配置文件 (spring配置文件)
 step3. 配置前端控制器(web.xml)
 step4. 实体类 (Admin)
 step5. 映射文件 (AdminMapper.xml)
   注意:实体类的属性名如果与表的字段表不一致,应该用别名。
 step6.修改配置文件
   添加: datasource,SqlSessionFactoryBean。
   注意:SqlSessionFactoryBean应该指定映射文件的位置。 

 step7. AdminDAO接口
   注意:应该与映射文件保持一致。检查一下映射文件的namespace 是否等于AdminDAO接口的完整类名。
 step8. 修改配置文件
   添加:MapperScannerConfigurer。
   注意:指定要扫描的包名。

Ajax(aschronous javascript and xml:异步的js和xml):
是一种用来改善"用户体验"的技术,其实质是利用浏览器内置的一个对象 (ajax对象)异步地向服务器发送请求。服务器送回部分数据,浏览器利用这些数据对当前页面做部分更新。整个过程,页面无刷新,不打断用户的操作。
注:
异步:指的是当ajax对象向服务器发送请求时,浏览器不会销毁当前页面,用户仍然可以对当前页面做其它的操作。

部分数据:一般不需要返回完整的页面。一般是以文本或者xml的形式返回。


如何获得ajax对象:

 要区分浏览器。

[html] view plain copy
  1. function getXhr(){  
  2. <span style="white-space:pre">  </span>var xhr = null;  
  3.     if(window.XMLHttpRequest){  
  4.         //非ie浏览器  
  5.         xhr = new XMLHttpRequest();  
  6.     }else{  
  7.         //ie浏览器  
  8.         xhr = new ActiveXObject("MicroSoft.XMLHttp");  
  9.     }  
  10.     return xhr;  
  11. }  
Ajax对象的几个重要属性:

 a. onreadystatechange: 绑定事件处理函数(处理readystatechange 事件)。
     注:当ajax对象的readyState的值发生了任何的改变(比如从0变成了1) ,就会产生readystatechange事件。
 b. readyState: 有5个值(0,1,2,3,4),表示ajax对象与服务器通信的状态。4表示ajax对象已经获取了服务器返回的所有的数据。
 c. responseText:服务器返回的文本数据。
 d. responseXML:服务器返回的xml数据。 
 e. status:服务器返回的状态码。

编程步骤:

 step1. 获取ajax对象。
   比如: var xhr = getXhr(); 
 step2. 利用ajax对象发请求。
   发送get请求:xhr.open('get','check_username.do?username=Tom',true);
                       xhr.onreadystatechange=f1; xhr.send(null); 

   注:第一个参数:请求方式。
       第二个参数: 请求地址,如果是get请求,请求参数要添加到请求地址后面。
       第三个参数:如果值是true,表示异步。如果值是false,表示同步( 浏览器会锁定当前页面)。

 step3. 编写服务器端代码。
 step4. 编写事件处理函数。
   比如:if(xhr.readyState == 4 && xhr.status == 200){ var txt =xhr.responseText; 更新页面... }

[html] view plain copy
  1. //利用ajax对象异步地向服务器发送请求,  
  2. //并且利用服务器返回的数据更新当前页面。  
  3. function check_uname(){  
  4.    //step1. 获得ajax对象。  
  5.    var xhr = getXhr();  
  6.    //step2. 利用ajax对象发请求。  
  7.    var uri = 'check_uname.do?username=' + $F('username');  
  8.    //encodeURI函数会检查uri中的字符,如果  
  9.    //是非ASCII字符,都会统一使用utf-8来编码。  
  10.    xhr.open('get',encodeURI(uri),true);  
  11.    xhr.onreadystatechange=function(){  
  12.      //step4. 处理服务器返回的数据  
  13.      if(xhr.readyState == 4 && xhr.status == 200){  
  14.         //获得服务器返回的数据  
  15.         var txt = xhr.responseText;  
  16.         //更新页面  
  17.         $('username_msg').innerHTML = txt;  
  18.      }  
  19.    };  
  20.    xhr.send(null);  
  21. }  

发送post请求:

 注:

  a. 请求参数放到send方法里面。
  b. 按照http协议,如果发送的是post请求,应该提供一个 'content-type'消息头。但是,默认情况下,ajax对象并不 会提供这样一个消息头。

[html] view plain copy
  1. function check_uname(){  
  2.    //step1. 获得ajax对象  
  3.    var xhr = getXhr();  
  4.    //step2. 利用ajax对象发请求  
  5.    xhr.open('post','check_uname.do',true);  
  6.    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');  
  7.    xhr.onreadystatechange=function(){  
  8.      //step4. 处理服务器返回的数据  
  9.      if(xhr.readyState == 4 && xhr.status == 200){  
  10.      var txt = xhr.responseText;  
  11.      $('username_msg').innerHTML = txt;  
  12.       }  
  13.    };  
  14.    xhr.send('username=' + $F('username'));  
  15. }  
处理ajax应用中的乱码问题:

 1. post请求:

     a. 乱码原因:浏览器提供的ajax对象在发送post请求时,会对中文参数使用utf-8 来编码,而服务器端默认会使用iso-8859-1来解码。

     b. 解决方案:request.setCharacterEncoding("utf-8");

 2. get请求:

     a. 乱码原因:IE提供的ajax对象在发送get请求时,会对中文参数使用gbk来编码,而其它浏览器会使用utf-8来编码。服务器端默认会使用iso-8859-1来解码。

     b. 解决方案:

         step1. 修改服务器端的配置,使用指定的字符集来解码。 比如,修改tomcat的server.xml,添加URIEncoding=utf-8。

                    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>

         step2. 可以使用encodeURI函数对中文参数来编码(该函数会使用utf-8来编码)。

json(javascript object notation:js对象声明):

json是什么:

 一种轻量级的数据交换格式。
 注:
  a. 数据交换:将数据转换成一种与平台无关的数据格式(比如xml),然后发送给接收方来处理。
  b.轻量级:相对于xml,json的文档更小,解析速度更快。

语法:

  a. 表示一个对象
   {属性名:属性值,属性名:属性值...}
   注意:
     -属性名必须使用双引号括起来。
     -属性值可以是string,number,true/false,null,object。
     -属性值如果是string,必须使用双引号括起来。
   比如:{"code":"600015","name":"山东高速","price":10} 
  b.表示一个由对象组成的数组。
    [{},{},{}....]

如何将java对象转换成json字符串:

 通过使用json官方提供的工具(比如json-lib),也可以使用其它组织或者公司提供的工具(比如google提供的工具),把对象/对象数组集合转化成json字符串;ajax会将服务器返回的json字符串自动转换成相应的js对象或者js对象组成的数组。
 JSONObject: 单个对象的转换。
 JSONArray:对象组成的集合或者数组的转换。

jQuery对ajax技术的支持:

$.ajax():

用法:$.ajax({});
注:{}是一个描述选项参数的对象,常用的选项参数有以下这些:
 url: 请求地址 (比如 check_uname.do)
 data:请求参数(有两种格式,第一种格式是请求字符串的形式,比如'username=Tom&age=22';第二种格式是对象的形式,比如{'username':'Tom','age':22})。
 type:请求方式 (比如get/post)
 dataType: 指定服务器返回的数据类型。常见的有:
    text: 文本。
    html: html文本。
    json: json字符串。
    xml: xml文本。
    script: JavaScript脚本。
 success:是一个函数,用来处理服务器返回的数据。
 error:是一个函数,用来处理服务器返回的异常。

load函数:

作用:异步地向服务器发送请求,并且将服务器返回的数据直接添加到符合要求的节点之上。
用法:$obj.load(url,[data]);
注:
  $obj:要操作的节点。
  url:请求地址。
  data:请求参数(格式同上)。

------------------------------------------------------------------------------------------------------


原创粉丝点击