Spring初体验

目录

IOC&&DI

一、IOC

1. 快速入门

1.1 导入Spring开发的基本坐标

1.2 编写相应的实体类

1.3 创建核心配置文件applicationContext.xml

1.4 在配置文件中配置Bena实例

1.5 使用 Spring 的 API 获得 Bean 实例

2. Spring配置文件

2.1 Bean标签

2.2 Bean标签范围配置

2.3 Bean生命周期配置

3.4 Bean实例化的三种方式

二、DI

1. 快速入门

2. 依赖注入的方式

2.1 Bean依赖注入的数据类型

2.2 引入其它配置文件

三、Spring相关API

1.1 ApplicationContext的继承体系

1.2 ApplicationContext的实现类

1.3 getBean()方法使用

四、Spring配置第三方Bean

1.配置DataSource数据源步骤

1.1 导入数据源的坐标和数据库驱动坐标

1.2 创建数据源基本配置文件

1.3 在配置文件中导入数据源配置文件

1.4 在xml文件中配置数据源的Bean

五、Spring注解开发

1.1 Spring原始注解[不会取代xml文件,只需要开启组件扫描]

1.2 Spring新注解

六、 Spring集成Junit

1. 步骤

1.1 导入spring集成Junit的坐标

1.2 使用@Runwith注解替换原来的运行期

1.3 使用@ContextConfiguration指定配置文件或配置类

1.4 使用@Autowired注入需要测试的对象

1.5 创建测试方法进行测试

AOP

1. 实现方式 : 动态代理

2. 专业术语

3. 实现AOP

4. xml实现AOP步骤

4.1 导入 AOP 相关坐标

4.2 创建目标接口和目标类(内部有切点)

4.3 创建切面类(内部有增强方法)

4.4 将目标类和切面类的对象创建权交给 spring

4.5 applicationContext.xml 中配置织入关系

4.6 测试代码

5. xml配置AOP详解

6. 注解实现AOP步骤

6.3 将目标类和切面类的对象创建权交给 spring

6.4 在切面类中使用注解配置织入关系

6.5 在配置文件中开启组件扫描和 AOP 的自动代理

6.6 测试

7. 注解类详解

7.1 切点表达式的抽取

MVC

1. 快速入门

1.1 导入SpringMVC相关坐标

1.2 在web.xml配置SpringMVC的核心控制器

1.3 创建Controller和业务方法

1.4 配置注解

1.5 创建spring-mvc.xml

1.6 测试

2. 回写数据

2.1 SpringMVC的数据响应-回写数据-直接回写字符串(应用)

2.2 SpringMVC的数据响应-回写数据-直接回写json格式字符串(应用)

2.3 SpringMVC的数据响应-回写数据-JSON格式[自动转换]

3. SpringMVC的请求

3.1 SpringMVC的请求-获得请求参数-配置全局乱码过滤器

3.2 请求中注解的使用

3.3 Restful风格的参数的获取

3.4 自定义类型转换器

3.5 获得请求参数-获得Servlet相关API

3.6 -SpringMVC的请求-获得请求参数-获得请求头信息

4. 拦截器

4.1 快速入门

4.2 拦截器结论

5. SpringMVC异常处理机制

5.1 异常处理两种方式

5.2 简单异常处理器SimpleMappingExceptionResolver

5.3 自定义异常处理步骤

在框架学习中,对Spring的初步理解和使用,Spring是一个非常优秀的框架,不仅仅是在功能上值得我们学习,在源码上我们也可以欣赏大师之作,规范代码书写,本文仅仅是对Spring的初体验

IOC&&DI

一、IOC

1. 快速入门

①导入 Spring 开发的基本包坐标

②编写相应的类

③创建 Spring 核心配置文件

④在 Spring 配置文件中配置Bean实例

⑤使用 Spring 的 API 获得 Bean 实例

1.1 导入Spring开发的基本坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

1.2 编写相应的实体类

public class User {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

1.3 创建核心配置文件applicationContext.xml

在类路径下(resources)创建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">

</beans>

1.4 在配置文件中配置Bena实例

<bean id="user" class="springIOC.domain.User"></bean>

1.5 使用 Spring 的 API 获得 Bean 实例

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println(user);

2. Spring配置文件

2.1 Bean标签

将配置对象的权利交由给Spring容器创建,默认情况下调用类的无参构造器实例化对象,如果无参构造器不存在则不能创建成功

基本属性:

  • id : Bean实例在Spring容器中的唯一标识
  • class : Bean的全限定名称

2.2 Bean标签范围配置

scope:指对象的作用范围,取值如下:

取值范围说明
singleton默认值,单例的
prototype多例的
requestWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
sessionWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
global sessionWEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session

1)当scope的取值为singleton时

​ Bean的实例化个数:1个

​ Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例

​ Bean的生命周期:

对象创建:当应用加载,创建容器时,对象就被创建了

对象运行:只要容器在,对象一直活着

对象销毁:当应用卸载,销毁容器时,对象就被销毁了

2)当scope的取值为prototype时

​ Bean的实例化个数:多个

​ Bean的实例化时机:当调用getBean()方法时实例化Bean

对象创建:当使用对象时,创建新的对象实例

对象运行:只要对象在使用中,就一直活着

对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了

2.3 Bean生命周期配置

init-method:指定类中的初始化方法名称

destroy-method:指定类中销毁方法名称

3.4 Bean实例化的三种方式

1) 使用无参构造方法实例化[常用]

​ 它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败

2) 工厂静态方法实例化

​ 工厂的静态方法返回Bean实例

public class StaticFactoryBean {
    public static Xxx createXxx(){    
    return new Xxx();
    }
}
<bean id="xxx" class="*.*.factory.StaticFactoryBean" 
      factory-method="createXxx" />

3) 工厂实例方法实例化

​ 工厂的非静态方法返回Bean实例

public class DynamicFactoryBean {  
	public Xxx createXxx(){    
    return new Xxx();
    }
}
<bean id="factoryBean" class="*.*.factory.DynamicFactoryBean"/>
<bean id="xxx" factory-bean="factoryBean" factory-method="createXxx"/>

二、DI

1. 快速入门

①导入 Spring 开发的基本包坐标

②编写相应的类,且在一个类A有其它类B的成员变量,则A依赖B

③创建 Spring 核心配置文件

④在 Spring 配置文件中配置A和B的Bean实例,并且将B的Bean注入A的Bena的属性

⑤使用 Spring 的 API 获得A的 Bean 实例,调用A的B

2. 依赖注入的方式

①构造方法

​ 创建有参构造

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    public void di() {
        userDao.di();
    }
}

​ 配置Spring容器调用有参构造时进行注入,注入式constructor-arg中name属性值得value应该是有参构造器中参数的名称

<bean id="userDao" class="springIOC.dao.impl.UserDaoImpl"/>

    <bean id="userService" class="springIOC.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"/>

②set方法

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void di() {
        userDao.di();
    }
}

<bean id="userService" class="springIOC.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

③p命名空间注入

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:

首先,需要引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

<bean id="userService" class="springIOC.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

2.1 Bean依赖注入的数据类型

上面的操作,都是注入的引用Bean,处了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。

注入数据的三种数据类型

普通数据类型

引用数据类型

集合数据类型

2.2 引入其它配置文件

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载

<import resource="applicationContext-xxx.xml"/>

三、Spring相关API

1.1 ApplicationContext的继承体系

applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象

1.2 ApplicationContext的实现类

1)ClassPathXmlApplicationContext

​ 它是从类的根路径下加载配置文件 推荐使用这种

2)FileSystemXmlApplicationContext

​ 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

3)AnnotationConfigApplicationContext

​ 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

1.3 getBean()方法使用

public Object getBean(String name) throws BeansException {  
	assertBeanFactoryActive();   
	return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException {   			    	assertBeanFactoryActive();
	return getBeanFactory().getBean(requiredType);
}

其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。

当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错

getBean()方法使用

ApplicationContext applicationContext = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
  UserService userService1 = (UserService) applicationContext.getBean("userService");
  UserService userService2 = applicationContext.getBean(UserService.class);

四、Spring配置第三方Bean

1.配置DataSource数据源步骤

①导入数据源的坐标和数据库驱动坐标

②创建数据源基本配置文件

③在配置文件中导入数据源配置文件

④在xml文件中配置数据源的Bean

1.1 导入数据源的坐标和数据库驱动坐标

<!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

1.2 创建数据源基本配置文件

在类路径下(resources)创建properties配置文件

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
# 初始化连接数量
jdbc.initialSize=5
# 最大连接数
jdbc.maxActive=10
# 最大等待时间
jdbc.maxWait=3000

1.3 在配置文件中导入数据源配置文件

导入context命名空间和规范

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

引入properties文件

<!--引入properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

1.4 在xml文件中配置数据源的Bean

spel表达式 : spring底层核心之一

<!--配置bean-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
        <property name="maxWait" value="${jdbc.maxWait}"/>
    </bean>

五、Spring注解开发

1.1 Spring原始注解[不会取代xml文件,只需要开启组件扫描]

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

Spring原始注解主要是替代的配置

注解说明
@Component使用在类上用于实例化Bean
@Controller使用在web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入,通过反射直接对属性赋值,既不是set方法也不是构造方法
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource相当于@Autowired+@Qualifier,按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestroy使用在方法上标注该方法是Bean的销毁方法

注意:

使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。

<!--注解的组件扫描-->
<context:component-scan base-package="com.itheima"></context:component-scan>

使用@Value进行字符串的注入

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("注入普通数据")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

1.2 Spring新注解

注解说明
@Configuration用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解,代替配置文件
@ComponentScan用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 扫描包相同
@Bean使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource用于加载.properties 文件中的配置
@Import用于导入其他配置类

@Configuration

@ComponentScan

@Import

@Configuration
@ComponentScan("com.itheima")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}


@PropertySource

@value

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


@Bean

@Bean(name="dataSource")
public DataSource getDataSource() throws PropertyVetoException { 
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource;
} 

测试加载核心配置类创建Spring容器

AnnotationConfigApplicationContext(SpringConfiguration.class);  

六、 Spring集成Junit

1. 步骤

①导入spring集成Junit的坐标

②使用@Runwith注解替换原来的运行期

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注入需要测试的对象

⑤创建测试方法进行测试

1.1 导入spring集成Junit的坐标

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

1.2 使用@Runwith注解替换原来的运行期

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}

1.3 使用@ContextConfiguration指定配置文件或配置类

@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

1.4 使用@Autowired注入需要测试的对象

1.5 创建测试方法进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class IOCTest {
    @Autowired
    private UserService userService;

    @Test
    public void t1(){
        userService.di();
    }
}

AOP

1. 实现方式 : 动态代理

常用的动态代理技术

JDK 代理 : 基于接口的动态代理技术

cglib 代理:基于父类的动态代理技术

2. 专业术语

  • Target(目标对象):代理的目标对象
  • Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类
  • Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点[方法]
  • Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义[已经被增强了的方法]
  • Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知[增加的功能]
  • Aspect(切面):是切入点和通知(引介)的结合
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入

3. 实现AOP

1)需要编写的内容

  • 编写核心业务代码(目标类的目标方法)
  • 编写切面类,切面类中有通知(增强功能方法)
  • 在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合

2)AOP 技术实现的内容

Spring 框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。

3)AOP 底层使用哪种代理方式

在 spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。

4. xml实现AOP步骤

①导入 AOP 相关坐标

②创建目标接口和目标类(内部有切点)

③创建切面类(内部有增强方法)

④将目标类和切面类的对象创建权交给 spring

⑤在 applicationContext.xml 中配置织入关系

⑥测试代码

4.1 导入 AOP 相关坐标

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

4.2 创建目标接口和目标类(内部有切点)

public interface TargetInterface {
    public void method();
}

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

4.3 创建切面类(内部有增强方法)

public class MyAspect {
    //前置增强方法
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

4.4 将目标类和切面类的对象创建权交给 spring

xml

<!--目标类-->
    <bean id="target" class="springAop.target.impl.Target"></bean>
    <!--切面类-->
    <bean id="myAspect" class="springAop.aspect.MyAspect"></bean>

4.5 applicationContext.xml 中配置织入关系

导入aop命名空间

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd

配置切点表达式和前置增强的织入关系

<aop:config>
        <!--引用myAspect的Bean为切面对象-->
        <aop:aspect ref="myAspect">
            <!--配置Target的method方法执行时要进行myAspect的before方法前置增强-->
            <aop:before method="before" pointcut="execution(public void springAop.target.impl.Target.method())"/>
        </aop:aspect>
    </aop:config>

4.6 测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class AOPTest {
    @Autowired
    TargetInterface target;

    @Test
    public void t1(){
        target.method();
    }
}

5. xml配置AOP详解

1) 切点表达式的写法

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

  • 访问修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号* 代表任意
  • 包名与类名之间一个点 . 代表当前包下的类,两个点 … 表示当前包及其子包下的类
  • 参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表

例如:

execution(public void com.itheima.aop.Target.method())	
execution(void com.itheima.aop.Target.*(..))
execution(* com.itheima.aop.*.*(..))
execution(* com.itheima.aop..*.*(..))
execution(* *..*.*(..))

2) 通知的类型

通知的配置语法:

<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"/>

名称标签说明
前置aop:before
后置aop:after-returning
环绕aop:around
异常抛出通知aop:throwing
最终通知aop:after

3) 切点表达式的抽取

当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用 pointcut-ref 属性代替 pointcut 属性来引用抽取后的切点表达式。

<aop:config>
    <!--引用myAspect的Bean为切面对象-->
    <aop:aspect ref="myAspect">
        <aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"/>
        <aop:before method="before" pointcut-ref="myPointcut"></aop:before>
    </aop:aspect>
</aop:config>

6. 注解实现AOP步骤

①创建目标接口和目标类(内部有切点)

②创建切面类(内部有增强方法)

③将目标类和切面类的对象创建权交给 spring

④在切面类中使用注解配置织入关系

⑤在配置文件中开启组件扫描和 AOP 的自动代理

⑥测试

6.1

6.2

6.3 将目标类和切面类的对象创建权交给 spring

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}
@Component("myAspect")
public class MyAspect {
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

6.4 在切面类中使用注解配置织入关系

@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("execution(* com.itheima.aop.*.*(..))")
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

6.5 在配置文件中开启组件扫描和 AOP 的自动代理

<!--组件扫描-->
<context:component-scan base-package="com.itheima.aop"/>

<!--aop的自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

6.6 测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired
    private TargetInterface target;
    @Test
    public void test1(){
        target.method();
    }
}

7. 注解类详解

7.1 切点表达式的抽取

同 xml配置
aop 一样,我们可以将切点表达式抽取。抽取方式是在切面内定义方法,在该方法上使用@Pointcut注解定义切点表达式,然后在在增强注解中进行引用。具体如下:

@@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("MyAspect.myPoint()")
    public void before(){
        System.out.println("前置代码增强.....");
    }
    
    @Pointcut("execution(* com.itheima.aop.*.*(..))")
    public void myPoint(){}
}

MVC

1. 快速入门

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

1.1 导入SpringMVC相关坐标

<!--servlet坐标-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
		
		 <!--springMVC-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

1.2 在web.xml配置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>


1.3 创建Controller和业务方法

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("login running ...");
        return "hello mvc";
    }
}

1.4 配置注解

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("login running ...");
        return "hello mvc";
    }
}

1.5 创建spring-mvc.xml

开启组件扫描

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!--配置注解扫描-->
    <context:component-scan base-package="springMVC.controller"/>
</beans>

1.6 测试

2. 回写数据

2.1 SpringMVC的数据响应-回写数据-直接回写字符串(应用)

通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数据,此时不需要视图跳转,业务方法返回值为void

将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回

@RestController自带有@ResponseBody,该类的所有方法都直接返回数据

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("login running ...");
        return "hello mvc";
    }
}

2.2 SpringMVC的数据响应-回写数据-直接回写json格式字符串(应用)

@RequestMapping(value="/quick8")
    @ResponseBody
    public String save8() throws IOException {
        return "{\"username\":\"zhangsan\",\"age\":18}";
    }

手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串,我们可以使用web阶段学习过的json转换工具jackson进行转换,通过jackson转换json格式字符串,回写字符串

@RequestMapping(value="/quick9")
    @ResponseBody
    public String save9() throws IOException {
        User user = new User();
        user.setUsername("lisi");
        user.setAge(30);
        //使用json的转换工具将对象转换成json格式字符串在返回
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);

        return json;
    }

2.3 SpringMVC的数据响应-回写数据-JSON格式[自动转换]

①导入Jackson坐标

 <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.8</version>
        </dependency>

②在Spring-xml.xml配置文件中使用mvc:annotation-driven/

在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置

<mvc:annotation-driven/>

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。

使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和

RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用

<mvc:annotation-driven />替代注解处理器和适配器的配置。

同时使用<mvc:annotation-driven />

默认底层就会集成jackson进行对象或集合的json格式字符串的转换

3. SpringMVC的请求

①get请求参数名称和方法中参数名称相同时可以自动装配,并转换类型

②post请求表单数据,如果表单中name名称和实体类名称相同,可以自动封装成对象

③post请求JSON数据时,可以添加注解@RequestBody标签,自动从请求体中获取数据并封装成对象

3.1 SpringMVC的请求-获得请求参数-配置全局乱码过滤器

当post请求时,数据会出现乱码,我们可以在web.xml中设置一个过滤器来进行编码的过滤。

<!--配置全局过滤的filter-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.2 请求中注解的使用

@RequestParam : 当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定

@RequestBody : 从请求体中获取JSON格式的数据

3.3 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注解进行占位符的匹配获取工作。

@GetMapping("/findById/{id}")
    public User findById(@PathVariable("id") Integer id){
        System.out.println(id);
        //1.伪造User对象
        User user = new User();
        user.setUserName("张三");
        user.setUserAge(18);
        return user;
    }

@PathVariable(“id”)中属性值必须和上面访问路径中占位符的属性值一样

3.4 自定义类型转换器

3.5 获得请求参数-获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:

HttpServletRequest

HttpServletResponse

HttpSession

    @ResponseBody
    public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
    }

3.6 -SpringMVC的请求-获得请求参数-获得请求头信息

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)

@RequestHeader注解的属性如下:

value:请求头的名称

required:是否必须携带此请求头

 @ResponseBody
    public void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {
        System.out.println(user_agent);
    }

使用@CookieValue可以获得指定Cookie的值

@CookieValue注解的属性如下:

value:指定cookie的名称

required:是否必须携带此cookie

 @ResponseBody
    public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
        System.out.println(jsessionId);
    }

4. 拦截器

Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现

4.1 快速入门

①创建拦截器类实现HandlerInterceptor接口

public class MyInterceptor1 implements HandlerInterceptor {
    //在目标方法执行之前 执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle.....");
        return true;
}
    //在目标方法执行之后 视图对象返回之前执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("postHandle...");
    }
    //在流程都执行完毕后 执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion....");
    }
}

②配置拦截器

配置:在SpringMVC的配置文件中配置

 <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--对哪些资源执行拦截操作-->
            <mvc:mapping path="/**"/>
            <bean class="springMVC.controller.UserController"/>
        </mvc:interceptor>
    </mvc:interceptors>

4.2 拦截器结论

当拦截器的preHandle方法返回true则会执行目标资源,如果返回false则不执行目标资源

多个拦截器情况下,配置在前的先执行,配置在后的后执行

拦截器中的方法执行顺序是:preHandler-------目标资源----postHandle---- afterCompletion

5. SpringMVC异常处理机制

5.1 异常处理两种方式

① 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver

② 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

5.2 简单异常处理器SimpleMappingExceptionResolver

<!--配置简单映射异常处理器-->
    <bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”>    <property name=“defaultErrorView” value=“视图页面”/>   默认错误视图
    <property name=“exceptionMappings”>
        <map>		异常类型		                             错误视图
            <entry key="java.lang.ClassCastException" value="视图"/>
        </map>
    </property>
</bean>

5.3 自定义异常处理步骤

①创建异常处理器类实现HandlerExceptionResolver

public class MyExceptionResolver implements HandlerExceptionResolver {
   @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response, Object handler, Exception ex) {

       try {
           response.getWriter().write(500);
       } catch (IOException e) {
           e.printStackTrace();
       }
       return null;
    }
}

②配置异常处理器

<!--配置异常处理器-->
    <bean id="exceptionResolver"
          class="springMVC.exceptionResolver.MyExceptionResolver"/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值