Spring+SSM
Spring
基于黑马程序员SSM框架的课堂笔记,感谢黑马程序员!
# Spring+SpringMVC+MyBatis
Spring快速入门
-
导入相关依赖
- Spring-context
- junit
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> -
接口 实现类 注册bean
- 接口
public interface UserDao { void save(); }- 实现类
public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("Sava running..."); } }- 注册bean applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> </beans> -
测试
public class MyTest { @Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = context.getBean("userDao", UserDao.class); userDao.save(); } }
Spring配置文件
1.Bean标签的基本配置
用于配置对象交由Spring来创建。默认情况下它调用的是类的无参构造函数,如果没有无参构造函数则创建不成功。
基本属性:
- id: Bean实例在Spring容器中的唯一标识
- class: Bean的全限定名称
2.Bean标签的范围配置
- scpoe : 指对象的作用范围,取值如下:
| 取值范围 | 说明 |
|---|---|
| singleton | 默认值,单例的 |
| prototype | 多例的 |
| request | WEB项目中,Spring创建一个Bean对象,将对象存入到request域中 |
| session | WEB项目中,Spring创建一个Bean对象,将对象存入到session域中 |
| global session | WEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session |
测试:
- 单例模式【加载配置文件的时候创建对象】
默认情况【scope="singleton"】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl" scope="singleton"/>
</beans>
测试
public class MyTest {
@Test
public void Test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
UserDao userDao1 = context.getBean("userDao",UserDao.class);
System.out.println(userDao);
System.out.println(userDao1);
}
}
结果:
com.jotian.dao.Impl.UserDaoImpl@51e2adc7
com.jotian.dao.Impl.UserDaoImpl@51e2adc7
- 多例模式【getBean时创建对象】
设置【scope="singleton"】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl" scope="prototype"/>
</beans>
测试
public class MyTest {
@Test
public void Test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
UserDao userDao1 = context.getBean("userDao",UserDao.class);
System.out.println(userDao);
System.out.println(userDao1);
}
}
结果:
com.jotian.dao.Impl.UserDaoImpl@3cb1ffe6
com.jotian.dao.Impl.UserDaoImpl@3dfc5fb8
注:
-
当scope的取值为singleton时
Bean的实例化个数:1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
- 对象创建:当应用加载,创建容器时,对象就被创建了
- 对象运行:只有容器在,对象一直活着
- 对象销毁:当应用加载,销毁容器时,对象就被销毁了
-
当scope的取值为prototype时
- Bean的实例化个数:多个
- Bean的实例化时机:当调用getBean()方法时实例化Bean
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,就一直活着
- 对象销毁:当对象长时间不使用时,就被java的垃圾回收器回收了
Bean的生命周期配置
- init-method : 指定类的初始化方法名称
- destroy-method :指定方法销毁的方法名称
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("无参构造执行了。。。");
}
public void init(){
System.out.println("初始化方法。。。");
}
public void destory(){
System.out.println("销毁方法。。。");
}
@Override
public void save() {
System.out.println("Sava running...");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"/>
</beans>
public class MyTest {
@Test
public void Test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
((ClassPathXmlApplicationContext)context).close();
}
}
无参构造执行了。。。
初始化方法。。。
销毁方法。。。
注:
调用.close() 方法为了告诉程序,结束的切入点。从而调用销毁的方法
Bean实例化的三种方式
- 无参构造方法实例化【之前的都是无参构造实例化】
- 工厂静态方法实例化
- 工厂实例方法实例化
第二种:
public class StaticFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("无参构造执行了...");
}
@Override
public void save() {
System.out.println("Save Running ...");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.jotian.factory.StaticFactory" factory-method="getUserDao"/>
</beans>
第三种:
public class DynamicFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("无参构造执行了...");
}
@Override
public void save() {
System.out.println("Save Running ...");
}
}
<bean id="favtory" class="com.jotian.factory.DynamicFactory"/>
<bean id="userDao" factory-bean="favtory" factory-method="getUserDao"/>
</beans>
Bean的依赖注入分析
set方法 构造方法 注入
初始:
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
@Override
public void save() {
UserDao userDao = new UserDaoImpl();
userDao.save();
}
}
@Test
public void Test01() {
UserServiceImpl userService = new UserServiceImpl();
userService.save();
}
}
改进
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
@Override
public void save() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
userDao.save();
}
}
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/>
<bean id="userService" class="com.jotian.service.Impl.UserServiceImpl"/>
@Test
public void Test01() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class);
userService.save();
}
分析:
目前UserService实例和UserDao实例都存在容器中,当前的做法是在容器外部获得UserService实例和UserDao实例,然后在程序中结合。

所以-->因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UserService内部。

Bean的依赖注入概念
依赖注入(Dependency Injection):它是Spring框架核心IOC的具体实现
在编写程序时,通过控制反转,把对象的创建交给Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低它们之间的依赖关系,但是不会消除,例如:业务层任然会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。
简单的说,就是坐等框架把持久层对象传入到业务层,而不是我们自己去获取。
- 构造方法
- set方法
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/>
<bean id="userService" class="com.jotian.service.Impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<!--前userDao是UserServiceImpl属性名
后userDao是引用容器中bean的id
-->
-
set方法注入
p命名空间注入的本质是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"其次,需要修改注入方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> <bean id="userService" class="com.jotian.service.Impl.UserServiceImpl" p:userDao-ref="userDao"> </bean> </beans> -
构造方法注入
-
public class UserServiceImpl implements UserService { private UserDao userDao; public UserServiceImpl(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.save(); } }<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> <bean id="userService" class="com.jotian.service.Impl.UserServiceImpl"> <constructor-arg name="userDao" ref="userDao"/> </bean> <!--前userDao是构造方法里面的参数名 后userDao引用容器中的id -->
Bean的依赖注入的数据类型
上面的操作,都是注入的应用Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
注入的数据类型:
- 普通数据类型
- 引用数据类型【上面的注入全是引用数据类型的注入】
- 集合数据类型
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String getWife() {
return wife;
}
public void setWife(String wife) {
this.wife = wife;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address +
", books=" + Arrays.toString(books) +
", hobbys=" + hobbys +
", card=" + card +
", games=" + games +
", wife='" + wife + '\'' +
", info=" + info +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="address" class="com.jotian.pojo.Address"/>
<!--第一种:普通值注入,value-->
<bean id="student" class="com.jotian.pojo.Student" >
<property name="name" value="冰天雪地"/>
<!--第二种: Bean注入,ref-->
<property name="address" ref="address"/>
<!--第三种:数组-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!--第四种:List-->
<property name="hobbys">
<list>
<value>上课</value>
<value>看书</value>
<value>看网课</value>
<value>敲代码</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="语文" value="87"/>
<entry key="数学" value="140"/>
<entry key="英语" value="37"/>
<entry key="物理" value="87"/>
</map>
</property>
<!--Set-->
<property name="games">
<set>
<value>CS</value>
<value>CF</value>
<value>游戏</value>
<value>莫忘少年凌云志,曾许人间第一流</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--properties-->
<property name="info">
<props>
<prop key="姓名">路星河</prop>
<prop key="年龄">18</prop>
<prop key="出生">同桌的你</prop>
<prop key="live">耿耿星河</prop>
</props>
</property>
</bean>
</beans>
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
System.out.println(student.getAddress());
for (String book : student.getBooks()) {
System.out.println(book);
}
System.out.println(student.getCard());
System.out.println(student.getGames());
System.out.println(student.getHobbys());
System.out.println(student.getInfo());
System.out.println(student.getWife());
}
}
注:
map集合
<list>
<entry key="user" value-ref=""></entry></entry>
</list>
<!--value-ref 后缀ref表示引用 引用的存在与容器当中-->
引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将这部分配置拆解到其他的配置文件中,而在Spring主配置文件通过import标签进行加载

<import resource="applicationContext-xxx.xml"/>
知识点小结
Spring的重点配置
标签 id 属性:在容器中Bean实例的唯一表识,不允许重复
class 属性:要实例化的Bean的全限定名
scope属性:Bean的作用范围,常用在Singleton(默认)【单例】和prototype【多例】
标签 :属性注入 name 属性:属性的名称
value 属性:注入的普通属性值
ref 属性:注入的对象引用值
标签
标签
标签
标签:导入其他的Spring的分文件
Spring相关API
applicationContext:接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象

ApplicationContext的实现类
-
ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件推荐使用这种
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); -
FileSystemXmlApplicationContext
它是从磁盘路径下加载配置文件,配置文件可以在磁盘的任意位置
ApplicationContext context = new FileSystemXmlApplicationContext("C:\\Users\\jotian\\IdeaProjects\\Spring_SpringMVC_MyBatis\\Spring-01-Iop\\src\\main\\resources\\applicationContext.xml"); -
AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建spring容器,它用来读取注解。
注解开发时讲
getBean()方法使用
public Object getBean(String name) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name, requiredType);
}
public <T> T getBean(Class<T> requiredType) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(requiredType);
}
context.getBean("userService")
context.getBean("userService",UserService.class)
context.getBean(UserService.class)
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回时Object,需要强转。当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法报错。
知识要点
Spring的重点API
ApplicationContext context = new ClassPathXmlApplicationContext("xml文件")
context.getBean("id")
context.getBean(Class)
Spring配置数据源
数据源(连接池)的作用
- 数据源(连接池)是提高程序性能出现的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据库中获取
- 使用完毕之后将连接资源归还给数据源
常见的数据源(连接池): DBCP、C3P0、BoneCp、Druid等
不懂!!!???
数据源的开发步骤
-
导入数据源的坐标和数据库驱动的坐标
- 数据库驱动的mysql-connector-java
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency>- c3p0
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency>- druid
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> -
创建数据源对象
-
设置数据源的基本连接数据
-
使用数据源获取连接资源归还连接资源
数据源的手动创建
测试:
@Test
//手动创建c3p0数据源
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setUser("root");
dataSource.setPassword("1121");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
//测试手动创建druid数据源
public void test2() throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setUsername("root");
dataSource.setPassword("1121");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
抽取配置文件:
-
配置文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.user=root jdbc.pwd=1121 -
测试
@Test //测试手动创建druid数据源 public void test2() throws SQLException { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis"); dataSource.setUsername("root"); dataSource.setPassword("1121"); DruidPooledConnection connection = dataSource.getConnection(); System.out.println(connection); connection.close(); }方便解耦不要把代码写死了!
Spring配置数据源
可以将DataSource的创建权交由Spring容器去完成set注入
-
容器加载
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="user" value="root"/> <property name="password" value="1121"/> </bean>name后写的是setJdbcUrl 的 JdbcUrl -->jdbcUrl
-
测试u
@Test public void test3() throws SQLException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ComboPooledDataSource dataSource = context.getBean("dataSource", ComboPooledDataSource.class); Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close(); }
-
抽取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
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.pwd}"/> </bean> </beans>@Test public void test3() throws SQLException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ComboPooledDataSource dataSource = context.getBean("dataSource", ComboPooledDataSource.class); Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close(); }
知识要点
Spring容器加载properties文件
<context:property-placeholder location="classpath:jdbc.properties"/>
<property name="" value="${}"/>
Spring原始注解
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
Spring原始注解主要是代替
注解
| 注解 | 说明 |
|---|---|
| @Component | 使用在类上用于实例化Bean |
| @Controller | 使用在web层类用于实例化Bean |
| @Service | 使用在service层类上用于实例化Bean |
| @Repository | 使用在dao层类上用于实例化Bean |
| @Autowired | 使用在字段上用于根据类型依赖注入 |
| @Qualifier | 结合@Autoeired一起使用用于根据名称进行依赖注入 |
| @Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
| @Value | 注入普通属性 |
| @Scope | 标注Bean的作用范围 |
| @PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
| @PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
演示【xml配置】:
-
dao
public interface UserDao { void sava(); }public class UserDaoImpl implements UserDao { @Override public void sava() { System.out.println("UserDao---->sava方法执行"); } } -
service
public interface UserService { void save(); }public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.sava(); } } -
Bean注册
<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> <bean id="userService" class="com.jotian.service.Impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> -
web【假的】
@Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class); userService.save();
演示【注解】
注意
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定那个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类,字段和方法。
注解方式可以不要set方法!注意注解的位置
<!--注解的组件扫描-->
<context:component-scan base-package="com.jotian"/>
-
dao
public interface UserDao { void sava(); }//<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> @Component("userDao") public class UserDaoImpl implements UserDao { @Override public void sava() { System.out.println("UserDao---->sava方法执行"); } } -
service
public interface UserService { void save(); }//<bean id="userService" class="com.jotian.service.Impl.UserServiceImpl"> @Component("userService") public class UserServiceImpl implements UserService { private UserDao userDao; // <property name="userDao" ref="userDao"/> @Autowired @Qualifier("userDao") public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.sava(); } } -
Bean注册
<!--配置组件扫描--> <context:component-scan base-package="com.jotian"/> -
Web
@Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class); userService.save(); }
扩展衍生注解
-
dao
//<bean id="userDao" class="com.jotian.dao.Impl.UserDaoImpl"/> //@Component("userDao") @Repository("userDao") public class UserDaoImpl implements UserDao { @Override public void sava() { System.out.println("UserDao---->sava方法执行"); } } -
service
//<bean id="userService" class="com.jotian.service.Impl.UserServiceImpl"> //@Component("userService") @Service("userService") public class UserServiceImpl implements UserService { // <property name="userDao" ref="userDao"/> @Autowired //按照数据类型从Spring容器中进行匹配的 @Qualifier("userDao") //是按照id值从容器中进行匹配。但是主要此处@Qualifier结合@Autowired一起使用 @Resource(name="userDao") //相当于@Autoeired和@Qualifier private UserDao userDao; @Override public void save() { userDao.sava(); } }@Value("itvast") private String name; @Value("${}") //配置文件里面找value private Stirng user
Spring新注解
使用上面的注解还不能全部代替xml配置文件,还需要使用注解代替的配置如下:
- 非自定义的Bean的配置:
- 加载properties文件的配置:<context:property-placeholder>
- 组件扫描的配置:context:component-scan
- 引入其他文件:
| 注解 | 说明 |
|---|---|
| @Configuration | 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 |
| @ComponentScan | 用于指定Spring在初始化时要扫描的包。作用和在Spring的xml的配置文件中的<context:component-scan base-package=com.jotian/> |
| @Bean | 使用在方法上,标注该方法的返回值存储到Spring容器中 |
| @PropertySource | 用于加载.properties文件中的配置 |
| @import | 用于导入其他的配置类 |
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void sava() {
System.out.println("UserDao---->sava方法执行");
}
}
@Service("userService")
public class UserServiceImpl implements UserService {
// <property name="userDao" ref="userDao"/>
@Autowired
@Qualifier("userDao")
private UserDao userDao;
@Override
public void save() {
userDao.sava();
}
}
// <context:property-placeholder location=""/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.pwd}")
private String pwd;
@Bean("dataSource")
public DataSource getDateSoutrce() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(user);
dataSource.setPassword(pwd);
return dataSource;
}
}
//标志该类是Spring的核心配置类
@Configuration
//<!--配置组件扫描-->
//<context:component-scan base-package="com.jotian"/>
@ComponentScan("com.jotian")
//<import resource=""/>
@Import({DataSourceConfiguration.class}) //数组
public class SpringCofiguration {
}
@Test
public void test1(){
ApplicationContext context = new AnnotationConfigApplicationContext(SpringCofiguration.class);
UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class);
userService.save();
}
Spring集成Junit
原始Junit测试Spring的问题
在测试类中,每个测试方法都有以下两行代码:
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml")
IAccountService as = context.getBean("accountService",IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常,所以又不能轻易删掉。
上述问题的解决方案
- 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
- 将需要进行测试Bean直接在测试类中进行注入
Spring集成junit步骤
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void sava() {
System.out.println("save --> running");
}
}
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
@Override
public void save() {
userDao.sava();
}
}
-
导入spring继承的junit坐标
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.12.RELEASE</version> </dependency> -
使用@RunWith注解替换原来的运行期
-
使用@ContextConfiguration指定配置文件或者配置类
-
使用@Autowired注入需要测试的对象
-
创建测试方法进行测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringConfiguration { @Autowired @Qualifier("userService") private UserService userService; @Test public void test1(){ userService.save(); } }
出现错误
- 当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上。
- 版本不一致。版本不匹配
Spring与Web环境集成
Tomcat
maven坐标导入--->web
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
</dependency>
ApplicationContext应用上下文获取方式
应用上下文对象是通过该 new ClassPathXmlApplicationContext(Spring配置文件)方式获取的,但是每次从容器中获得Bean时都要编写new ClassPathXmlApplicationContext(Spring配置文件),这样的弊端是配置文件加载多次,应用上下文对象创建多次。
在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就夹在Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获取上下文ApplicationContext对象了。
Spring提供获取应用上下文的工具
例子
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//读取web.xml中的全局参数
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//将Spring的应用上下文对象存储到ServletContext域中
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("context",context);
System.out.println("Spring容器创建完毕。。。");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--全局初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器-->
<listener>
<listener-class>com.jotian.listener.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>com.jotian.web.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
</web-app>
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext servletContext = servletContextEvent.getServletContext();
//读取web.xml中的全局参数
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
ApplicationContext context = new ClassPathXmlApplicationContext(contextConfigLocation);
//将Spring的应用上下文对象存储到ServletContext域中
servletContext.setAttribute("context",context);
System.out.println("Spring容器创建完毕。。。");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
public class WebApplicationContextUtils {
public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
return (ApplicationContext) servletContext.getAttribute("context");
}
}
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ServletContext servletContext = req.getServletContext();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService = context.getBean("userService", UserService.class);
userService.save();
}
}
Spring提供获取应用上下文的工具
上面分析的不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器类不加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获取应用上下文对象。
所以我们需要做的只有两件事:
-
在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.0.RELEASE</version> </dependency> -
在WebApplicationContextUtils获取应用上下文对象ApplicationContext
![]()
<!--全局初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
导入Spring集成web的坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
配置ContextLoaderListener监听器
<!--全局初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器-->
<listener>
<listener-class>com.jotian.listener.ContextLoaderListener</listener-class>
</listener>
通过工具获取应用上下文对象
ApplicationContext context = WebApplicationConextUtils。getWebApplicationContext(servletConext);
Object obj = applicationContext.getBean("id");
Spring继承web环境步骤
- 配置ContextLoaderListener监听器
- 使用WebApplicationContextUtils获取应用上下文
SpringMVC简介
SpringMVC概述
SpringMVC是一种基于java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow中。
SpringMVC已经成为目前最主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,成为最优秀的MVC框架,它通过一套注解,让一个简单的java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。

SpringMVC快速入门
需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。
开发步骤:
- 导入SpringMVC相关坐标
- 配置SpringMVC核心控制器DispathcerServlrt
- 创建Controller类和视图页面
- 使用注解配置Controller类中业务方法的映射地址
- 配置SpringMVC核心文件spring-MVC.xml
- 客户端发起请求测试
-
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>我的第一个MVC ! hello</h1> </body> </html> -
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--全局初始化参数--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置SpringMVC的前端控制器--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> -
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--注解的组件扫描--> <context:component-scan base-package="com.jotian"/> </beans> -
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--Controller的组件扫描--> <context:component-scan base-package="com.jotian.controller"/> </beans> -
UserController.java
@Controller @RequestMapping("/user") public class UserController { // 请求地址 http://localhost:8034/quick @RequestMapping("/quick") public String save(){ System.out.println("Controller save running..."); return "/success.jsp"; } }
SpringMvc流程图

SpringMVC组件解析
SpringMVC的执行流程

- 用户发送请求至前端控制器DispatcherServlet
- DispathcherServlet收到请求调用HandlerMapping处理器映射器
- 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有就生成)并返回给DispatcherServlet
- DispatcherServlet调用HandlerAdapter处理器适配器
- HandlerAdapter经过适配器调用具体的处理器(Controller,也叫后端控制器)
- Controller执行完成返回ModelAndView
- HandlerAdapte将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户
SpringMVC注解解析
@Controller
作用:使用在web层类用于实例化Bean
@RequestMapping
作用:用于建立请求URL和处理请求方法之间的对应关系
位置:
- 类上,请求URL的第一级访问目录、此处不写的话,就相当于应用 的根目录
- 方法上,请求URL的第二级访问目录,写在类上的使用@RequestMapping标注的一级目录一起组成访问虚拟路径
- value:用于指定请求的URL。它和path属性的作用是一样的
- method:用于指定请求的方式
- params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须与配置的一摸一样
- params={"accountName"} ,表示请求参数必须由accountName
- params={"moeny!100"},表示请求参数中money不能是100
@Controller
// 请求地址 http://localhost:8034/user/quick
@RequestMapping("/user")
public class UserController {
// 请求地址 http://localhost:8034/quick
@RequestMapping("/quick")
public String save(){
System.out.println("Controller save running...");
return "/success.jsp";
}
}
mvc命名空间注入
命名空间:
xmlns:context="http://www.springframework.org/schema/context"
约束地址:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
组件扫描
SpringMVC基于Spring容器,所以进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=”com.jotian.controller“>进行组件扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--注解的组件扫描-->
<context:component-scan base-package="com.jotian"/>
</beans>
<!--注解的组件扫描-->
<context:component-scan base-package="com.jotian">
<!--只扫描Controller这个组件-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!--只扫描Controller这个组件之外的-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
Spring XMl文件配置
SpringMVC的相关组件
- 前端控制器:DispatcherServlet
- 处理器映射器:HandlerMapping
- 处理器适配器:HandlerAdapter
- 处理器:Handler
- 视图解析器:view Resolver
- 视图:View
SpringMVC的注解和配置
-
请求映射注解:@RequestMapping
-
视图解析器配置:(前后缀)
REDIRECT_URL_PREFIX = "redirect" FORWARD_URL_PREFIX = "forward" prefix=""; suffix="";
SpringMVC的数据响应
Spring数据响应的方式
-
页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
-
回写数据
- 直接返回字符串
- 返回对象或结果集
页面跳转
返回字符串形式
直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转
@Controller
@RequestMapping("/user")
public class UserController {
// 请求地址 http://localhost:8034/quick
@RequestMapping("/quick")
public String save(){
System.out.println("Controller save running...");
return "success";
}
}

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
返回ModelAndView
@RequestMapping("quick2")
public ModelAndView save2(){
/**
* modol:模型 作用封装数据
* view: 视图 作用战术数据
*/
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
modelAndView.addObject("username","itcast");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>我的第一个MVC ! hello</h1>
<h1> ${username} </h1>
</body>
</html>
取不到数据 <%isELIgnored="false"%> 加上这个
Spring会自动提供数据对象 例如
@RequestMapping("quick3")
public ModelAndView save3(ModelAndView modelAndView){
modelAndView.addObject("username","jotian");
modelAndView.setViewName("success");
return modelAndView;
}
@RequestMapping("quick4")
public String save4(Model model){
model.addAttribute("username","自学java");
return "success";
}
@RequestMapping("quick5")
public String save5(HttpServletRequest request){
request.setAttribute("username","jotian自学java");
return "success";
}
回写数据
直接返回字符串
Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为相应体返回的话,只需要使用response.getWriter().print(“hello word”)即可,那么再Controller中想直接回写字符串该怎么样呢?
-
通过SpringMVC框架注入的response对象,使用reponse.getWriter().pring(“hello word”)回写数据,此时不需要视图跳转,业务方法返回值void
@RequestMapping("/quick6") public void quickMethod4(HttpServletResponse response) throwa IOException{ response.getWriter().print("hello world") }错误 Spring不能智能到知道你是要跳转页面还是回写文字
@RequstMapping("/quisk7") public String save7(){ return "hello word"; //这个应该是自动寻找视图跳转 而不是回文字,所以会直接报错 } -
直接返回字符串
将需要回写的字符串直接返回,但是此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应中返回。
@RequnstMapping("/quick8") @ResponseBody public String save8(){ return "(\"username\":\"zhangsan\",\"age\":18)"; }导入josn包
<dependecy> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependecy> <dependecy> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependecy> <dependecy> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependecy>@RequnstMapping("/quick8") @ResponseBody public String save8(){ User user = new User(); user.setUserName("张三"); user.setAge(18); //使用json的转换工具将对象装换成json格式字符串在返回。 ObjecMapper objectMapper = new ObjectMapper(); String json = objectMapper.wrteValueAsString(user); return json; }返回对象或集合
<!--配置处理器映射器--> <bean class="org.springframework.web.server.annotation.RequestMapingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean>@RequnstMapping("/quick8") @ResponseBody //期望SpringMVC自动将User装换成json格式的字符串 public User save8(){ User user = new User(); user.setUserName("张三"); user.setAge(18); return user; }细节点:
在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置
<!--mvc的注解驱动--> <mvc:annotation-driven/>在SpringMVC的各个组件中,处理器映射器,处理器适配器,视图解析器称为SpringMVC的三大组件。使用mvc:annotation-drivern自动加载RequestMappingHandlerMapping(处理器映射器)和RequestMappingHandlerAdapter(处理适配器),可用Spring-xml.xml配置文件中使用mvc:annotation-driven替代注解处理器和适配器的配置。
同时使用mvc:annotation-driven默认底层就会集成jackson进行对象或集合的json格式字符串的转换。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
知识要点
SpringMVC的数据响应方式
- 页面跳转
- 直接返字符串
- 通过ModelAndView对象返回
- 回写数据
- 直接返回接返回字符串
- 返回对象或集合
SpringMVC获得请求数据
获得请求参数
客户端请求参数的格式是:name=value&name=value...
服务器端要获得请求参数,又是还需要进行数据的封装,SpringMVC可以接收如下类型的参数:
- 基本类型参数
- POJO类型参数
- 数组类型参数
- 集合类型参数
获得基本类型参数
Controller的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配
http://localhost:8080/jotian_springmvc/quick?username=zhangsan&age=18
@RequestMapping("/quick")
@ResponseBody
public void save(String username,int age)throw Exception{
System.out.println(username);
System.out.pringln(age);
}
获得POJO类型参数
Controller的业方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配
http://localhost:8080/jotian_springmvc/quick?username=zhangsan&age=18
@Date
public void User{
private String username;
private int age;
}
@RequestMappring("/quick")
@ResponseBody
public void quickMethod(User user)throws Exception{
System.out.pringln(user)
}
获得数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数会自动映射匹配
http://localhost:8080/jotian_springmvc/quick?strs=zhangsan&strs=18
@RequestMapping("/quick")
@ResponseBody
public void quickMethod(Stinrg[] strs)throws Exception{
System.out.pringln(Arrays.asList(strs));
}
获得集合类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以
- VO对象
@Date
public class VO {
private List<User> userList;
}
@RequestMapping("/quick")
@ResponseBody
public void save(Vo vo)throws Exception{
System.out.pringln(vo);
}
<from action="${pageContext.request.contextPath}/user/quick14" method="post">
<input type="test" name="usetList[0].username"><br/>
<input type="test" name="usetList[0].age"><br/>
<input type="test" name="usetList[1].username"><br/>
<input type="test" name="usetList[1].age"><br/>
<input type="submit" value="提交">
</from>
获得集合类型参数
当使用ajax提交时,可以指定contentType未json形式,那么在方法参数位置使用RequestBody可以直接接收集合数据而无需似乎用POJO进行包装
获取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注解进行占位符的匹配获取工作。
http://localhost:8080/itheima_springmvc/quick/zhangsan
@RequestMapping("/quick/{name}")
@ResponseBody
public void quickMethod(@PathVariable(value="name" required=true)String name){
System.out.println(name);
}
自定义类型转换器
- SpringMVC默认已经提供了一些常用的类型转换器,例如客户端提供的字典转换成int型进行参数设置。
- 但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。
自定义类型转换器的开发步骤:
- 定义转换器类型的Converter接口
- 在配置文件中声明转换器
- 在
中引用转换器
获取Servlet相关的API
SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:
-
HttpServletRequest
-
HttpServletResponse
-
HttpSession
@ResquestMapping("/quick") @ResponseBody public void quickMethod16(HttpServletRequest request,HttpServletResponse response,HttpSession session){ System.out.println(resquest); System.out.println(response); System.out.println(session); }
获取请求头@Resquest
-
@ResquestHeader
使用@ResquestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)@ResquestHeader注解的属性如下:
- value:请求头名称
- required :是否必须携带此请求头
@ResquestMapping("/quick") @ResponseBody public void save(@ResquestHeader(value="User_Agent",required=false)String user_agent)throws Exception{ System.out.println(user_agent) } -
@CookieValue
使用@CooKieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
-
value:指定cookie的名称
-
required:是否必须携带此cookie
@ResquestMapping("quick") @ResponseBody public void save(@CookieValue(value="JESSIONID")String jessionId){ System.out.println(jessionId); }
-
文件上传
-
文件上传客户端三要数
-
表单项type=“file”
-
表单的提交方式是post
-
表单的enctype属性是多部分表单形式,级enctype=“multipart/form-data”
<form action="${pageContext.request.contextPath}/quick" method="post" enctype="multipart/form-data"> 名称:<input type="text" name="name"><br> 文件:<input type="file" name="file"><br> <input type="submit" value="提交"><br> </form> -
当from表单修改为多部份表单时,request.getParameter()将失效
-
enctype=“appilcation/x-www-from-urlencoded”时,form表单的正文内容格式是:key=value&key=value&key=value
-
当form表单的enctype取值为Mutilpart/from-data时,请求正文内容就变为多部份形式:
单文件上传的步骤
- 导入fileupload和io坐标
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency>- 配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommoonsMultipartResolver"> <!--上传文件总大小--> <property name="maxUploadSize" value="5242800"/> <!--上传单个文件的大小--> <property name="maxUploadSizePerFile" value="5343800" <!--上传文件的编码类型--> <property name="defaultEncoding" value="UTF-8"> <bean/>- 编写文件上传代码
@RequestMapping("/quick") @ResponseBody public void quickMethod20(String name,MultipaetFile uploadFile)throws IOException{ //获得文件名称 String originalFilename = uploadFile.getOriginalFilename(); //保存文件 uploadFile.transferTo(new File("C:\\upload\\"+oridinalFilename)); } -
多文件上传实现
多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可
<h1>多文件上传测试</h1>
<form action="${pageContext.request.contextPath}/quick" method="post" enctype="multipart/form-data">
名称:<input type="text" name="name"><br>
文件1:<input type="file" name="uploadFiles"><br>
文件2:<input type="file" name="uploadFiles"><br>
文件3:<input type="submit" value="提交"><br>
</form>
@RequestMappping("/quick")
@ResponseBody
public void quickMethod(String name,MultipartFile[] uploadFiles)throws IOException{
for(MultipartFile uploadFile:uploadFiles){
String originalFilename = uploadFile.getOriginalFilename();
uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
}
}
知识要点
MVC实现数据请求方式
- 基本类型参数
- POJO类型参数
- 数组类型参数
- 集合类型参数
MVC获取数据细节
- 中文乱码问题
- @RequestParam和@PathVariable
- 自定义类型转换器
- 获得Serclet相关API
- @RequestHeader和@CookieValue
- 文件上传
附页:
Springmvc jar包介绍
spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。
除了spring.jar文件,Spring还包括有其它13个独立的jar包,各自包含着对应的Spring组件,用户可以根据自己的需要来选择组合自己的jar包,而不必引入整个spring.jar的所有类文件。
(1) spring-core.jar
这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
(2) spring-beans.jar
这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring-beans.jar文件就可以了。
(3) spring-aop.jar
这个jar文件包含在应用中使用Spring的AOP特性时所需的类。使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。
(4) spring-context.jar
这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI所需的全部类,UI方面的用来与模板(Templating)引擎如Velocity、FreeMarker、JasperReports集成的类,以及校验Validation方面的相关类。
(5) spring-dao.jar
这个jar文件包含Spring DAO、Spring Transaction进行数据访问的所有类。为了使用声明型事务支持,还需在自己的应用里包含spring-aop.jar。
(6) spring-hibernate.jar
这个jar文件包含Spring对Hibernate 2及Hibernate 3进行封装的所有类。
(7) spring-jdbc.jar
这个jar文件包含对Spring对JDBC数据访问进行封装的所有类。
(8) spring-orm.jar
这个jar文件包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖spring-dao.jar里的类,用这个包时你需要同时包含spring-dao.jar包。
(9) spring-remoting.jar
这个jar文件包含支持EJB、JMS、远程调用Remoting(RMI、Hessian、Burlap、Http Invoker、JAX-RPC)方面的类。
(10) spring-support.jar
这个jar文件包含支持缓存Cache(ehcache)、JCA、JMX、邮件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。
(11) spring-web.jar
这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。
(12) spring-webmvc.jar
这个jar文件包含Spring MVC框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。
(13) spring-mock.jar
这个jar文件包含Spring一整套mock类来辅助应用的测试。Spring测试套件使用了其中大量mock类,这样测试就更加简单。模拟HttpServletRequest和HttpServletResponse类在Web应用单元测试是很方便的。
如何选择这些发布包,决定选用哪些发布包其实相当简单。
如果你正在构建Web应用并将全程使用Spring,那么最好就使用单个全部的spring.jar文件;
如果你的应用仅仅用到简单的Inversion of Control / Dependency Injection(IoC/DI)容器,那么只需spring-core.jar与spring-beans.jar即可;
如果你对发布的大小要求很高,那么就得精挑细选了,只取包含自己所需特性的jar文件了。
采用独立的发布包你可以避免包含自己的应用不需要的全部类。当然你可以采用其它的一些工具来设法令整个应用包变小,节省空间的重点在于准确地找出自己所需的Spring依赖类,然后合并所需的类与包就可以了。
Eclispe有个插件叫ClassPath Helper可以帮你找找所依赖的类。
Spring包依赖说明:
\1) spring-core.jar需commons-collections.jar,spring-core.jar是以下其它各个的基本。
\2) spring-beans.jar需spring-core.jar,cglib-nodep-2.1_3.jar
\3) spring-aop.jar需spring-core.jar,spring-beans.jar,cglib-nodep-2.1_3.jar,aopalliance.jar
\4) spring-context.jar需spring-core.jar,spring-beans.jar,spring-aop.jar,commons-collections.jar,aopalliance.jar
\5) spring-dao.jar需spring-core.jar,spring-beans.jar,spring-aop.jar,spring-context.jar
\6) spring-jdbc.jar需spring-core.jar,spring-beans.jar,spring-dao.jar
\7) spring-web.jar需spring-core.jar,spring-beans.jar,spring-context.jar
\8) spring-webmvc.jar需spring-core.jar/spring-beans.jar/spring-context.jar/spring-web.jar
\9) spring-hibernate.jar需spring-core.jar,spring- beans.jar,spring-aop.jar,spring-dao.jar,spring-jdbc.jar,spring- orm.jar,spring-web.jar,spring-webmvc.jar
\10) spring-orm.jar需spring-core.jar,spring-beans.jar,spring-aop.jar,spring-dao.jar,spring-jdbc.jar,spring-web.jar,spring-webmvc.jar
\11) spring-remoting.jar需spring-core.jar,spring-beans.jar,spring- aop.jar,spring-dao.jar,spring-context.jar,spring-web.jar,spring- webmvc.jar
\12) spring-support.jar需spring-core.jar,spring-beans.jar,spring-aop.jar,spring-dao.jar,spring-context.jar,spring-jdbc.jar
\13) spring-mock.jar需spring-core.jar,spring-beans.jar,spring-dao.jar,spring-context.jar,spring-jdbc.jar
一、只是使用spring框架
dist\spring.jar
lib\jakarta-commons\commons-logging.jar
如果使用到了切面编程(AOP),还需要下列jar文件
lib\aspectj\aspectjweaver.jsr 和 aspectjrt.jar
lib\cglib\cglib-nodep-2.1_3.jar
如果使用了JSR-250中的注解如@Resource/@PostConstruct/@PreDestroy
还需下列jar文件
lib\j2ee\common-annotations.jar
二、只是使用spring框架若使用注解方式
只要加一些命名空间和开启解析器
并且@Resource需要加lib\j2ee\common-annotations.jar
打开处理器
三、要自动扫描
只要开启解析器和一些命名空间
四、spring框架采用aop编程
需要导入一些命名空间
xmlns:aop.......
开启解析器
如果使用到了切面编程(AOP),还需要下列jar文件
lib\aspectj\aspectjweaver.jsr 和 aspectjrt.jar
lib\cglib\cglib-nodep-2.1_3.jar
五、spring+Jdbc开发
需要数据源文件 lib\jakarta-commons\commons-pool.jar、lib\jakarta-commons\commons-dbcp.jar
1、spring文件 :
dist\spring.jar、
lib\jakarta-commons\commons-logging.jar
2、jdbc驱动文件 mysql**** sql*** :
导入tx命名空间
对事务注解的解析器
六、spring2.5+hibernate3.3+struts1.3
(1)、hibernate核心包
hibernate3.jar
lib\required*.jar
lib\optional\ehcache-1.2.3.jar (二级缓存文件)
hibernate注解包
lib\test\slf4j-log4j12.jar
(2)、spring包
dist\spring.jar
lib\jakarta-commons\commons-logging.jar 和commons-pool.jar、commons-dbcp.jar(后为数据源文件)
dist\modules\spring-webmvc-struts.jar (与struts1的集成)
lib\aspectj\aspectjweaver.jsr 和 aspectjrt.jar (Aop文件)
lib\cglib\cglib-nodep-2.1_3.jar (Aop文件)
lib\j2ee\common-annotations.jar (注解文件)
lib\log4j\log4j-1.2.15.jar
(3)、sturs1.3.8
建议将jstl-1.0.2.jar和standard-1.0.2.jar文件更换为1.1版本此时JSTL文件
还有spring已存在antlr-2.7.6.jar文件所以将struts中的antlr-2.7.6.jar文件删除以免冲突
数据库驱动
mysql*** sql****根据需求换
如果在web容器实例spring容器
加文件到web.xml......
如果action让容器管理,则path(Struts的配置文件)和name(Spring配置文件)要一致
还必须在struts的配置文件里加一个控制器
spring为struts1.3解决乱码问题
在web.xml配置一个filter
七、spring2.5+hibernate3.3+struts2整合开发
struts2文件lib里面所有不带-plugin结尾的jar文件,但除了struts2-spring-plugin-2.0.11.1.jar


浙公网安备 33010602011771号