SpringBoot基本教程

介绍

简化Spring应用开发的一个框架、整个Spring技术栈的一个大整合。

Spring Framework架构图

IOC 和 AOP

IOC 控制反转 和 DI 依赖注入

IOC (Inversion of Controller) 控制反转。Spring提供一个IOC容器,使用对象从手动new方式替换成Spring容器来提供对象。这种对象创建控制权由自己手动创建转移到Spring创建即为控制反转。 IOC容器负责对象的创建、初始化等一些列操作。被创建或被管理的对象在IOC容器中称为Bean

DI (Dependency Injection) 依赖注入。在容器中建立bean与bean之间的依赖关系整个过程称为依赖注入。

定义bean

xml配置

xml 复制代码
<bean id="person"  class="com.zjx.test.Person" ></bean>

注解配置

java 复制代码
@ComponentScan
@Component 一般用在公共组件上
- @Controller 一般用在控制层
- @Service 一般用在业务层
- @Repository 一般用在数据层

通过这种@Component扫描注解的方式定义bean的前提是:需要先配置扫描路径

设置依赖注入

1、构造器方式

默认使用了无参构造器创建bean

xml 复制代码
<bean id="person" class="com.zjx.test.Person">
</bean>

使用有参的构造器,通过<constructor-arg>标签来完成配置

xml 复制代码
<bean id="person" class="com.zjx.test.Person">
   <constructor-arg index="0" value="zjx"></constructor-arg>
   <constructor-arg index="1" ref="anotherPerson"></constructor-arg>
</bean>
  • index表示下标,从0开始。
  • value表示常量值
  • ref表示引用另一个bean
2、Setter注入方式

spring还提供了另外一种思路:通过setter方法设置bean所需参数,这种方式耦合性相对较低,比有参构造器使用更为广泛。

java 复制代码
@Data
public class Person {
    private String name;
    private int age;
}

然后在bean.xml文件中配置bean时,加上<property>标签设置bean所需参数。

xml 复制代码
<bean id="person" class="com.zjx.test.Person">
   <property name="name" value="zjx"></constructor-arg>
   <property name="age" value="18"></constructor-arg>
</bean>
3、@Autowired 配合 @Qualifer

注意@Qualifer不能独立使用,必须搭配@Autowired

java 复制代码
public class MyBeanConfiguration {
    @Bean
    public User user() {
        return new User("markus", 24);
    }
}
java 复制代码
@Import({
        com.zjx.test.MyBeanConfiguration.class
})
public class AutowiredDemo {
    @Autowired
    private User user;

}

当Spring容器中有多个相同类型的Bean时,它还可以与@Qualifier配合使用来指定某一特定的Bean

java 复制代码
public class SameTypeBeanConfiguration {
    @Bean
    public User user1() {
        return new User("markus", 24);
    }

    @Bean
    public User user2() {
        return new User("Luna", 23);
    }
}
java 复制代码
public class QualifierAnnotationUseDemo {
    @Autowired
    @Qualifier(value = "user1")
    private User user;
}
4、@Value

@Value 是 Spring 提供的一个注解,用于从配置文件或其他来源(如系统环境变量、SpEL 表达式)中读取值并注入到 Bean 的字段或方法参数中。

yml 复制代码
app:
  name: Spring Boot Demo
  version: 1.0.0
java 复制代码
@Component
public class AppConfig {
    @Value("${app.name}")
    private String appName;
    @Value("${app.version}")
    private String appVersion;
    public void printConfig() {
        System.out.println("Application Name: " + appName);
        System.out.println("Application Version: " + appVersion);
    }
}

@Value 注解支持 Spring 表达式语言(SpEL),可用于动态计算值。

java 复制代码
@Component
public class SpELExample {
    @Value("#{2 * 5}")
    private int result;

    public void printResult() {
        System.out.println("Result: " + result);
    }
}

@ConfigurationProperties

java 复制代码
person
    name:zjx
    age:18
    
@Configuration
@ConfigurationProperties(prefix = "person")
public class PersonProperties {
    private String name;
    private Integer age;

    // getter & setter
}

@Value@ConfigurationProperties 对比

5、@Resouce

@Resource和@Autowired两个注解的区别及说明

@Autowired是Spring 里面提供的一个注解,它默认是根据类型 来实现Bean的依赖注入。@Autowired里面有一个required属性,默认值是true 表示强制要求bean实例的一个注入,在应用启动的时候,如果IOC容器中不存在对应类型的bean,那么启动就会报错;如果我们不希望实现依赖注入就可以把这个属性设置为false。

  • @Primary表示主要的Bean,当存在多个相同类型的Bean的时候,会优先使用声明了@Primary注解的一个Bean
  • @Qualifier 相当于条件筛选,可以根据Bean的名字可以去找到需要装配的目标Bean

@Resource是JDK中提供的一个注解。最大的区别就是@Resource可以支持ByName 和 ByType两种注入方式;

  • 如果使用name属性,spring会根据bean的名字来进行依赖注入;
  • 如果使用type属性,spring会根据bean的类型来进行依赖注入,如果两个属性都没有进行设置,@Resource默认是根据定义的属性名字去容器中进行匹配,如果没有匹配成功,再根据类型来匹配;
  • 如果两个都没有匹配到就会报错

配置第三方Bean(引入外部配置Bean)

1、静态工厂

这种方式的关键是需要定义一个工厂类,它里面包含一个创建bean的静态方法。例如:

java 复制代码
public class MyBeanFactory {
    public static Person createPerson(String name, int age) {
        return new Person(name, age);
    }
}
java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person {
    private String name;
    private int age;
}

在bean.xml文件中配置bean时,通过factory-method参数指定静态工厂方法,同时通过<constructor-arg>设置相关参数。

xml 复制代码
<bean class="com.zjx.test.MyBeanFactory" factory-method="createPerson">
   <constructor-arg index="0" value="zjx"></constructor-arg>
   <constructor-arg index="1" value="18"></constructor-arg>
</bean>
2、实例工厂

这种方式也需要定义一个工厂类,但里面包含非静态的创建bean的方法。

java 复制代码
public class MyBeanFactory {
    public Person createPerson(String name, int age) {
        return new Person(name, age);
    }
}

然后bean.xml文件中配置bean时,需要先配置工厂bean。然后在配置实例bean时,通过factory-bean参数指定该工厂bean的引用。

java 复制代码
<bean id="myBeanFactory" class="com.zjx.test.MyBeanFactory">
</bean>
<bean factory-bean="myBeanFactory" factory-method="createPerson">
   <constructor-arg index="0" value="zjx"></constructor-arg>
   <constructor-arg index="1" value="18"></constructor-arg>
</bean>
3、FactoryBean

上面的实例工厂方法每次都需要创建一个工厂类,不方面统一管理。这时我们可以使用FactoryBean接口。

java 复制代码
public class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

在它的getObject方法中可以实现我们自己的逻辑创建对象,并且在getObjectType方法中我们可以定义对象的类型。

xml 复制代码
<bean id="userFactoryBean" class="com.sue.async.service.UserFactoryBean">
</bean>

注意:getBean("userFactoryBean");获取的是getObject方法中返回的对象。而getBean("&userFactoryBean");获取的才是真正的UserFactoryBean对象。

4、@Bean

@Component系列注解虽说使用起来非常方便,但是bean的创建过程完全交给spring容器来完成,我们没办法自己控制。

spring从3.0以后,开始支持JavaConfig的方式定义bean。它可以看做spring的配置文件,但并非真正的配置文件,我们需要通过编码java代码的方式创建bean。例如:

java 复制代码
@Configuration
public class MyConfiguration {
    @Bean
    public Person person() {
        return new Person();
    }
}

在JavaConfig类上加@Configuration注解,相当于配置了<beans>标签。而在方法上加@Bean注解,相当于配置了<bean>标签。

5、@Conditional注解

springboot还引入了一些列的@Conditional注解,用来控制bean的创建。

java 复制代码
@Configuration
public class MyConfiguration {
    @ConditionalOnClass(Country.class)
    @Bean
    public Person person() {
        return new Person();
    }
}

@ConditionalOnClass注解的功能是当项目中存在Country类时,才实例化Person类。换句话说就是,如果项目中不存在Country类,就不实例化Person类。

这个功能非常有用,相当于一个开关控制着Person类,只有满足一定条件才能实例化。

spring中使用比较多的Conditional还有:

  • ConditionalOnBean
  • ConditionalOnProperty
  • ConditionalOnMissingClass
  • ConditionalOnMissingBean
  • ConditionalOnWebApplication
6、@Import

通过前面介绍的@Configuration和@Bean相结合的方式,我们可以通过代码定义bean。但这种方式有一定的局限性,它只能创建该类中定义的bean实例,不能创建其他类的bean实例,如果我们想创建其他类的bean实例该怎么办呢?

这时可以使用@Import注解导入。

java 复制代码
@Data
public class Role {
    private Long id;
    private String name;
}

使用@Import注解导入Role类

java 复制代码
@Import(Role.class)
@Configuration
public class MyConfig {
}

然后在调用的地方通过@Autowired注解注入所需的bean。

java 复制代码
@RequestMapping("/")
@RestController
public class TestController {
    @Autowired
    private Role role;

    @GetMapping("/test")
    public String test() {
        System.out.println(role);
        return "test";
    }
}

聪明的你可能会发现,我没有在任何地方定义过Role的bean,但spring却能自动创建该类的bean实例,这是为什么呢?

这也许正是@Import注解的强大之处。

此时,有些朋友可能会问:@Import注解能定义单个类的bean,但如果有多个类需要定义bean该怎么办呢?

恭喜你,这是个好问题,因为@Import注解也支持。

java 复制代码
@Import({Role.class, User.class})
@Configuration
public class MyConfig {
}

@Import参数需要的是一个数组,可以引入多个配置类。 @Import注解在配置类中只能写一次。下面方式不允许的。

java 复制代码
@Import(Role.class)
@Import(User.class)
@Configuration
public class Myconfig {
}

作用范围

@Scope 定义bean作用范围,默认值singleton(单例)、可选值prototype(非单例)、requestweb(请求)、sessionweb(会话)

作用域范围

  • singleton单例范围,Spring中bean的实例默认都是单例的。
  • prototype原型范围,这个使用较少,这种作用域的bean,每次注入调用,Spring都会创建返回不同的实例,但是,需要注意的是,如果未指明代理类型,即不使用代理的情况下,将会在容器启动时创建bean,那么每次并不会返回不同的实例,只有在指明作用域代理类型例如TARGET_CLASS后,才会在注入调用每次创建不同的实例。
  • requestweb请求范围,当使用该作用域范围时(包括下面的session作用域),必须指定proxyMode作用域代理类型,否则将会报错,对于request作用域的bean,Spring容器将会创建一个代理用作依赖注入,只有在请求时并且请求的处理中需要调用到它,才会实例化该目标bean。
  • sessionweb会话范围,这个和request类似,同样必须指定proxyMode,而且也是Spring容器创建一个代理用作依赖注入,当有会话创建时,并且在会话中请求的处理中需要调用它,才会实例话该目标bean,由于是会话范围,生命依赖于session。

生命周期

java 复制代码
@Component
public class MyBean {

    @PostConstruct
    public void init() {
        // 初始化逻辑
        System.out.println("Bean 初始化完成,执行 @PostConstruct 方法");
    }
    @PreDestroy
    public void init() {
        // 销毁
        System.out.println("执行 @PreDestroy 方法");
    }
}

AOP 面向切面编程

AOP(Aspect Oriented Programming)即面向切面编程,是对某一类事件的集中处理。面向切面编程(AOP)是一种编程范式,旨在将横切关注点(如日志记录、事务管理、权限验证等)从业务逻辑代码中分离出来,从而提高代码的可重用性、可维护性和模块性。

Spring AOP 通过代理模式在运行时动态地将横切关注点织入到目标对象中。

AOP 的组成:切面(Aspect)、切点(Pointcut)、通知(Advice)。AOP 的主要核心概念有:

切面(Aspect):

定义:切面是一个模块,它封装了横切关注点,包含了定义切点和通知的代码。 作用:将横切关注点模块化,便于复用和管理

连接点(Join Point):

定义:程序执行过程中能够插入切面的点,如方法调用、异常抛出等。 在Spring AOP中:连接点通常是方法的调用。

切点(Pointcut):

定义:切点定义了一组连接点,用于确定通知应该在哪些连接点上执行。 表示方式:通常使用表达式来匹配连接点,如AspectJ表达式。

通知(Advice):

定义:通知是切面在某个连接点执行的动作,它包含了在连接点执行的代码。 类型:

  • 前置通知(Before):在目标方法执行前执行。
  • 后置通知(After):在目标方法执行后执行。
  • 返回通知(After Returning):在目标方法成功执行后执行。
  • 异常通知(After Throwing):在目标方法抛出异常后执行。
  • 环绕通知(Around):在目标方法执行前后执行,并可以控制目标方法的执行。
xml 复制代码
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getuser")
    public String getUser() {
        System.out.println("hello user");
        return "hello user";
    }
}

对UserController下的所有方法进行增强

java 复制代码
//定义切面 一个切面类可以有多个切入点
@Aspect
@Component
public class UserAspect {
    //定义切点
    @Pointcut("execution(* com.zjx.demo.controller.UserController.* (..))")
    public void myPointCut(){
        //@Pointcut注解不用定义方法内容,myPointCut方法不会执行
    };
 
    //定义前置通知
    @Before("myPointCut()")
    public void before(){
        System.out.println("执行了前置通知");
    };
 
    //定义后置通知
    @After("myPointCut()")
    public void after() {
        System.out.println("执行了后置通知");
    }
 
    //环绕通知
    @Around("myPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前通知");
        Object ret =  joinPoint.proceed();
        System.out.println("环绕后通知");
        return ret;
    }
 
    //返回之前通知
    @AfterReturning("myPointCut()")
    public void afterReturning() {
        System.out.println("执行return之前的通知");
    }
    
    //返回之前通知 带返回值
    @AfterReturning(value = "myPointCut()", returning = "result")
    public void afterReturning2(JoinPoint jp, Object result) {
        String name = jp.getSignature().getName();
        System.out.println(name + "方法返回值为:" + result);
    }
    
    // 异常通知
    @AfterThrowing(value = "myPointCut()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        String name = jp.getSignature().getName();
        System.out.println(name + "方法抛异常了,异常是:" + e.getMessage());
    }
}

注解说明:

  • @Aspect:表明这是一个切面类。
  • @Pointcut:表明这是一个切入点。
    • execution 中的第一个 * 表示方法返回任意值
    • 第二个 * 表示 service 包下的任意类
    • 第三个 * 表示类中的任意方法,括号中的两个点表示方法参数任意,即这里描述的切入点为service 包下所有类中的所有方法。
  • @Before:表示这是一个前置通知,该方法在目标方法之前执行。通过 JoinPoint 参数可以获取目标方法的方法名、修饰符等信息。
  • @After:表示这是一个后置通知,该方法在目标执行之后执行。
  • @AfterReturning:表示这是一个返回通知,在该方法中可以获取目标方法的返回值。
    • returning 参数是指返回值的变量名,对应方法的参数。
    • 注意:本样例在方法参数中定义 result 的类型为 Object,表示目标方法的返回值可以是任意类型。若 result 参数的类型为 Long,则该方法只能处理目标方法返回值为 Long 的情况。
  • @AfterThrowing:表示这是一个异常通知,即当目标方法发生异常,该方法会被调用。
    • 样例中设置的异常类型为 Exception 表示所有的异常都会进入该方法中执行。
    • 若异常类型为 ArithmeticException 则表示只有目标方法抛出的 ArithmeticException 异常才会进入该方法的处理。
  • @Around:表示这是一个环绕通知。环绕通知是所有通知里功能最为强大的通知,可以实现前置通知、后置通知、异常通知以及返回通知的功能。
    • 目标方法进入环绕通知后,通过调用 ProceedingJointPoint 对象的 proceed 方法使目标方法继续执行,开发者可以在次修改目标方法的执行参数、返回值值,并且可以在此目标方法的异常。

基础配置

不使用spring-boot-starter-parent

  • 通常使用spring-boot-starter-parent提供默认以下配置
  • Java版本默认使用1.8
  • 编码格式使用UTF-8
  • 提供Dependency Management进行项目依赖的版本管理
  • 默认的资源过滤与插件配置
xml 复制代码
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.3.4.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>

使用spring-boot-starter-parent虽然方便,但是一般开发微服务项目或多模块项目一般使用公司自己的parent,这时还想项目依赖统一的版本管理,需要使用dependencyManagement来实现。

xml 复制代码
<properties>
    <java.version>8</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-dependencies</artifactId>
         <version>Hoxton.SR9</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>
    <dependencies>
<dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version> <!-- 使用适合您项目的版本 -->
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

@SpringApplication

@SpringBootApplication是一个3合一注解

java 复制代码
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {   
}

定制Banner

Web容器配置

Tomcat配置

yml 复制代码
server:
#  Web容器端口号
  port: 8080
#  项目出错跳转页面
  error:
    path: /error
  servlet:
#    项目名称路径,不配做时默认 / ,如果配置了,就要在访问路径加上配置的项目名称路径
    context-path: /myproject
#    session失效时间,默认单位秒
    session:
      timeout: 30ms
  tomcat:
#    Tomcat请求编码
    uri-encoding: UTF-8
#    Tomcat最大线程数
    threads:
      max: 200
#      存放Tomcat运行日志和临时文件的目录,若不配置,则默认使用系统的临时目录
    basedir: /home/basedir

HTTPS配置

Properties配置

加载优先级

Profile

每个运行环境(开发、测试、上线)都配置成一个对应profile,这样以后只要修改一下活动profile,应用就可以轻易地在不同的运行环境之间自由切换。就是通过 配置的 profile 快速切换开发环境。

通用配置文件: application.properties或者application.yml

profile相关: application-{profile名}.properties或者application-{profile名}.yml

profile相关的配置文件的优先级更高(后加载,后加载的会覆盖前面加载的)

yml 复制代码
spring:
  profiles:
    active: prod

@Profile("prod") 注解作用:表示这个控制器仅对dev作为活动profile时才生效(就是把开发环境切换成 dev ,这个控制器才生效) application.yml配置文件中使用 spring.profiles.active 属性,用于切换活动profile,意味着最终最多时能有一个活动profile,就是最终只能有一个开发环境,要么正式,要么测试,要么其他,只能有一个开发环境。

整合Web开发

返回Json数据

@RestController

自定义JSON转换器

第一种:默认的 jackson-databind

默认情况下,类上使用 @Controller 注解,方法上使用 @ResponseBody 注解,返回的对象会默认被转换成 JSON 格式;

另外,@RestController 注解是 @Controller 注解 和 @ResponseBody 注解的组合,是等效的!

第二种:使用 Gson

1、Gson简介 GSON 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个JSON 字符转成一个 Java 对象,或者将一个 Java对象 转化为 JSON 字符串。

特点: 快速、高效;代码量少、简洁;面向对象;数据传递和解析方便

2、使用步骤

第一步:在 pom.xml 中移除默认的 jackson-databind ,引入 Gson 依赖

xml 复制代码
<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--gson-->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

第二步:自定义 HttpMessageConverter

Spring Boot 已经默认提供了 Gson 的自动转换类 GsonHttpMessageConvertersConfigurations,因此 Gson 的以来添加之后,可以直接像使用 jackson-databind 那样直接使用 gson 。但是在 Gson 进行转换时,如果相对日期进行格式化,那么需要开发者自定义 HttpMessageConverter !

java 复制代码
package com.zibo.api.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.GsonHttpMessageConverter;

import java.lang.reflect.Modifier;

@Configuration
public class GSONConfig {
    @Bean
    GsonHttpMessageConverter gsonHttpMessageConverter(){
        // 自己提供一个 GSONHttpMessageConverter 实例
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        GsonBuilder builder = new GsonBuilder();
        // 设置解析式日期的格式
        builder.setDateFormat("yyyy-MM-dd");
        // 设置解析时修饰符为 protected 的字段被过滤掉
        builder.excludeFieldsWithModifiers(Modifier.PROTECTED);
        // 创建 Gson 对象,放入 converter 实例并返回
        Gson gson = builder.create();
        converter.setGson(gson);
        return converter;
    }
}

第三种:使用 fastjson

1、简介

fastjson 是阿里巴巴 的一个开源的 JSON 解析框架,是目前 JSON 解析速度最快 的开源框架,该框架也可以集成到 Spring Boot 中,大但并不能立即使用!需要提供相应的 HttpMessageConverter 后才能使用!

2、使用步骤

第一步:在 pom.xml 中移除默认的 jackson-databind ,引入 fastjson 依赖

xml 复制代码
<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--fast json-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

第二步:自定义 HttpMessageConverter

java 复制代码
package com.zibo.api.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;

@Configuration
public class MyFastJsonConfig {
    @Bean
    FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
        // 自己提供一个 FastJsonHttpMessageConverter 实例
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        // 设置解析式日期的格式
        config.setDateFormat("yyyy-MM-dd");
        // 设置解析时编码格式为 UTF-8
        config.setCharset(StandardCharsets.UTF_8);
        config.setSerializerFeatures(
                SerializerFeature.WriteClassName,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty
        );
        converter.setFastJsonConfig(config);
        return converter;
    }
}

另一种配置方式

java 复制代码
package com.zibo.api.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class MyWebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 自己提供一个 FastJsonHttpMessageConverter 实例
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        // 设置解析式日期的格式
        config.setDateFormat("yyyy-MM-dd");
        // 设置解析时编码格式为 UTF-8
        config.setCharset(StandardCharsets.UTF_8);
        config.setSerializerFeatures(
                SerializerFeature.WriteClassName,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty
        );
        converter.setFastJsonConfig(config);
        converters.add(converter);
    }
}

静态资源访问

文件上传

@ControllerAdvice

自定义错误页

CORS支持

配置类与XML配置

注册拦截器

启动系统任务

整合Servlet、Filter和Listener

路径映射

其他注解

@PropertySource

整合持久层

整合JdbcTemplate

整合MyBatis

整合Spring Data JPA

多数据源

整合NoSQL

整合Redis

整合MongoDB

Session共享

构建RESTful服务

REST简介

JPA实现REST

MongoDB实现REST

SpringBoot缓存

Ehcache 2.x缓存

Redis单机缓存

Redis集群缓存

SpringBoot安全管理

SpringSecurity

shiro

消息服务

JMS

AMQP

企业开发

邮件发送

定时任务

批处理

Swagger2

数据校验

应用监控

端点配置

监控信息可视化

邮件报警

整合WebSocket

开发工具与单元测试

devtools

单元测试

项目构建与部署

JAR

WAR

原理

相关推荐
你说你说你来说1 小时前
安卓广播接收器(Broadcast Receiver)的介绍与使用
android·笔记
你说你说你来说1 小时前
安卓Content Provider介绍及使用
android·笔记
珊瑚里的鱼2 小时前
【双指针】专题:LeetCode 202题解——快乐数
开发语言·c++·笔记·算法·leetcode·职场和发展
美味的大香蕉6 小时前
Spark-SQL
笔记
踢足球的程序员·6 小时前
OpenGL学习笔记(立方体贴图、高级数据、高级GLSL)
笔记·学习·图形渲染
WarPigs6 小时前
VRoid-Blender-Unity个人工作流笔记
笔记·blender
米小葱7 小时前
【图解】系统设计学习笔记
笔记·学习
pumpkin845148 小时前
学习笔记十二——Rust 高阶函数彻底入门(超详细过程解析 + 每步数值追踪)
笔记·学习·rust
OKay_J9 小时前
蓝桥杯备赛笔记(嵌入式)
笔记·stm32·学习·蓝桥杯
牧木江9 小时前
【从C到C++的算法竞赛迁移指南】第二篇:动态数组与字符串完全攻略 —— 写给C程序员的全新世界
c语言·c++·经验分享·笔记·算法