Maven
黑马SSM课程笔记:https://blog.csdn.net/weixin_43973189/article/details/121984883
Spring
第一章 Spring的IoC和DI
Spring程序开发步骤
1、导入Spring开发的基本包坐标
2、编写Dao接口和实现类
3、创建Spring核心配置文件
在Spring配置文件中配置UserDaolmpl
4、使用Spring的API获得Bean实例
#Spring配置文件
1、Bean标签基本配置
2、Bean标签范围配置
3、Bean生命周期配置(不是很重要)
● init-method:指定类中的初始化方法名称
● destroy-method:指定类中销毁方法名称
4、Bean实例化三种方式
(1)使用无参构造方法实例化(掌握这种)
它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败
(2)工厂静态方法实例化
工厂的静态方法返回Bean实例
(3)工厂实例方法实例化
工厂的非静态方法返回Bean实例
5、Bean的依赖注入入门
① 创建 UserService,UserService 内部调用 UserDao的save() 方法
② 将 UserServiceImpl 的创建权交给 Spring
③ 从 Spring 容器中获得 UserService 进行操作
6、Bean的依赖注入分析
7、Bean的依赖注入概念
依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。
IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
怎么将UserDao怎样注入到UserService内部呢?
● 构造方法
● set方法
(1)set方法注入
在UserServiceImpl中添加setUserDao方法
配置Spring容器调用set方法进行注入
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入P命名空间:
其次,需要修改注入方式
(2)构造方法注入
创建有参构造
8、Bean的依赖注入的数据类型
上面的操作,都是注入的引用Bean,处了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
注入数据的三种数据类型
● 普通数据类型
● 引用数据类型
● 集合数据类型
其中引用数据类型,此处就不再赘述了,之前的操作都是对UserDao对象的引用进行注入的,下面将以set方法注入为例,演示普通数据类型和集合数据类型的注入。
(1)普通数据类型的注入
(2)集合数据类型(List)的注入
(3)集合数据类型(List)的注入
(4)集合数据类型( Map<String,User> )的注入
(5)集合数据类型(Properties)的注入
9、引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
10、知识要点
Spring的重点配置
#Spring相关API
1、ApplicationContext的继承体系
applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
2、ApplicationContext的实现类
(1)ClassPathXmlApplicationContext
它是从类的根路径下(resources文件夹下)加载配置文件 推荐使用这种
例如:
(2)FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
例如:
(3)AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
3、getBean()方法使用
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错。
4、知识要点
Spring的重点API
第二章 IoC和DI注解开发
1.Spring配置数据源
1.1 数据源(连接池)的作用
● 数据源(连接池)是提高程序性能如出现的
● 事先实例化数据源,初始化部分连接资源
● 使用连接资源时从数据源中获取
● 使用完毕后将连接资源归还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等
数据源的开发步骤:
① 导入数据源的坐标和数据库驱动坐标
② 创建数据源对象
③ 设置数据源的基本连接数据
④ 使用数据源获取连接资源和归还连接资源
1.2 数据源的手动创建
① 导入c3p0和druid的坐标
导入mysql数据库驱动坐标
② 创建C3P0连接池
② 创建Druid连接池
③ 提取jdbc.properties配置文件
④ 读取jdbc.properties配置文件创建连接池
1.3 Spring配置数据源
可以将DataSource的创建权交由Spring容器去完成
● DataSource有无参构造方法,而Spring默认就是通过无参构造方法实例化对象的
● DataSource要想使用需要通过set方法设置数据库连接信息,而Spring可以通过set方法进行字符串注入
测试从容器当中获取数据源
1.4 抽取jdbc配置文件
applicationContext.xml加载jdbc.properties配置文件获得连接信息。
首先,需要引入context命名空间和约束路径:
● 命名空间:xmlns:context=“http://www.springframework.org/schema/context”
● 约束路径:http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
jdbc.properties文件内容:
1.5 知识要点
Spring容器加载properties文件
- Spring注解开发
2.1 Spring原始注解
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
常见注解:
一: 组件类注解
Spring使用配置文件或者注解的方式标识需要处理的java类,把对应Java类当成bean注册到容器。
@Component :标准一个普通的spring Bean类。 @Repository:标注一个DAO组件类。 @Service:标注一个业务逻辑组件类。 @Controller:标注一个控制器组件类。 这些都是注解在平时的开发过程中出镜率极高,@Component、@Repository、@Service、@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型。 @Component可以代替@Repository、@Service、@Controller,因为这三个注解是被@Component标注的。
注意:
1、被注解的java类当做Bean实例,Bean实例的名称默认是Bean类的首字母小写,其他部分不变。@Service也可以自定义Bean名称,但是必须是唯一的!
2、尽量使用对应组件注解的类替换@Component注解,便于开发和维护。
3、指定了某些类可作为Spring Bean类使用后,最好还需要让spring搜索指定路径,在Spring配置文件加入如下配置:
<!-- 自动扫描指定包及其子包下的所有Bean类 -->
<context:component-scan base-package="org.springframework.*"/>
二:装配bean时常用的注解
1、注解介绍
@Autowired:属于Spring 的org.springframework.beans.factory.annotation包下,可用于为类的属性、构造器、方法进行注值 @Resource:不属于spring的注解,而是来自于JSR-250位于java.annotation包下,使用该annotation为目标bean指定协作者Bean。 @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
注意:
1、@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。
2、@Autowired只按照Type 注入;@Resource默认按Name自动注入,也提供按照Type 注入
3、@Resource注解的使用性更为灵活,可指定名称,也可以指定类型 ;@Autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@Qualifier进行限定
三:@Component vs @Configuration and @Bean
@Component可以替代 @Configuration注解
四:spring MVC模块注解
见3.3 SpringMVC注解解析
五:Spring事务模块注解
1、常用到的注解
在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作。使用**@Transactional** 作为注解,需要在配置文件激活
<!-- 开启注解方式声明事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
2、举例
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return result;
}
...
}
readOnly : 事务的读写属性,取true或者false,true为只读、默认为false
rollbackFor : 回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚
timeout (补充的) : 设置超时时间,单位为秒
isolation : 设置事务隔离级别,枚举类型,一共五种
3、总结
事务的传播机制和隔离机制
Spring原始注解主要是替代的配置
注意:
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。
使用@Compont或@Repository标识UserDaoImpl需要Spring进行实例化。
● 使用@Compont或@Service标识UserServiceImpl需要Spring进行实例化
● 使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入
● 使用@Value进行字符串的注入
● 使用@Scope标注Bean的范围
● 使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法
2.2 Spring新注解
使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:
● 非自定义的Bean的配置:
● 加载properties文件的配置:context:property-placeholder
● 组件扫描的配置:context:component-scan
● 引入其他文件:
● @Configuration
● @ComponentScan
● @Import
● @PropertySource
● @Value
● @Bean
测试加载核心配置类创建Spring容器
- Spring集成Junit
3.1在测试类中,每个测试方法都有以下两行代码:
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
3.2上述问题解决思路
● 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
● 将需要进行测试Bean直接在测试类中进行注入
3.3 Spring集成Junit步骤
① 导入spring集成Junit的坐标
② 使用@Runwith注解替换原来的运行期
③ 使用@ContextConfiguration指定配置文件或配置类
④ 使用@Autowired注入需要测试的对象
⑤ 创建测试方法进行测试
3.4 Spring集成Junit代码实现
① 导入spring集成Junit的坐标
② 使用@Runwith注解替换原来的运行期
③ 使用@ContextConfiguration指定配置文件或配置类
④ 使用@Autowired注入需要测试的对象
⑤ 创建测试方法进行测试
3.5 知识要点
Spring集成Junit步骤
① 导入spring集成Junit的坐标
② 使用@Runwith注解替换原来的运行期
③ 使用@ContextConfiguration指定配置文件或配置类
④ 使用@Autowired注入需要测试的对象
⑤ 创建测试方法进行测试
第三章 SpringMVC入门
- Spring集成web环境
1.1 ApplicationContext应用上下文获取方式
应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。
在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。
1.2 Spring提供获取应用上下文的工具
上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。
所以我们需要做的只有两件事:
① 在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)
② 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext
1.3 导入Spring集成web的坐标
1.4 配置ContextLoaderListener监听器
1.5 通过工具获得应用上下文对象
1.6 知识要点
Spring集成web环境步骤
① 配置ContextLoaderListener监听器
② 使用WebApplicationContextUtils获得应用上下文
- SpringMVC 简介
2.1 SpringMVC雏形
2.2 SpringMVC快速入门
需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。
开发步骤:
① 导入SpringMVC相关坐标
② 配置SpringMVC核心控制器DispathcerServlet
③ 创建Controller类和视图页面
④ 使用注解配置Controller类中业务方法的映射地址
⑤ 配置SpringMVC核心文件 spring-mvc.xml
⑥ 客户端发起请求测试
① 导入Spring和SpringMVC的坐标
① 导入Servlet和Jsp的坐标
② 在web.xml配置SpringMVC的核心控制器
③ 创建Controller和业务方法
③ 创建视图页面success.jsp
④ 配置注解
⑤ 创建spring-mvc.xml
⑥ 访问测试地址
Spring访问流程(代码角度)
2.3 SpringMVC流程图示
2.4 知识要点
SpringMVC的开发步骤
① 导入SpringMVC相关坐标
② 配置SpringMVC核心控制器DispathcerServlet
③ 创建Controller类和视图页面
④ 使用注解配置Controller类中业务方法的映射地址
⑤ 配置SpringMVC核心文件 spring-mvc.xml
⑥ 客户端发起请求测试
SpringMVC 组件解析
3.1 SpringMVC的执行流程
① 用户发送请求至前端控制器DispatcherServlet。
② DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③ 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
④ DispatcherServlet调用HandlerAdapter处理器适配器。
⑤ HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
⑥ Controller执行完成返回ModelAndView。
⑦ HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧ DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ ViewReslover解析后返回具体View。
⑩ DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。
3.2 SpringMVC组件解析
前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
处理器:Handler
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
视图解析器:View Resolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
视图:View
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面
3.3 SpringMVC注解解析
常用注解
@Controller
作用:@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。这个时候就需要我们把这个控制器类交给Spring 来管理。有两种方式可以管理:
<!--方式一-->
<bean class="com.cqvie.handler.HelloWorld"/>
<!--方式二-->
< context:component-scan base-package = "com.cqvie" /> <!-- 路径写到controller的上一层 -->
@RequestMapping
作用:用于建立请求 URL 和处理请求方法之间的对应关系。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。返回值会通过视图解析器解析为实际的物理视图,对于 InternalResourceViewResolver 视图解析器,会做如下的解析:通过 prefix + returnVal + suffix 这样的方式得到实际的物理视图,然后做转发操作。
<!-- 配置视图解析器:如何把 handler 方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
RequestMapping注解有六个属性:
1、 value
value:指定请求的实际地址;
2、method;
method: 指定请求的method类型, GET、POST、PUT、DELETE等
3、consumes
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
4、produces
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
5、params
params: 指定request中必须包含某些参数值是,才让该方法处理。
6、headers
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@ResponseBody
告知SpringMVC框架,方法返回的字符串不是跳转,而是直接在http响应体中返回。(方法返回的东西会通过IO流的方式写入到浏览器。)
位置:
● 类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
● 方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径
属性:
● value:用于指定请求的URL。它和path属性的作用是一样的
● method:用于指定请求的方式
● params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
例如:
● params = {“accountName”},表示请求参数必须有accountName
● params = {“moeny!100”},表示请求参数中money不能是100
@Resource和@Autowired
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public class HelloWorld{
// 下面两种@Autowired只要使用一种即可
@Autowired
private UserDao userDao; // 用于字段上
@Autowired
public void setUserDao(UserDao userDao) {
// 用于属性的方法上
this.userDao = userDao;
}
}
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
public class HelloWorld{
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
(2)@Resource
@Resource默认按照ByName自动注入,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
public class HelloWorld{
// 下面两种@Resource只要使用一种即可
@Resource(name="userDao")
private UserDao userDao; // 用于字段上
@Resource(name="userDao")
public void setUserDao(UserDao userDao) {
// 用于属性的setter方法上
this.userDao = userDao;
}
}
@PathVariable
用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。如:
@Controller
public class TestController {
@RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET)
public String getLogin(@PathVariable("userId") String userId,
@PathVariable("roleId") String roleId){
System.out.println("User Id : " + userId);
System.out.println("Role Id : " + roleId);
return "hello";
}
@RequestMapping(value="/product/{productId}",method = RequestMethod.GET)
public String getProduct(@PathVariable("productId") String productId){
System.out.println("Product Id : " + productId);
return "hello";
}
@RequestMapping(value="/javabeat/{regexp1:[a-z-]+}",
method = RequestMethod.GET)
public String getRegExp(@PathVariable("regexp1") String regexp1){
System.out.println("URI Part 1 : " + regexp1);
return "hello";
}
}
@CookieValue
作用:用来获取Cookie中的值;
参数: value:参数名称 required:是否必须 defaultValue:默认值
使用案例:
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
System.out.println("JSESSIONID = " + sessionId);
return "success";
}
@RequestParam
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
@RequestMapping(value = "/quick16")
@ResponseBody
public void save16(@RequestParam("name") String username) {
System.out.println(username);
}
注解@RequestParam还有如下参数可以使用:
● value:与请求参数名称
● required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
● defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
@SessionAttributes
@SessionAttributes即将值放到session作用域中,写在class上面。
@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(value 属性值),
还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types 属性值),用例:
@SessionAttributes(value = {
"user"}, types = {
String.class})
@RequestMapping("/springmvc")
@Controller
public class SessionAttributesTest {
/**
* @SessionAttributes
* 除了可以通过属性名指定需要放到会话中的属性外(value 属性值),
* 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types 属性值)。
* 注意: 该注解只能放在类的上面,不能放在方法上面
*
* @return
*/
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<String, Object> map) {
User user = new User(1, "刘邦", "qwe", "123", "辽宁");
map.put("user", user);
map.put("school", "重庆");
return "success";
}
}
@ResponseBody
作用: 告知SpringMVC框架,方法回的字符串不是跳转是直接在http响应体中返回。
使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
3.2组件扫描
SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=“com.itheima.controller"/>进行组件扫描。
3.4 SpringMVC的XML配置解析
视图解析器
SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:
翻看该解析器源码,可以看到该解析器的默认设置,如下:
可以通过属性注入的方式修改视图的的前后缀
3.5 知识要点
SpringMVC的相关组件
• 前端控制器:DispatcherServlet
• 处理器映射器:HandlerMapping
• 处理器适配器:HandlerAdapter
• 处理器:Handler
• 视图解析器:View Resolver
• 视图:View
SpringMVC的注解和配置
• 请求映射注解:@RequestMapping
• 视图解析器配置:
第四章 SpringMVC的请求和响应
SpringMVC的数据响应
1.1 SpringMVC的数据响应方式
1) 页面跳转
● 直接返回字符串
● 通过ModelAndView对象返回
2) 回写数据
● 直接返回字符串
● 返回对象或集合
1.2 页面跳转
(1)返回字符串形式
直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转。
返回带有前缀的字符串:
转发:forward:/WEB-INF/views/index.jsp
重定向:redirect:/index.jsp(因为webinfo文件夹[即WEB-INF]是受保护的,所以要把重定向的jsp放到可以直接访问的地方)
(2)返回ModelAndView对象
(3)向request域存储数据
在进行转发时,往往要向request域中存储数据,在jsp页面中显示,那么Controller中怎样向request域中存储数据呢?
① 通过SpringMVC框架注入的request对象setAttribute()方法设置
② 通过ModelAndView的addObject()方法设置
1.3回写数据
(1)直接返回字符串
Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用response.getWriter().print(“hello world”) 即可,那么在Controller中想直接回写字符串该怎样呢?
① 通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数据,此时不需要视图跳转,业务方法返回值为void。
② 将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法
返回的字符串不是跳转是直接在http响应体中返回。
在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时我们可以手动拼接json字符串返回。
手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串,我们可以使用web阶段学习过的json转换工具jackson进行转换,导入jackson坐标。
通过jackson转换json格式字符串,回写字符串。
(2)返回对象或集合
通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:
在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,可以使用mvc的注解驱动代替上述配置。
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用mvc:annotation-driven自动加载 RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用mvc:annotation-driven替代注解处理器和适配器的配置。
同时使用mvc:annotation-driven默认底层就会集成jackson进行对象或集合的json格式字符串的转换。
1.4 知识要点
SpringMVC的数据响应方式
1) 页面跳转
● 直接返回字符串
● 通过ModelAndView对象返回
2) 回写数据
● 直接返回字符串
● 返回对象或集合
- SpringMVC 获得请求数据
2.1 获得请求参数
客户端请求参数的格式是:name=value&name=value… …
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数:
● 基本类型参数
● POJO类型参数(简单的bean)
● 数组类型参数
● 集合类型参数
2.2 获得基本类型参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。
2.3 获得POJO类型参数
Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。
2.4 获得数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。
2.5 获得集合类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以。
当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装。
注意:通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种
方式指定放行静态资源:
● 在spring-mvc.xml配置文件中指定放行的资源
● 直接使用mvc:default-servlet-handler/标签
2.6 请求数据乱码问题
当post请求时,数据会出现乱码,可以设置一个过滤器来进行编码的过滤。
2.7 参数绑定注解@requestParam
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
注解@RequestParam还有如下参数可以使用:
● value:与请求参数名称
● required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
● defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
2.8 获得Restful风格的参数
Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。
Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
● GET:用于获取资源
● POST:用于新建资源
● PUT:用于更新资源
● DELETE:用于删除资源
例如:
● /user/1 GET : 得到 id = 1 的 user
● /user/1 DELETE: 删除 id = 1 的 user
● /user/1 PUT: 更新 id = 1 的 user
● /user POST: 新增 user
上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。
2.9 自定义类型转换器
● SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
● 但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。
自定义类型转换器的开发步骤:
① 定义转换器类实现Converter接口
② 在配置文件中声明转换器
③ 在中引用转换器
① 定义转换器类实现Converter接口
② 在配置文件中声明转换器
③ 在中引用转换器
2.10 获得Servlet相关API
SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:
● HttpServletRequest
● HttpServletResponse
● HttpSession
输出:
org.apache.catalina.connector.RequestFacade@143935e
org.apache.catalina.connector.ResponseFacade@14ac0c3
org.apache.catalina.session.StandardSessionFacade@1daa35e
这里输出的是catalina,等价于这里生成的三个对象是tomcat原生产生的,然后传给springmvc框架,调用方法时引用传递给参数。
2.11 获得请求头
(1)@RequestHeader
使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
● value:请求头的名称
● required:是否必须携带此请求头
(2)@CookieValue
使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
● value:指定cookie的名称
● required:是否必须携带此cookie
2.12 文件上传
(1)文件上传客户端三要素
● 表单项type=“file”
● 表单的提交方式是post
● 表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”
(2)文件上传原理
● 当form表单修改为多部分表单时,request.getParameter()将失效。
● enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是:
key=value&key=value&key=value
● 当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:
2.13 单文件上传步骤
① 导入fileupload和io坐标
② 配置文件上传解析器
③ 编写文件上传代码
2.14 单文件上传实现
① 导入fileupload和io坐标
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.3
② 配置文件上传解析器
@RequestMapping(value = “/quick22”)
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws IOException {
System.out.println(username);
//获得上传文件的名称
String originalFilename = uploadFile.getOriginalFilename();
uploadFile.transferTo(new File(“E:\图片\” + originalFilename));
}
2.15 多文件上传实现
多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可
文件1:
文件2:
文件3:
@RequestMapping(value = “/quick23”)
@ResponseBody
public void save23(String username, MultipartFile[] uploadFile) throws IOException {
System.out.println(username);
for (MultipartFile multipartFile : uploadFile) {
String originalFilename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File(“E:\图片\” + originalFilename));
}
}
2.16 知识要点
MVC实现数据请求方式
● 基本类型参数
● POJO类型参数
● 数组类型参数
● 集合类型参数
MVC获取数据细节
● 中文乱码问题
● @RequestParam 和 @PathVariable
● 自定义类型转换器
● 获得Servlet相关API
● @RequestHeader 和 @CookieValue
● 文件上传
第五章 JdbcTemplate
知识要点
① 导入spring-jdbc和spring-tx坐标
② 创建数据库表和实体
③ 创建JdbcTemplate对象
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
④ 执行数据库操作
更新操作:
jdbcTemplate.update (sql,params)
查询操作:
jdbcTemplate.query (sql,Mapper,params)
jdbcTemplate.queryForObject(sql,Mapper,params)
第六章 Spring练习(itheima_spring_test工程)
applicationContext.xml:spring核心配置文件,配置bean(如业务层、Dao层的bean)
spring-mvc.xml:SpringMVC的核心配置文件,配置注解驱动、内部资源视图解析器、静态资源访问
jdbc.properties:抽取JDBC数据库连接信息
log4j.properties:关于日志的配置文件(不需要会写)
第七章 SpringMVC拦截器
1、SpringMVC拦截器
1.1 拦截器(interceptor)的作用
Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
1.2 拦截器和过滤器区别
1.3 拦截器的快速入门
自定义拦截器很简单,只有如下三步:
① 创建拦截器类实现HandlerInterceptor接口
② 配置拦截器
③ 测试拦截器的拦截效果
① 创建拦截器类实现HandlerInterceptor接口
public class Intercepter1 implements HandlerInterceptor {
//目标方法执行之前 执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return false;
}
//在目标方法执行之后 视图对象返回之前
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("post");
}
//在流程都执行完毕之后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("after");
}
}
② 配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/"/>
<bean class="com.itheima.interceptor.Intercepter1"/>
</mvc:interceptor>
</mvc:interceptors>
③ 测试拦截器的拦截效果(编写目标方法)
@Controller
public class TargetController {
@RequestMapping("/target")
public ModelAndView show(){
System.out.println("目标资源执行......");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name","itcast");