博客摘录「 Springboot入门到精通(超详细文档)」2025年7月4日

1.Spring Boot返回Json数据及数据封装

  1. Controller 中使用**@RestController**注解即可返回 Json 格式的数据

首先看看@RestController注解包含了什么东西, @ResponseBody 注解是将返回的数据结构转换为 Json 格式

java 复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

Spring Boot 中默认使用的 json 解析框架是 jackson

1.1 Spring Boot 默认对Json的处理

1.1.1 创建实体类

java 复制代码
@Data
public class Student {
    public int studentId;
    public String studentName;
}

1.1.2 创建接口类

java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/json")
public class JsonTest {

    @RequestMapping("/getStudent")
    public Student getStudent() {
        return new Student(18, "小志");
    }

    @RequestMapping("/getStudentList")
    public List<Student> getStudentList() {

        List<Student> list = new ArrayList<>();
        list.add(new Student(18, "小志"));
        list.add(new Student(19, "小庄"));
        list.add(new Student(20, "小王"));

        return list;
    }

    @RequestMapping("/getStudentMap")
    public Map<String,Object> getStudentMap() {

        Map<String,Object> map = new HashMap();

        map.put("学生姓名",new Student(25,"小王"));
        map.put("家庭地址","厦门市惠安县");
        map.put("出生年月",202000326);

        return map;
    }

}

1.1.3 结果展示

java 复制代码
-- /json/getStudent
{"studentId":18,"studentName":"小志"}

-- /json/getStudentList
[{"studentId":18,"studentName":"小志"},{"studentId":19,"studentName":"小庄"},{"studentId":20,"studentName":"小王"}]

-- /json/getStudentMap
{"家庭地址":"厦门市惠安县","学生姓名":{"studentId":25,"studentName":"小王"},"出生年月":202000326}

map 中不管是什么数据类型,都可以转成相应的 json 格式

1.1.4 jackson 中对null的处理

把map中的数据更改,测试jackson 中对null的处理

java 复制代码
 @RequestMapping("/getStudentMap")
    public Map<String,Object> getStudentMap() {

        Map<String,Object> map = new HashMap();

        map.put("学生姓名",new Student(25,"小王"));
        map.put("家庭地址","厦门市惠安县");
        map.put("出生年月",null);

        return map;
    }


--/json/getStudentMap 返回结果
{"家庭地址":"厦门市惠安县","学生姓名":{"studentId":25,"studentName":"小王"},"出生年月":null}

添加 jackson 的配置类

java 复制代码
package org.example.springbootdemo.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
import java.io.IOException;
 
@Configuration
public class JacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString("");
            }
        });
        return objectMapper;
    }
}

-----------------------------------------------------结果如下--------------------------------------------------------------

java 复制代码
{
  "家庭地址": "厦门市惠安县",
  "学生姓名": {
    "studentId": 25,
    "studentName": "小王"
  },
  "出生年月": ""
}

1.2 使用阿里巴巴FastJson的设置

使用 fastJson 时,对 null 的处理和 jackson 有些不同,需要继承 WebMvcConfigurationSupport 类,然后覆盖configureMessageConverters 方法,在方法中,我们可以选择对要实现 null 转换的场景,配置好即可。

java 复制代码
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.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
 
@Configuration
public class fastJsonConfig extends WebMvcConfigurationSupport {
 
    /**
     * 使用阿里 FastJson 作为JSON MessageConverter
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 保留map空的字段
                SerializerFeature.WriteMapNullValue,
                // 将String类型的null转成""
                SerializerFeature.WriteNullStringAsEmpty,
                // 将Number类型的null转成0
                SerializerFeature.WriteNullNumberAsZero,
                // 将List类型的null转成[]
                SerializerFeature.WriteNullListAsEmpty,
                // 将Boolean类型的null转成false
                SerializerFeature.WriteNullBooleanAsFalse,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect);
 
        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(mediaTypeList);
        converters.add(converter);
    }
}

1.3 封装返回的统一数据结构

1.3.1 定义返回统一的json结构

java 复制代码
@Data
public class CommomResult<T> {

    private String code;
    private String message;
    private T data;

    public CommomResult(String code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

1.3.2 修改接口层的返回操作及测试

java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/json")
public class JsonTest {

    @RequestMapping("/getStudent")
    public CommomResult getStudent() {

        //return new Student(18, "小志");
        return new CommomResult("0","查询成功",new Student(18,"小志"));
    }

    @RequestMapping("/getStudentList")
    public CommomResult getStudentList() {

        List<Student> list = new ArrayList<>();
        list.add(new Student(18, "小志"));
        list.add(new Student(19, "小庄"));
        list.add(new Student(20, "小王"));

        //return list;
        return new CommomResult<>("0","查询成功",list);
    }

    @RequestMapping("/getStudentMap")
    public CommomResult getStudentMap() {

        Map<String,Object> map = new HashMap();

        map.put("学生姓名",new Student(25,"小王"));
        map.put("家庭地址","厦门市惠安县");
        map.put("出生年月",null);

        //return map;
        return new CommomResult<>("0","查询成功",map);
    }

}

1.3.3 测试结果

java 复制代码
-- /json/getStudent
{
  "code": "0",
  "message": "查询成功",
  "data": {
    "studentId": 18,
    "studentName": "小志"
  }
}

-- /json/getStudentList
{
  "code": "0",
  "message": "查询成功",
  "data": [
    {
      "studentId": 18,
      "studentName": "小志"
    },
    {
      "studentId": 19,
      "studentName": "小庄"
    },
    {
      "studentId": 20,
      "studentName": "小王"
    }
  ]
}

-- /json/getStudentMap
{
  "code": "0",
  "message": "查询成功",
  "data": {
    "家庭地址": "厦门市惠安县",
    "学生姓名": {
      "studentId": 25,
      "studentName": "小王"
    },
    "出生年月": ""
  }
}

2.使用slf4j进行日志记录

3.Spring Boot中的项目属性配置

3.1 少量配置信息的情况

通过注解,获取当前配置信息

配置文件信息

java 复制代码
server:
  port: 12888

配置类

java 复制代码
@Component
public class ConfigEntity {

    @Value("${server.port}")
    private String port;
}

测试接口层

注意(@value注解的包):

复制代码
import org.springframework.beans.factory.annotation.Value;
java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/test")
public class TestController {

    @Value("${server.port}")
    private String port;

    private final static Logger logger = LoggerFactory.getLogger(TestController.class);

    @RequestMapping("/getConfig")
    public String getConfig() {
        logger.info("获取注解的配置:" + port);
        return "获取配置";
    }

}

结果如下

java 复制代码
-- /test/getConfig
2025-07-18 11:03:10.568  INFO 21816 --- [  XNIO-1 task-1] o.e.s.c.TestController                   : 获取注解的配置:12888

3.2 多个配置信息的情况

java 复制代码
application-dev.yml 文件

# 配置多个微服务的地址
url:
  # 订单微服务的地址
  orderUrl: http://localhost:8002
  # 用户微服务的地址
  userUrl: http://localhost:8003
  # 购物车微服务的地址
  shoppingUrl: http://localhost:8004

情况一的方式,需要添加多个@value注解,情况二则是封装一个url的配置封装类

注意@ConfigurationProperties需要引入依赖,还需补充prefix 参数前缀

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
java 复制代码
@Data
@Component
@ConfigurationProperties(prefix = "url")
public class UrlApplication {

    private String orderUrl;
    private String userUrl;
    private String shoppingUrl;
}

测试接口

java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/test")
public class TestController {

    @Resource
    private UrlApplication urlApplication;

    private final static Logger logger = LoggerFactory.getLogger(TestController.class);

    @RequestMapping("/getConfig")
    public String getConfig() {
        logger.info("获取注解的配置:" + urlApplication.getOrderUrl());
        logger.info("获取注解的配置:" + urlApplication.getShoppingUrl());
        logger.info("获取注解的配置:" + urlApplication.getUserUrl());
        return "获取配置";
    }

}

结果

java 复制代码
-- /test/getConfig
2025-07-18 11:38:27.261  INFO 11612 --- [  XNIO-1 task-1] o.e.s.c.TestController                   : 获取注解的配置:http://localhost:8002
2025-07-18 11:38:27.262  INFO 11612 --- [  XNIO-1 task-1] o.e.s.c.TestController                   : 获取注解的配置:http://localhost:8004
2025-07-18 11:38:27.262  INFO 11612 --- [  XNIO-1 task-1] o.e.s.c.TestController                   : 获取注解的配置:http://localhost:8003

3.3 指定项目配置文件

通过application.yml中的属性:

java 复制代码
spring:
  profiles:
    active: XX

4.Springboot中的MVC支持

Spring Boot 的 MVC 支持主要来介绍实际项目中最常用的几个注解,包括 @RestController@RequestMapping@PathVariable@RequestParam 以及**@RequestBody**。主要介绍这几个注解常用的使用方式和特点。

4.1. @RestController

java 复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

@RestController 注解包含了原来的 @Controller@ResponseBody 注解

@ResponseBody 注解是将返回的数据结构转换为 Json 格式

如果接口返回的是类似 /login 登录页面,那就不能使用 @RestController 注解,因为使用这个注解返回就会解析成json字符串,得使用@Controller注解,且导入 thymeleaf 依赖(请求的路径未在控制器中定义,或对应的 Thymeleaf 模板不存在则报错如下)

4.2. @RequestMapping

@RequestMapping 是一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上。

该注解有6个属性,一般在项目中比较常用的有三个属性:value、method 和 produces。

value 属性:指定请求的实际地址 ,value 可以省略不写

method 属性:指定请求的类型 ,主要有 GET、PUT、POST、DELETE,默认为 GET

produces属性:指定返回内容类型,如 produces = "application/json; charset=UTF-8"

4.3. @PathVariable

@PathVariable 注解主要是用来获取 url 参数

java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/test")
public class TestController {

    @GetMapping("/testRequest/{id}")
    public String testRequest(String id) {
        System.out.println("获取到的id为:" + id);
        return "测试@PathVariable ";
    }

-- /test/testRequest/18
获取到的id为:null

    @GetMapping("/testRequest/{id}")
    public String testRequest(@PathVariable String id) {
        System.out.println("获取到的id为:" + id);
        return "测试@PathVariable ";
    }

-- /test/testRequest/18
获取到的id为:18

}

如果想要 url 中占位符中的 id 值直接赋值到参数 id 中,需要保证 url 中的参数和方法接收参数一致,否则就无法接收。如果不一致的话,其实也可以解决,需要用 @PathVariable 中的 value 属性来指定对应关系。

java 复制代码
  @GetMapping("/testRequest/{name}")
    public String testRequest(@PathVariable(value = "name") String studentName) {
        System.out.println("学生的姓名:" + studentName);
        return "测试@PathVariable ";
    }

支持多个参数的接收。同样地,如果 url 中的参数和方法中的参数名称不同的话,也需要使用 value 属性来绑定两个参数

4.4.@RequestParam

@RequestParam 注解顾名思义,也是获取请求参数的

主要区别在于: @PathValiable 是从 url 模板中获取参数值, 即这种风格的 url:http://localhost:8080/user/{id} ;而 @RequestParam 是从 request 里面获取参数值,即这种风格的 url:http://localhost:8080/user?id=1

java 复制代码
    @GetMapping("/testRequest")
    public String testRequest(@RequestParam(value = "age") String age) {
        System.out.println("学生的年龄:" + age);
        return "测试@PathVariable ";
    }


--/test/testRequest?age=88
学生的年龄:88

除了 value 属性外,还有个两个属性比较常用:

  • required 属性:true 表示该参数必须要传,否则就会报 404 错误,false 表示可有可无。
  • defaultValue 属性:默认值,表示如果请求中没有同名参数时的默认值。

如果表单数据很多,我们不可能在后台方法中写上很多参数,每个参数还要 @RequestParam 注解。针对这种情况,我们需要封装一个实体类来接收这些参数,实体中的属性名和表单中的参数名一致即可。

java 复制代码
@Data
public class User {
    public String userName;
    public String passWord;
}

接口测试类

java 复制代码
@RestController
@CrossOrigin
@RequestMapping("/test")
public class TestController {

    @PostMapping("/form")
    public String form(@RequestParam(value = "userName") String userName ,@RequestParam(value = "passWord") String passWord ) {
        System.out.println("用户名:" + userName);
        System.out.println("密码:" + passWord);
        return "测试@PathVariable ";
    }

    @PostMapping("/form2")
    public String form2(User user) {
        System.out.println("用户名:" + user.userName);
        System.out.println("密码:" + user.passWord);
        return "测试@PathVariable ";
    }

}

---------------------------------------------------------结果-----------------------------------------------------------------

用户名:吕子乔

密码:12138

4.5. @RequestBody

java 复制代码
    @PostMapping("/form3")
    public String form3(@RequestBody User user) {
        System.out.println("用户名:" + user.userName);
        System.out.println("密码:" + user.passWord);
        return "测试@RequestBody ";
    }

---------------------------------------------------------结果-----------------------------------------------------------------

java 复制代码
用户名:陈美嘉
密码:1314520