内容简述:Spring简介、Spring容器、Spring IOC/DI、Spring 五大组件、Spring MVC、Spring JDBC、MyBatis、AJAX。
一、Spring简介、Spring容器
1. Spring是什么?
- 开源的,用来简化企业级应用开发的应用开发框架。
(1)简化开发
- Spring对常用的api(比如jdbc) 做了封装,这样,可以大大简化这些api的使用。(比如使用springjdbc访问数据库,就不用考虑如何获取连接和关闭连接了)。
(2)解耦
- Spring帮我们建立对象之间的依赖关系,这样,对象之间的耦合度会大大降低,代码的维护性会大大提高。(代码要求:高内聚(类的功能要单一),低耦合。)
(3)集成其它框架
Spring可以将其它的一些框架集成进来(比如用于定时任务处理的Quartz框架等),方便这些框架的使用。
(因为spring可以集成其他框架,所以spring又叫做一站式框架)
2.Spring容器
(1)什么是Spring容器?
- Spring框架中的一个核心模块,用于管理对象。
(2)启动Spring容器
step1.导包。
spring-webmvc(org.springframework),junit
step2. 添加spring配置文件。
step3. 启动容器。
1 | String config = "applicationcontext.xml"; |
(3)创建对象
1)方式一: 无参构造器
step1. 为类添加无参构造器(或者缺省构造器)
step2. 在配置文件里面,添加bean元素。(注意:与javabean无关)
注:bean就是容器所创建的对象。
step3. 启动容器,调用容器的getBean方法。
1 | <!-- 使用无参构造器创建对象 --> |
- 2)方式二: 静态工厂方法 (了解)
1 | <!-- 使用静态工厂方法创建对象 --> |
- 3)方式三: 实例工厂方法(了解)
1 | <!-- 使用实例工厂方法创建对象 --> |
(4)作用域
1)默认情况下,容器对于每个bean元素,只会创建一个实例。
2)如果将作用域设置为”prototype”,则每调用一次getBean方法,就会创建一个新的实例。
1 | <!-- 指定作用域 --> |
(5)延迟加载 (了解)
1)默认情况下,容器启动之后,会将作用域为”singleton”的bean创建好。
2)延迟加载指的是,容器启动之后,对作用域为”singleton”的bean不再创建,直到调用了getBean方法才会创建。
(6)生命周期
- 1)初始化方法
- 容器创建好bean的实例之后,会立即调用初始化方法。
- 2)销毁方法
- 容器关闭之前,会调用销毁方法。
1 | <!-- 指定初始化方法和销毁方法 --> |
二、Spring IOC、参数值注入
1. IOC/DI
(1)IOC(Inversion Of Controll 控制反转)
- 对象之间的依赖关系由容器来建立。
(2)DI(Dependency Injection 依赖注入
- 容器可以通过调用set方法或者构造器来建立对象之间的依赖关系。
总结: IOC是目标,DI是手段。
(3)依赖注入的两种方式
- 1)方式一: set方法注入
- step1. 添加set方法;
- step2. 在配置文件中,使用<property>元素来配置。
1 | <bean id="b1" class="ioc.B"/> |
- 2)方式二: 构造器注入
- step1. 添加构造器;
- step2. 在配置文件当中,使用<constructor-arg>元素来配置。
1 | <!-- 构造器注入 --> |
(4)自动装配
自动装配,指的是容器依据某些规则,自动建立对象之间的依赖关系。
(底层仍然是需要调用set方法或者构造器)
1)默认情况下,容器不会自动装配。
2)设置autowire属性
autowire: 表示让容器自动建立对象之间的依赖关系。
byName: 依据属性名查找对应的bean(就是以属性名作为bean的id来查找),找到之后,调用set方法来建立依赖关系。
注:如果找不到,则不注入。
byType: 依据属性类型来查找对应的bean,找到之后,调用set方法来建立依赖关系。
注:如果找到多个,则会出错。
constructor: 与byType类似,只不过,调用构造器来注入。
(5)注入基本类型的值
- 使用value属性来注入,spring容器会帮我们做一些类型的转换工作,比如将字符串转换成数字。
(6)注入集合类型的值 (List,Set,Map,Properties)
方式一: 直接注入
注:list的value值可以重复,set的value值不可以重复(重复的话只存一遍)。
xml代码
1 | <list> |
java代码
1 | public class ValueBean { |
注意:Properties是键值对,值只能是字符串
- 方式二: 引用的方式注入
- step1. 将集合类型的值先配置成一个bean。
- step2. 再将这个bean注入到对应的bean里面。
1 | <util:list id="interestBean"> |
注意:util是命名空间,namespace,是为了区分同名的元素而添加的限定
(7)读取.properties文件的内容
1 | <!-- 读取.properties文件的内容 --> |
文件位置:
文件内容:
测试:
1 |
|
结果:
三、基于注解的组件扫描、SpringMVC、五大组件
注意:javaBean和bean一点关系都没有。
(8)spring表达式
- 读取bean的属性
1.使用注解来简化配置文件
(1)什么是组件扫描?
- 容器会扫描指定的包及其子包下面的所有的类,如果该类前面有特定的注解比如@Component),则容器会将其纳入容器进行管理(相当于在配置文件里面有一个bean元素)。
(2)如何进行组件扫描?
step1. 在类前面添加特定的注解,比如 @Component
(注:默认的id是首字母小写之后的类名。)
- step2. 在配置文件当中,配置组件扫描。
(3)依赖注入相关的注解
1)@Autowired @Qualifier–(依赖于spring,@Autowired先根据类型查找(byType,byType默认使用set方法注入),如果找到一个接口下面有多个实现,则再根据名称查找(byName,或者直接使用@Qualifier实现byName方式),如果还找不到就会抛出异常)
(注:该注解支持set方法和构造器注入。)
注意:@Autowired不需要手动显式地声明set方法和构造器方法。
注意:
- bean配置文件中的set注入和构造器注入指的是将容器中创建好的bean实例通过set方法和构造器方法注入到相应的属性中;
- @Autowired,@Resource注解是将容器中创建好的bean实例直接注入到相应的变量中,然后调用修饰的方法给类的属性赋值。其中,@Autowired支持修饰set方法和构造器方法,@Resource只支持修饰set方法。
2)@Resource–(依赖于javaee,包为javax.annotation-api-1.2.jar)
(设定项目tomcat依赖的时候会自动导入)
(注:该注解只支持set方法注入。)
(4)注入基本类型的值和spring表达式的值
SpringMVC
(1)什么是SpringMVC?
用来简化基于MVC架构的web应用程序开发的框架。
(注:SpringMVC是spring中的一个模块。)
(2)五大组件
1)有哪五大组件?
- DispatcherServlet 前端控制器(在web.xml文件中配置)
- HandlerMapping 映射处理器(在Spring配置文件中配置)
- Controller 处理器(在Spring配置文件中配置+代码实现)
- ModelAndView 处理结果和视图名(在Spring配置文件中配置)
- ViewResolver 视图解析器
2)它们之间的关系
a.请求发送给DispatcherServlet来处理,DispatcherServlet会依据HandlerMapping的配置调用对应的Controller来处理。
b.Controller将处理结果封装成ModelAndView对象,然后返回给DispatcherServlet。
c.DispatcherServlet会依据ViewResolver的解析调用对应的视图对象(比如jsp)来生成相应的页面。
(注:视图部分可以使用jsp,也可以使用其它的视图技术,比如 freemarker,velocity 等等。)
(3)编程步骤
- step1. 导包 spring-webmvc
- step2. 添加配置文件。
- step3. 配置DispatcherServlet。
- step4. 写Controller。
- step5. 写jsp。
- step6.在配置文件当中,添加HandlerMapping, ViewResolver的配置。
1 | <!-- 配置HandlerMapping映射处理器 --> |
练习: http://localhost:8080/springmvc-lab/toLogin.do 返回一登录页面。
四、SpringMVC应用
1. 基于注解的SpringMVC应用
(1)编程步骤
- step1.导包 spring-webmvc
- step2.添加spring配置文件。
- step3.配置DispatcherServlet。
- step4.写Controller
- 1.不用实现Controller接口;
- 2.方法签名不做要求,返回值可以是ModelAndView,也可以是String;
- 3.可以添加多个方法;
- 4.使用@Controller;
- 5.可以在方法前或者类前添加@RequestMapping,相当于HandlerMapping。
- step5.写jsp
- step6.在配置文件当中,添加ViewResolver配置,添加组件扫描,添加MVC注解扫描。
1 | <!-- 配置组件扫描 --> |
注意:需要添加相应的注解,比如@RequestMapping,MVC注解扫描才会扫描到。
(2)读取请求参数值
- 1)方式一:通过request提供的方法
1 | public String login(HttpServletRequest request){ |
- 2)方式二:通过@RequestParam注解
1 | public String login2(String adminCode, @RequestParam("pwd")String password){ |
3)方式三:通过javabean
step1. 先写一个java类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/**
* 用于封装请求参数值,属性名与请求参数名一致
* 注:
* 名称要一样,类型要匹配
* (数字会自动进行相应的类型转换,比如将String转换成int)
* 提供相应的get/set方法
* @author ACGkaka
*/
public class AdminParam {
private String adminCode;
private String pwd;
private int phone;
public int getPhone(){
return phone;
}
public void setPhone(int phone){
this.phone = phone;
}
public String getAdminCode(){
return adminCode;
}
public void setAdminCode(String adminCode){
this.adminCode = adminCode;
}
public String getPwd(){
return pwd;
}
public void setPwd(String pwd){
this.pwd = pwd;
}
}step2. 将该类作为方法参数
1
2
3
4
5public String login3(AdminParam ap){
System.out.println("login3()");
System.out.println("adminCode:" + ap.getAdminCode());
return "index";
}
(3)向页面传值
1)方式一:将数据绑订到request
1
2
3
4
5
6
7
8
9"/login4.do") (
public String login4(AdminParam ap,HttpServletRequest request){
System.out.println("login4()");
String adminCode=ap.getAdminCode();
request.setAttribute("adminCode", adminCode);
//默认情况下,DispatcherServlet
//会使用转发。
return "index";
}2)方式二:返回ModelAndView
1
2
3
4
5
6
7
8
9
10
11
12"/login5.do") (
public ModelAndView login5(AdminParam ap){
System.out.println("login5()");
String adminCode=ap.getAdminCode();
//step1.将数据添加到一个Map对象里面
Map<String,Object> data=new HashMap<String, Object>();
//相当于执行了request.setAttribute
data.put("adminCode", adminCode);
//step2.将Map对象添加到ModelAndView中
ModelAndView mav=new ModelAndView("index",data);
return mav;
}3)方式三:将数据添加到ModelMap
1
2
3
4
5
6
7"/login6.do") (
public String login6(AdminParam ap,ModelMap mm){
System.out.println("login6()");
String adminCode=ap.getAdminCode();
mm.addAttribute("adminCode",adminCode);
return "index";
}4)方式四:将数据绑订到session
1
2
3
4
5
6
7"/login7.do") (
public String login7(AdminParam ap,HttpSession session){
System.out.println("login7()");
String adminCode=ap.getAdminCode();
session.setAttribute("adminCode", adminCode);
return "index";
}
(4)重定向
1)方法的返回值是String,比如: return “redirect:toIndex.do”;
1
2
3
4
5
6
7
8
9
10
11"/login8.do") (
public String login8(){
System.out.println("login8()");
return "redirect:toIndex.do";
}
"/toIndex.do") (
public String toIndex(){
System.out.println("toIndex()");
return "index";
}2)方法的返回值是ModelAndView,比如:
1
2
3
4
5
6
7"/login9.do") (
public ModelAndView login9(){
System.out.println("login9()");
RedirectView rv=new RedirectView("toIndex.do");
ModelAndView mav=new ModelAndView(rv);
return mav;
}
五、系统分层、登录案例
1.系统分层
(1)为什么要分层?
- 为了系统好维护,系统的设计应该要做到“高内聚,低耦合”。
- “高内聚”:指的是类的职责要单一,这样,一个类就可以会拆分成多个类(比如AccountService拆分成了AccountService和AccountDAO),这样,就形成了分层的概念。
- “低耦合”:指的是类与类之间不要直接依赖。(AccountService要调用AccountDAO,应该使用依赖注入)。
(2)如何分层?
表示层:数据展现和操作界面,以及请求分发。(Controller)
业务层:封装了业务逻辑。 (Service)
持久层: 封装了数据访问逻辑。(DAO)
注:表示层调用业务层,业务层调用持久层。上一层通过接口来调用下一层提供的服务(这样,下一层的实现发生了改变,不影响上一层)。
六、中文乱码处理、拦截器、Spring处理异常
1. 表单包含有中文参数值,如何读取?
- springmvc提供了一个过滤器(CharacterEncodingFilter),只需要配置该过滤器即可。
注意:
a. 表单的提交方式必须是”post”。
b. 编码与浏览器端的一致。
2.拦截器
(1)什么是拦截器?
- DispatcherServlet收到请求之后,如果有拦截器,会先调用拦截器,然后再调用Controller。
补充:过滤器属于servlet规范,而拦截器属于spring框架。
(2)如何写一个拦截器?
step1. 写一个java类,实现HandlerInterceptor接口。
step2. 在接口方法里面,实现拦截处理逻辑。
step3. 配置拦截器。
面试题:过滤器和拦截器在验证登录功能方面有什么区别?
- 过滤器更通用一些,拦截器是依赖于spring框架的!
面试题:过滤器和拦截器的区别?
1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖于servlet容器,而拦截器依赖于Spring容器
3、Filter是Servlet规范固定的,只能用于Web程序中,而拦截器既可以用户Web程序,也可以用于Application、Swing程序中
4、Filter在只在Servlet启动前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用弹性更大一些,所以在使用Spring架构的程序中,要优先使用拦截器。
5、过滤器和拦截器触发时机不一样,过滤器是在【请求进入容器后,但请求进入servlet之前】进行预处理的。请求结束返回也是,是【在servlet处理完后,返回给前端之前】。
6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
详细链接:https://www.iteye.com/blog/uule-2442198
3.让spring框架帮我们处理异常
即:将异常抛给spring框架,让spring框架来处理。
默认情况下,spring框架会将异常直接抛给最终的用户。
(1)方式一:配置简单异常处理器。
- step1.在spring配置文件当中,配置简单异常处理器。
- step2.添加相应的异常处理页面。 注:简单异常处理器,不能够对异常做复杂的处理。
(2)方式二: @ExceptionHandler。
step1. 在处理器当中添加一个异常处理方法。该方法前面需要添加@ExceptionHandler注解。
step2. 在异常处理方法里面,依据异常类型做不同的处理。
1 | /** |
七、SpringJDBC、Mybatis
1.SpringJdbc、Mybatis
(1)SpringJdbc是什么?
- Spring框架对jdbc的封装。
(2)编程步骤
- step1.导包 spring-webmvc,spring-jdbc,ojdbc,dbcp,junit。
- step2.添加spring配置文件。
- step3.配置JdbcTemplate。
注:JdbcTemplate把一些重复性的代码(比如获取连接,关闭 连接,异常处理等等都写好了),我们只需要调用该对象的方法就可以很方便的访问数据库。
- step4.调用JdbcTemplate的方法来访问数据库。
注:通常将JdbcTemplate注入到DAO。
1 | "employeeDAO") ( |
1 | create table t_emp( |
总结:
(1)Spring提供的JdbcTemplate对jdbc做了封装,大大简化了数据库的操作。
(2)Spring提供的JdbcTempate能直接数据对象映射成实体类,不再需要获取ResultSet去获取值/赋值等操作,提高开发效率。
(3)调用的还是javaweb中的jdbc,是对原生jdbc的封装,代码量更小,如同DBUtils一样。
2.MyBatis
(1)MyBatis是什么?
- 开源的持久层框架。
注:MyBatis底层仍然是jdbc。
Jdbc
- 优点:性能高,易掌握;
- 缺点:代码繁琐。
Hibernate
- 优点:不用写sql,代码简洁;
- 缺点:性能不好,复杂自动生成的sql效率低下,不容易掌握。
MyBatis
- 优点:代码简洁,容易掌握;
- 缺点:还得写sql,性能一般。
(2)编程步骤
step1. 导包。 mybatis,ojdbc,junit
step2. 添加配置文件。
注:主要是连接池的配置和映射文件的位置。
- step3. 写实体类。
注:实体类的属性名与表的字段名要一样(大小写可以忽略)。
- step4. 添加映射文件。
注:里面主要是sql语句。
1 | <mapper namespace="test"> |
注意:当parameterType为基本类型时,也就是说参数为一个值的时候(比如findById的参数id),#{}里面写什么变量都可以。
- step5. 调用SqlSession对象提供的方法来访问数据库。
TestCase.java
1 | public class TestCase { |
SqlMapConfig.xml
1 |
|
SqlMapConfig.xml
1 |
|
(3)工作原理
SqlSessionFactory读取SqlMapConfig.xml文件,文件中包含了EmpMapper.xml文件的地址;
然后,SqlSessionFactory会创建一系列预编译的Map对象,key是sql的id,value是对应的statement;
通过SqlSessionFactory获得SqlSession;
通过向SqlSession的相应方法中传入sqlid和相应的参数;
SqlSession会自动根据sqlid去预编译好的Map对象中查找对应的statment,然后执行,完成相应的功能。
八、Mybatis基本应用、Mapper映射器、Spring Mybatis(方式一)
练习:
使用MyBatis完成对部门表的增删改查操作。
a.添加部门信息。
b.查询出所有部门信息
c.依据id查询某个部门信息
d.修改某个部门信息
e.删除某个部门。
1 | create table t_dept( |
1.返回Map类型的结果
(1)MyBatis会将记录中的数据先放到一个Map对象里面
(以字段名作为key,以字段值作为value,一条记录对应一个Map对象),
然后 再将Map中的数据放到对应的实体对象里面。
(2)返回Map类型的结果,好处是不用实体类了,但是不方便
(因为要获得字段值,还需要调用Map对象提供的get方法,
注意:oracle数据库中,字段名统一都是大写,其他数据库不一定这样,很难确定map的key值)。
2.解决字段名与实体类的属性名不一致
(1)方式一: 使用别名。(就是让别名与属性名一样)。
select ename as name …
(2)方式二: 使用resultMap解决。
3.Mapper映射器
(1)什么是Mapper映射器?
- 符合映射文件要求的接口。
注:MyBatis会生成符合该接口要求的对象。
(2)接口具体要求
a.方法名要与sql的id一致。
b.方法的参数类型要与parameterType一致。
c.方法的返回类型要与resultType一致。
d.映射文件的namespace要等于接口的完整的名字。
(3)如何使用Mapper映射器
1 | // MyBatis会返回一个符合 |
4.Spring集成MyBatis (方式一 使用Mapper映射器)
(1)集成步骤
- step1.导包。spring-webmvc,mybatis,mybatis-spring,dbcp,ojdbc,spring-jdbc,junit。
- step2.添加spring配置文件。
注:不再需要MyBatis的配置文件,可以在spring的配置文件里面添加SqlSessionFactoryBean来代替。
1 | <!-- 配置SqlSessionFactoryBean --> |
- step3.实体类
- step4.映射文件
注:mapper.xml文件的namespace要求等于接口名。
step5.Mapper映射器
step6.配置MapperScannerConfigurer
注:该bean会扫描指定包及其子包下面的所有的Mapper映射器(即接口),然后调用getMapper方法获得映射器的实现(比如,调用 EmployeeDAO dao = SqlSession.getMapper(EmployeeDAO.class))。并且,将这些对象添加到Spring容器里面(默认的id是首字母小写之后的接口名,可以使用@Repository重命名)。
1 | <!-- 配置MapperScannerConfigurer --> |
(2)只扫描特定的接口。
- step1. 开发一个注解。
- step2. 将该注解添加到需要扫描的接口之上。
- step3. 修改MapperScannerConfigurer的配置。
1 | <!-- 配置MapperScannerConfigurer --> |
九、Spring MyBatis(方式二)
1.Spring集成MyBatis (方式二)
(1)集成步骤
step1.导包。spring-webmvc,mybatis,mybatis-spring,dbcp,ojdbc,spring-jdbc,junit。
step2.添加spring配置文件。
注:不再需要MyBatis的配置文件,可以在spring的配置文件里面添加SqlSessionFactoryBean来代替。
- step3.实体类
- step4.映射文件
注:namespace不再要求等于接口名。
- step5.DAO接口
注:接口方法没有特定要求
- step6.写一个DAO接口的实现类
注:可以注入SqlSessionTemplate。
1 | <!-- 配置SqlSessionTemplate --> |
1 | "empDAO") ( |
2.使用Spring集成MyBatis的方式重写AdminDAO
SSM(SM):SpringMVC+Spring+Mybatis
step1. 导包,需要添加 mybatis,mybatis-spring,spring-jdbc
step2. 在配置文件当中,添加 SqlSessionFactoryBean
step3. 实体类Admin,要注意属性与表的字段名不一样,建议用别名解决
step4. 映射文件,放在entity包下面
AdminMapper.xml
1 | <mapper namespace="cn.tedu.netctoss.dao.AdminDAO"> |
step5. Mapper映射器 (AdminDAO)
step6. 配置MapperScannerConfigurer
step7. 测试 AdminDAO
十、AJAX简介
3.ajax (asynchronous javascript and xml 异步的javascript和xml)
(1)ajax是什么?
- 是一种用来改善用户体验的技术,本质上是利用浏览器提供的一个特殊对象(XMLHttpRequest对象;
- 一般也可以称之为ajax对象)向服务器发送异步请求;服务器返回部分数据,浏览器利用这些数据对当前页面做部分更新;
- 整个过程,页面无刷新,不打断用户的操作。
注:异步请求,指的是,当ajax对象发送请求时,浏览器不会销毁当前页面,用户仍然可以对当前页面做其它操作。
(2)如何获得ajax对象?
- 需要考虑一些ie老版本的用户,因为ie是ActiveXObject对象,其他浏览器是XMLHttpRequest对象,所以要分情况讨论:
1 | function getXhr(){ |
(3)ajax对象的几个重要属性
onreadystatechange: 绑订事件处理函数,用来处理readystatechange事件。
注:当ajax对象的readyState属性值发生了任何的改变,比如从0变成了1,就会产生readystatechange事件。
readyState:有5个值(分别是0,1,2,3,4),用来获取ajax对象与服务器通信的进展。其中,4表示ajax对象已经获得了服务器返回的所有的数据。
responseText:获得服务器返回的文本数据。
responseXML:获得服务器返回的xml数据。
status:获得状态码。(例如200,404,500….)
(4)编程步骤
step1. 获得ajax对象,比如 var xhr = getXhr();
step2. 调用ajax对象的方法,发送请求
- 方式一 get请求
1
2
3
4// (请求方式,请求地址,boolean)
xhr.open('get','check.do?adminCode=king',true);
xhr.onreadystatechange = f1; // f1为事件处理函数
xhr.send(null); // 把数据打包发送到服务器注:
- true: 异步 (浏览器不会销毁当前页面,用户仍然可以对当前页面做其它操作)
- false:同步 (浏览器不会销毁当前页面,但是会锁定当前页面,用户不能够对当前页面做任何操作,尽量不用)。
- 方式二 post请求
1
2
3
4
5
6xhr.open('post','check.do',true);
// 设置请求头(消息头)
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
// f1为事件处理函数
xhr.onreadystatechange=f1;
xhr.send('adminCode=king');注:按照http协议要求,如果发送的是post请求,应该包含有Content-type消息头,但是,ajax默认不会带这个消息头,所以,需要调用setRequestHeader方法来添加这个消息头。
step3. 编写服务器端的程序
注:不需要返回完整的页面,只需要返回部分数据。
- step4. 编写事件处理函数
1 | if(xhr.readyState == 4 && xhr.status == 200){ |
十一、AJAX编码问题、缓存问题、JSON
1.编码问题
(1)GET请求
1)为什么会有乱码?
ie浏览器提供的ajax对象,在发送get请求时,会对中文参数值使用”gbk”来编码,其它浏览器会使用”utf-8”来编码。服务器端默认会使用”iso-8859-1”来解码。所以会有乱码。
2)如何解决?
step1. 服务器端,统一使用”utf-8”来解码。可以修改:
1
<Connector URIEncoding="utf-8" />
step2.客户端,使用encodeURI函数对中文参数值进行编码。
注:encodeURI函数是javascript内置的函数,会使用”utf-8”来编码。
(2)POST请求
1)为什么会有乱码?
- 浏览器提供的ajax对象在发送post请求时,对中文参数值会使用”utf-8”来编码,而服务器端会使用”iso-8859-1”来解码。
2)如何解决?
- request.setCharacterEncoding(“utf-8”)
2.缓存问题
(1)什么是缓存问题?(GET请求才有缓存问题)
- 如果使用ie浏览器提供的ajax对象发送get请求,会比较请求地址是否访问过,如果访问过,则不再发送新的请求,而是将第一次访问的结果显示出来(也就是说,第一次访问时,会将服务器返回的结果缓存下来了)。
(2)如何解决?
在请求地址后面添加一个随机数。
例:”getNumber.do?”+Math.random()
3.JSON (javascript object notation)
(1)json是什么?
- 是一种轻量级的数据交换格式。(json借鉴了javascript的部分语法)
- 数据交换:指的是将要交换的数据转换成一种与平台无关的数据格式(比如xml),然后发送给接收方来处理。
- 轻量级:json相对于xml而言,文档更小,解析速度更快。
(2)语法
1)表示一个对象
{属性名:属性值,属性值:属性值…}
- a.属性名必须使用双引号括起来。
- b.属性值可以string,number,true/false,null,object。
- c.属性值如果是string,必须使用双引号括起来。
2)表示对象组成的数组
[{},{},{}…]
(3)使用json
1)java对象如何转换成json字符串?
导包:
使用jackson提供的api(ObjectMapper)。
例1:
1
2ObjectMapper om=new ObjectMapper();
String jsonStr=om.writeValueAsString(stocks);- 例2:
1
2
3
4
5
6
7
8
9
10
11List<Stock> stocks=new ArrayList<Stock>();
for(int i=0;i<3;i++){
Stock s=new Stock();
s.setCode("600977"+i);
s.setName("中国嘉陵"+i);
s.setPrice(8+i);
stocks.add(s);
}
ObjectMapper om=new ObjectMapper();
String jsonStr=om.writeValueAsString(stocks);
System.out.println(jsonStr);2)将json字符串转换成javascript对象?
使用javascript内置对象JSON提供的parse()函数。
例1:
1
2
3
4var str='{"name":"Sally","age":22}';
// 使用javascript内置对象JSON提供的方法来转换
var obj=JSON.parse(str);
alert(obj.name);例2:
1
2
3
4var str='[{"name":"Sally","age":22},' + '{"name":"Eric","age":32}]';
var arr=JSON.parse(str);
// 返回的是由多个javascript对象组成的数组
alert(arr[0].name);
案例:
十二、JQuery对ajax的支持、load方法
1.jQuery对ajax编程的支持
(1)$.ajax方法
1)用法:
$.ajax({});
注:{}是一个对象,其属性用来控制ajax对象如何向服务器
发送请求,常见的属性如下:
url: 请求地址
sync: 是否为异步访问,有两个值:
“true” 异步访问(默认)
“false” 同步访问
type: 请求类型
data: 请求参数(可以是请求字符串形式,比如:”adminCode=king&age=22”,还可以是对象形式,比如{“adminCode”:”king”,”age”:22})
dataType: 服务器返回的数据类型,有如下类型:
“json” json字符串
“text” 文本
“html” html文档
“xml” xml文档
“script” javascript脚本
success: 绑订事件处理函数(服务器已经返回了所有数据,并且没有出错)。
error: 绑订事件处理函数(服务器出错了)
比如:
1 | $.ajax({//用不到的参数可以不写 |
(2)load方法
1)该方法会向服务器发送异步请求,并且将服务器返回的数据直接添加到符合要求的节点之上。
2)用法
$obj.load(url,[data]);
- url : 是请求地址。
- data: 是请求参数。有两种写法(请求字符串和对象的形式)
- (比如“adminCode=king&age=22”或{“adminCode”:“king”,“age”:22})
注:$obj,是jQuery对象
- 本文作者: ACG kaka
- 本文链接: http://acgkaka.github.io/2020/12/07/10Java入门(十)Spring框架 Mybatis框架 Ajax/
- 版权声明: 文章均为个人整理,如有侵权,请联系删除。