相关链接

  • Excel目录
  • springboot-annotation on Gitee

目录

  • springboot-annotation
    • 〇、创建springboot项目
    • 一、主程序类
      • 1. @SpringBootApplication
    • 二、Controller层(控制层)
      • 2.1 类注解 TYPE
        • 1. @Controller 注入ioc容器->controller层 ⭐️
        • 2. @RequestMapping 映射->资源目录 ⭐️
        • 3. @ResponseBody 后端 -> 浏览器 json对象⭐️
        • 4. @CrossOrigin 解决跨域问题
      • 2.2 方法注解 METHOD
        • 1. @RequestMapping => 2.1.2 🚕
        • 2. @CrossOrigin => 2.1.4 🚕
      • 2.3 参数注解 PARAMETER
        • 1. @RequestParam 获取 -> get请求参数 ⭐️
        • 2. @RequestBody 浏览器 -> 后端 json数据(post请求)⭐️
        • 3. @PathVariable 获取 -> restful风格请求参数
      • 2.4 合并注解
        • 1. @RestController 注入ioc容器->controller层⭐️
        • 2. @GetMapping Get方式请求资源目录 ⭐️
        • 3. @PostMapping Post方式请求资源目录⭐️
        • 4. @PutMapping Put方式请求资源目录
        • 5. @DeleteMapping Delete方式请求资源目录
        • 6. @PatchMapping Patch方式请求资源目录
      • 2.5 对比
        • 1. @Controller 和 @RestController
        • 2. @RequesetParam、@PathVariable、@RequestBody
        • 3.@Get/Post/Put/Delete/Patch Mapping
    • 三、Service层(服务层) (放入ioc)
      • 3.1 类注解 TYPE
        • 1. @Service 标记服务类->自动bean注册⭐️
        • 2. @Component 标记组件类->自动bean注册⭐️
        • 3. @Configuration 注入容器(手动) -> 自定义组件
      • 3.2 方法注解 METHOD
        • 1. @Bean 手动Bean注册
      • 3.3 注解的注解 ANNOTATION_TYPE
        • 1. @Bean => 3.2.1 🚕
      • 3.4 对比
        • 1. @Service --- @Component --- @Configuration + Bean
    • 四、注入bean(从ioc取)
      • 4.1 字段注解 FIELD
        • 1. @Autowired 容器ioc->获取bean⭐️
        • 2. @Resource 容器ioc->获取bean
        • 3. @Qualifier 容器ioc->(获取时)指定bean
      • 4.2 类注解 TYPE
        • 1. @Resource => 4.1.2 🚕
        • 2. @Qualifier => 4.1.3 🚕
      • 4.3 方法注解 METHOD
        • 1. @Autowired => 4.1.1 🚕
        • 2. @Resource => 4.1.2 🚕
        • 3. @Qualifier => 4.1.3 🚕
      • 4.4 参数注解 PARAMETER
        • 1. @Autowired => 4.1.1 🚕
        • 1. @Qualifier => 4.1.3 🚕
      • 4.5 构造器注解 CONSTRUCTOR
        • 1. @Autowired => 4.1.1 🚕
      • 4.6 注解的注解 ANNOTATION_TYPE
        • 1. @Autowired => 4.1.1 🚕
        • 2. @Qualifier => 4.1.3 🚕
      • 4.6 对比
        • 1. @Autowired --- @Autowired + @Qualifier --- @Resource
    • 五、其他
      • 1. @Alisfor 注解属性等价⭐️
      • 2. @Value 从配置文件中取参数
    • 六、lombok插件
      • 6.1 类注解
        • 1. @Data 实体类常用功能打包⭐️
        • 2. @NoArgsConstructor 无参构造⭐️
        • 3. @AllArgsConstructor 全参构造⭐️
        • 4. @Getter​ ​get方法⭐️
        • 5. @Setter set方法:star:
      • 6.2 lombok失效问题
    • 附录:springboot常见分层(AOP)
      • 1. controller层 @Controller
      • 2. service层 @Service
      • 3. dao层(mapper层) @Repository
      • 5. model层 @Data
      • 6. common层


springboot-annotation


版本:
  JDK:1.8
  Spring:5.3.8
  Springboot:2.5.2
  lombok:1.16.10

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache/POM/4.0.0" xmlns:xsi="http://www.w3/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache/POM/4.0.0 https://maven.apache/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springboot</groupId>
    <artifactId>annotation</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>annotation</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--视图解析器 freemarker-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-- SpringBoot中使用lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

注意: 不同版本之间注解会存在差异,例如@CrossOrigin注解


  • @Component: 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注;
  • @Repository: 用于标注数据访问组件,即DAO组件;
  • @Service: 用于标注业务层组件(业务逻辑);
  • @Controller: 用于标注控制层组件(不包含业务逻辑);

  • DispatcherServlet: 前端控制器 拦截前端所有请求:任务调度和分发;
  • 映射器: Handler 配置的映射对象;
  • 适配器: 通过ModelAndView寻找具体的处理器 Controller,以及Controller与前端进行数据交互;
  • 视图解析器: 根据返回的逻辑视图找到对应的物理视图,并且将其封装成一个View对象,由视图渲染器进行视图的渲染最终展现给用户,有JSP,Volocity,或下面用到的 Freemarker;


〇、创建springboot项目

  • Step1: New Project

  • Step2: Spring Initializr

  • Step3: wait

  • Step4: Java version 8

  • Step5: 导入依赖 Spring web

  • Step7: Finish

  • Step8: Wait (没有Maven的需要配置Maven,过程省略)

  • Step9: Finish (默认端口8080)

  • Step10: 解决pom.xml报红问题(不影响项目运行)File -> Invalidate Caches / Restart... -> Invalidate and Restart 清除缓存并重启IDEA就可以解决


一、主程序类


1. @SpringBootApplication


@SpringBootApplication: 是Sprnig Boot项目的核心注解,目的是开启自动配置。包含以下三个@

  @SpringBootConfiguration: 声明当前类是SpringBoot应用的配置类。
  (项目中只能有一个,一般无需自己添加。)

  @EnableAutoConfiguration: 开启自动配置。
  告诉SpringBoot基于所添加的依赖,去"猜测"你想要如何配置Spring。
  比如我们引入了spring-boot-starter-web,而这个启动器中帮我们添加了tomcat、SpringMVC的依赖,此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!我们使用SpringBoot构建一个项目,只需要引入所需框架的依赖,配置就可以交给SpringBoot处理了。

  @ComponentScan: 配置组件扫描的指令。
  提供了类似与<context:component-scan>标签的作用。通过basePackageClasses或者basePackages属性来指定要扫描的包。
  如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包。而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类。
  因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。


二、Controller层(控制层)


2.1 类注解 TYPE


1. @Controller 注入ioc容器->controller层 ⭐️


a.作用域:
  ElementType.TYPE:类、接口、枚举。

b.功能:
  1. @Controller用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。
  2. @Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是处理请求的处理器。

c.参数:
  value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController)

d.返回数据类型:
  具体页面(比如*.html)

e.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
  2. 注解合并:@Controller + @ResponseBody = @RestController
  3. 对比注解:@Controller 与 @RestController(2.5.1)


ViewController : 处理器

package com.springboot.annotation.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author GroupiesM
 * @date 2021/07/06
 * @introduction 1.controller注解相关的测试
 *
 * \@Controller 与 @RequestMapping
 */
@Controller
public class ViewController {
    /**
     * 不带数据直接返回页面
     * @return String
     */
    @RequestMapping("view")//url:http://localhost:8080/page/view
    public String view() {
        return "view.html";
    }
}

view.html: 页面(必须放在图中为位置,否则读不到)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>视图页面</title>
</head>
<body>
	<div>我的页面</div>
</body>
</html>

Step1: 使用浏览器访问 http://localhost:8080/view

Step2: 每次都写.html太麻烦了,在 application.properties 配置视图解析器(ViewResolver)前后缀

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html

Step3: 再次访问http://localhost:8080/view

Step4: 上面都是不带数据只返回页面,下面要带数据返回 view.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>视图页面</title>
</head>
<body>
    <div>我的页面</div>
    <hr><div>${str1}</div>
    <hr><div>${str2}</div>
</body>
</html>

Step5: 再次访问 http://localhost:8080/view

视图解析器: 常用的有 jsp、Volocity、Freemarker等。其中jsp视图解析器配置比较复杂,演示用freemarker解析比较方便

Step6: pom.xml 中引入freemarker(视图解析器,用来数据交互)

        <!--视图解析器 freemarker-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

Step7: application.properteis配置freemarker

#spring视图解析器
##页面视图前缀
spring.mvc.view.prefix=/
##页面视图后缀
spring.mvc.view.suffix=.html

#freeMarker视图解析器
##后缀
spring.freemarker.suffix=.html
##指定资源(页面)默认路径,默认指向templates路径
spring.freemarker.template-loader-path=classpath:/static/

Step8: ViewController新增返回数据方法 dataview,并稍加改造

package com.springboot.annotation.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author GroupiesM
 * @date 2021/07/06
 * @introduction 1.controller注解相关的测试
 *
 * \@Controller 与 @RequestMapping
 */
@Controller
@RequestMapping("/page")
public class ViewController {

    public static final String PAGE = "view";

    /**
     * 不带数据直接返回页面
     * @return String
     */
    @RequestMapping("/view")//url:http://localhost:8080/page/view
    public String view(){
        return PAGE;
    }

    /**
     * 带数据的返回页面
     * @return ModelAndView
     */
    @RequestMapping("/dataview")//url:http://localhost:8080/page/dataview
    public ModelAndView dataView(){
        ModelAndView view = new ModelAndView(PAGE);
        view.addObject("str1","我叫hello!");
        view.addObject("str2","我是张三!");
        return view;
    }
}

Step10: 访问 http://localhost:8080/page/view (不返回数据)

Step11: 访问 http://localhost:8080/page/dataview (返回数据),成功解析


2. @RequestMapping 映射->资源目录 ⭐️


a.作用域:
  1. ElementType.TYPE:类、接口、枚举;
  2. ElementType.METHOD:方法。

b.功能:
  配置http请求(url访问地址、请求方式、请求头等)。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @RequestMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @RequestMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  4. method:要映射到http请求方法,共八种(GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE);
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {“text/plain”, “application/"} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, "application/”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
  2. 注解合并:@RequestMapping可以使用在接口、类、枚举、方法上,@GETMapping、@POSTMapping等只能使用在方法上
    REST模式:POST,GET,PUT,DELETE,PATCH的含义与区别
   @RequestMapping(value = “user” , method = RequestMethod.GET) = @GetMapping(“user”)
   @RequestMapping(value = “user” , method = RequestMethod.POST) = @PostMapping(“user”)
   @RequestMapping(value = “user” , method = RequestMethod.PUT) = @PutMapping(“user”)
   @RequestMapping(value = “user” , method = RequestMethod.DELETE) = @DeleteMapping(“user”)
   @RequestMapping(value = “user” , method = RequestMethod.PATCH) = @PatchMapping(“user”)


映射资源目录示例(详细使用方法在2.1.1@Controller)


3. @ResponseBody 后端 -> 浏览器 json对象⭐️


a.作用域:
  1. ElementType.TYPE:类、接口、枚举;
  2. ElementType.METHOD:方法。

b.功能:
  1. 将java对象转为json对象(下面示例中返回User实体类,自动解析为json)。
  2. 将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
  3. 表示该方法的返回结果直接写入 HTTP responsebody 中,一般在异步获取数据时使用(也就是AJAX)。

c.参数:
  

d.相关注解:
  注解合并:@Controller + @ResponseBody = @RestController


User 实体类

package com.springboot.annotation.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   //private List<String> hobbies;
   private String[] hobbies;//爱好
}

UserController 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author GroupiesM
 * @date 2021/07/07
 * @introduction 4.@RequestBody相关测试
 */
@Controller
public class UserController {
    private static List<User> users = new ArrayList<>();

    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
    }

    /**
     * 查询用户
     * @return
     */
    @GetMapping("/get/user/a")//http://localhost:8080/get/user/a
    public Object get() {
        return users;
    }

    /**
     * 查询用户,返回json对象 @ResponseBody
     * @return
     */
    @ResponseBody
    @GetMapping("/get/user/b")//http://localhost:8080/get/user/b
    public Object getUser() {
        return users;
    }
}

Postman请求java对象 (没有@ResponseBody) http://localhost:8080/get/user/a

Postman请求java对象 (添加@ResponseBody)http://localhost:8080/get/user/b

user对象转为json对象


4. @CrossOrigin 解决跨域问题


a.作用域:
  1. ElementType.TYPE:类、接口、枚举;
  2. ElementType.METHOD:方法。

b.功能:
  1. 用于允许特定处理程序类和/或处理程序方法上的跨源请求(解决跨域问题)。
  2. 需要在每个接口上添加此注解,或者统一使用过滤器进行配置,效果相同。

c.参数:
  1.origins:允许可访问的域列表 @CrossOrigin(origins = "http://domain2")
  2. ⭐️value:允许可访问的域列表,与 origins() 等价;
  3. originPatterns:允许可访问的域列表,正则表达式,更加灵活;
  4. allowedHeaders:允许访问的请求头列表,默认 allowedHeaders = {“*”}
    1. *表示允许所有请求头。
    2. 允许访问的请求头在 响应首部(Access-Control-Allow-Headers) 的 预检请求(preflight request)中列出(没看懂)。
  5. exposedHeaders:用户代理(user-agent)允许访问的响应头列表 => HTTP Headers
    Cache-Control:?
    Content-Language:?
    Content-Type:指示服务器文档的MIME 类型。帮助用户代理(浏览器)去处理接收到的数据。
    Expires:?
    Last-Modified:?
    Pragma:?
  6. methods:支持的HTTP请求方法列表,默认与当前controller一致
  7. allowCredentials:默认情况下,标准的跨域请求是不会发送cookie等用户认证凭据的。打开后可以携带cookiec等信息。默认allowCredentials = “false”
    a. allowCredentials = “true” 表示对已配置域的高度信任,并通过公开特定于用户的敏感信息(如cookie和CSRF令牌),增加了web项目的攻击层面(attack surface)。
    b. allowCredentials = “true” 时,远程服务器也要作相应的处理。在响应头那里设置 Access-Control-Allow-Credentials: true 。如果没有这个设置的话,浏览器就会报错。
    c. allowCredentials = “true” 时,Access-Control-Allow-Origin不能设置为 *
  8. maxAge:准备响应前的缓存持续的最大时间(秒),默认maxAge = -1

d.名词解释:
  跨域: 指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
  同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;
   跨域问题以及使用@CROSSORIGIN解决
   注解@CrossOrigin解决跨域问题


UserController 处理器 添加@CrossOrigin
(表示来自本地8090端口的跨域请求可以访问以下两个资源 get 和 getUser)

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Controller
public class UserController {
    private static List<User> users = new ArrayList<>();

    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
    }

    /**
     * 查询用户
     * @return
     */
    @CrossOrigin(origins = "http://localhost:8090")
    @GetMapping("/get/user/a")//http://localhost:8080/get/user/a
    public Object get() {
        return users;
    }

    /**
     * 查询用户,返回json对象 @ResponseBody
     * @return
     */
    @ResponseBody
    @CrossOrigin(origins = "http://localhost:8090")
    @GetMapping("/get/user/b")//http://localhost:8080/get/user/b
    public Object getUser() {
        return users;
    }
}

2.2 方法注解 METHOD


1. @RequestMapping => 2.1.2 🚕


2. @CrossOrigin => 2.1.4 🚕


2.3 参数注解 PARAMETER


1. @RequestParam 获取 -> get请求参数 ⭐️


a.作用域:
  ElementType.PARAMETER:参数。

b.功能:
  1. 用于将请求参数区域的数据映射到控制层方法的参数上。
  2. 搭配@GetMapping使用,接收get请求 ?后面的参数。
  3. 搭配@PostMapping使用,接收post请求?后面的参数。
  4. 当请求中缺少某个参数时,默认为null,对于基本数据类型变量,则必须有值,如果允许空值,需要使用包装类声明;

c.参数:
  1. name:请求的参数名,默认为接收参数的变量名;
  2. ⭐️value:请求的参数名,默认为接收参数的变量名,与name()等价;

  3. required:请求时该参数是否必传,默认required = true
  4. defaultValue:参数的默认值,支持SpEL表达式。默认defaultValue = ValueConstants.DEFAULT_NONE,因为不能在注解的属性中使用null来表示空值,所以用这段16位Unicode的字符串来表示空值,并且是不会发生这段字符串与用户定义的值是一样的情况。避免了用户给出的值却被当作是空值的情况(value = \n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n时会被处理为null);

d.请求格式:
  多个参数用&隔开: http://localhost:8080/param?id=1&type=苹果&discount=80%&price=3元

e.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
  2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)


ParamController 处理器

package com.springboot.annotation.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author GroupiesM
 * @date 2021/07/06
 * @introduction 参数相关的测试
 */
@Controller
public class ParamController {
    public static final String PAGE = "param";

    @RequestMapping("/param")
    public ModelAndView param(//必须传参
                              @RequestParam(value = "id") int id,
                              //可以不传参,但在类中要进行赋值,否则freeMarker解析页面时会报错
                              @RequestParam(value = "type", required = false) String type,
                              //可以不传参,取默认值
                              @RequestParam(value = "discount", required = false, defaultValue = "80%") String discount,
                              //可以不传参,取默认值
                              @RequestParam(value = "price",defaultValue = "5元") String price) {
        //作用类似于上面 @RequestParam注解中的属性 defaultValue="苹果"
        //不同的是 defaultValue会让required默认转为false
        if (type == null) {
            type = "苹果";
        }
        System.out.print("id = " + id);
        System.out.print(" type = " + type);
        System.out.print(" price = " + price);
        System.out.println(" discount = " + discount);

        ModelAndView view = new ModelAndView(PAGE);
        view.addObject("id", id);
        view.addObject("type", type);
        view.addObject("price", price);
        view.addObject("discount", discount);
        return view;
    }
}

param.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>参数测试</title>
</head>
<body>
	<h2>${id}</h2>
	<h2>${type}</h2>
	<h2>${discount}</h2>
	<h2>${price}</h2>
</body>
</html>

Step1: 编辑要访问的页面param.html

Step2: 接受请求参数的控制类ParamController

Step3: 获得浏览器提交的请求参数

Step4: 默认required = fasle(必须传参),get请求没有给id传值,导致报错;

Step5: 解决方式:RequstMapping添加属性 ,required = false(允许为空),defaultValue = 0(默认值为0,默认defaultValue = null,基本类型接收null也会报错);

Step6: 请求多个参数时(id,type,price,discount)的页面;

Step7: 请求参数不完整时,由于type值为null,会报错;

Step8: 可以在代码中给默认值,效果等类似 defaultValue(但例如基本数据类型int就不可以通过判断 == null进行赋值,所以不完全一样);

Step9: 测试正常传值的效果;


2. @RequestBody 浏览器 -> 后端 json数据(post请求)⭐️


a.作用域:
  ElementType.PARAMETER:参数。

b.功能:
  1. 用于将请求体区域的数据【前端返回json内容给后端】映射到控制层方法的参数【后端接收的是java对象(自定义entity)】上。
  2. 搭配@PostMapping使用,接收post请求中,请求体携带的json字符串。
  3. @RequestBody接收数据时,前端不能使用get方式提交数据(get方式没有请求体),而是用post方式进行提交。

c.参数:
  required:该参数get请求时是否必传,默认required = true

d.请求格式:
  post -> body -> raw -> JSON

  {
      "id":66,
      "name": "admin",
      "gender": "男",
      "age": 33,
      "hobbies": [
          "睡觉"
      ]
  }

e.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @PostMapping(方法)+ @RequestBody(参数)
  2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)


User : 实体类

package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

UserRestController : 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserRestController {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;

    //静态代码块--存储用户信息
    static {users.add(new User(1, "张三", "男", 20,new String[]{"足球", "篮球"}))}

    /**
     * 新增数据,返回所有用户
     * @param user
     * @return
     */
    @PostMapping("/post")//http://localhost:8080/user/post
    public List<User> addUser(@RequestBody User user) {
        users.add(user);
        return users;
    }

Postman请求示例:


3. @PathVariable 获取 -> restful风格请求参数


a.作用域:
  ElementType.PARAMETER:参数。

b.功能:
  1. 映射URL绑定的占位符。
  2. 带占位符的URL是 Spring3.0 新增的功能,URL中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。

c.参数:
  1. name:请求的参数名,默认为接收参数的变量名;
  2. ⭐️value:请求的参数名,默认为接收参数的变量名,与name()等价;
  3. required:该参数请求时是否必传,默认required = true

d.请求格式:
  多个参数用&隔开: http://localhost:8080/param?1/苹果/0.8/3元

e.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @PathVariable(参数)
  2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)


ParamController: 处理器

package com.springboot.annotation.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ParamController {
    public static final String PAGE = "param";

    @RequestMapping("/param")
    public ModelAndView param(//必须传参
                              @RequestParam(value = "id") int id,
                              //可以不传参,但在类中要进行赋值,否则freeMarker解析页面时会报错
                              @RequestParam(value = "type", required = false) String type,
                              //可以不传参,取默认值
                              @RequestParam(value = "discount", required = false, defaultValue = "80%") String discount,
                              //可以不传参,取默认值
                              @RequestParam(value = "price", defaultValue = "5元") String price) {
        //作用类似于上面 @RequestParam注解中的属性 defaultValue="苹果"
        //不同的是 defaultValue会让required默认转为false
        if (type == null) {
            type = "苹果";
        }
        System.out.print("id = " + id);
        System.out.print(" type = " + type);
        System.out.print(" price = " + price);
        System.out.println(" discount = " + discount);

        ModelAndView view = new ModelAndView(PAGE);
        view.addObject("id", id);
        view.addObject("type", type);
        view.addObject("discount", discount);
        view.addObject("price", price);
        return view;
    }

    @RequestMapping("/param/{id}/{type}/{discount}/{price}")
    public ModelAndView path(@PathVariable(required = false) int id,
                             @PathVariable(required = false) String type,
                             @PathVariable(required = false) String discount,
                             @PathVariable(required = false) String price) {
        if (discount == null) {
            discount = "80%";
        }
        if (price == null) {
            price = "5元";
        }
        System.out.print("id = " + id);
        System.out.println("type = " + type);
        System.out.print(" price = " + price);
        System.out.println(" discount = " + discount);

        ModelAndView view = new ModelAndView(PAGE);

        view.addObject("id", id);
        view.addObject("type", type);
        view.addObject("discount", discount);
        view.addObject("price", price);
        return view;
    }
}

param.html: 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>参数测试</title>
</head>
<body>
	<h2>${id}</h2>
	<h2>${type}</h2>
	<h2>${discount}</h2>
	<h2>${price}</h2>
</body>
</html>

Step1: 使用Path格式正常请求

Step2: 使用Path格式请求,带特殊符号%

Step3: 使用Path请求缺少参数时(没有映射缺少参数的URL地址)

Step4: 使用Path请求缺少参数时,需要先在Mapping中映射多个URL地址


2.4 合并注解

1. @RestController 注入ioc容器->controller层⭐️


a.作用域:
  ElementType.TYPE:类、接口、枚举。

b.功能:
  1. @RestController = @Controller + @Responsebody 等于同时了这添加两个注解。
  2. @RestController 用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。
  3. 将Controller的方法返回的对象,通过 HttpMessageConverter 转换为指定格式后,写入到Response对象的body数据区。
  4. 使用此注解此次请求将不再走视图处理器,而是直接将此响应结果写入到输入流中,其效果等同于使用response对象输出指定格式的数据(java对象转为json对象)。

c.参数:
  1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Controller.value等价;
  2. ⭐️Controller.value:与 @Component.value等价;

d.返回数据类型:
  返回数据(对象,json,xml等)

e.相关注解:
  1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
  2. 注解合并:@Controller + @ResponseBody = @RestController
  3. 对比注解:@Controller 与 @RestController(2.5.1)


Step1: @RestController返回数据 (返回一个String)

Step2: @RestController返回数据 (返回一个entity,entity通过HttpMessageConverter转为json对象)


  使用Postman请求页面


Users 实体类: 修改用户属性

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

UserController 用户处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author GroupiesM
 * @date 2021/07/07
 * @introduction 3.RestController注解相关测试
 *
 * \@RestController 与 @GetMapping
 */

@RestController
@RequestMapping("user")
public class UserController {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;
    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20, new String[]{"足球","篮球"}));
        users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌","看电影"}));
    }
    @GetMapping("/get")//http://localhost:8080/user/get
    public Object get() {
        ArrayList<Object> arr = new ArrayList<>();
        User user = new User(1, "张三", "男", 20, new String[]{"足球","篮球"});
        System.out.println(user.toString());
        return user;
    }

    //通过性别查找用户的方法(@RequestParam传参)
    @GetMapping("/getbygender")//http://localhost:8080/user/getbygender
    public static Object getByGenderA(@RequestParam(value = "gender") String gender) {
        returnUser = new ArrayList<>();
        for (User user : UserController.users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }

    //通过性别查找用户的方法(@PathVariable传参)
    @GetMapping("/getbygender/{gender}")//http://localhost:8080/user/getbygender
    public static Object getByGenderB(@PathVariable("gender") String gender) {
        returnUser = new ArrayList<>();
        for (User user : UserController.users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }
}

Step3: 测试自定义功能,根据性别查询用户(@RequestParam格式)http://localhost:8080/user/getbygender?&gender=男

Step4: 测试自定义功能:根据性别查询用户(@PathVariable格式)`http://localhost:8080/user/getbygender/女``


2. @GetMapping Get方式请求资源目录 ⭐️


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  1. 配置http请求(url访问地址、请求头等),指定请求方式为Get。
  2. get请求一般用于信息获取,而且是安全的和幂等的 => 安全与幂等 。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @GetMapping(“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @GetMapping(“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {text/plain", "application/*} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, “application/*”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
  2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.GET) = @GetMapping(“user”)
  3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)


GetMapping部分源码


User : 实体类

package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

UserController : 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/user")
public class UserController {
    private static List<User> users = new ArrayList<>();

    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20,
                new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21,
                new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22,
                new String[]{"唱歌", "看电影"}));
    }
    
    /**
     * 查询用户
     * @return
     */
    @GetMapping(value = "/get")//http://localhost:8080/user/get
    public List<User> get() {
        return users;
    }


Step1: POSTMAN请求  http://localhost:8080/user/get


3. @PostMapping Post方式请求资源目录⭐️


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  1. 配置http请求(url访问地址、请求头等),指定请求方式为Post。
  2. Post请求一般用于创建数据,不是安全和幂等的 => 安全与幂等 。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @PostMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @PostMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {text/plain", "application/*} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, “application/*”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
  2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.POST) = @PostMapping(“user”)
  3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)


User : 实体类

package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

UserController : 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/user")
public class UserController {
    private static List<User> users = new ArrayList<>();

    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20,
                new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21,
                new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22,
                new String[]{"唱歌", "看电影"}));
    }
    
    /**
     * 新增一个用户,返回所有用户列表
     * @param user
     * @return
     */
    @PostMapping(value = "/post", produces = "application/json;charset=UTF-8")//http://localhost:8080/user/post
    public List<User> addUser(@RequestBody User user) {
        users.add(user);
        return users;
    }

Step1: Postman第一次请求  http://localhost:8080/user/post
请求方式: POST请求,Body -> raw -> json字符串

{
    "id": 4,
    "name": "张曼玉",
    "gender": "女",
    "age": 23,
    "hobbies": [
        "听音乐",
        "做饭"
    ]
}

Step2: Postman第二次请求  http://localhost:8080/user/post
请求方式: POST请求,Body -> raw -> json字符串

{
    "id": 5,
    "name": "王祖贤",
    "gender": "女",
    "age": 24,
    "hobbies": [
        "睡觉"
    ]
}


4. @PutMapping Put方式请求资源目录


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  1. 配置http请求(url访问地址、请求头等),指定请求方式为Put。
  2. Put请求一般用于创建或完整更新数据,而且是安全和幂等的 => 安全与幂等 。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @PutMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @PutMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {text/plain", "application/*} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, “application/*”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:
  2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.PUT) = @PutMapping (“user”)
  3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)


无示例…


5. @DeleteMapping Delete方式请求资源目录


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  1. 配置http请求(url访问地址、请求头等),指定请求方式为Delete。
  2. Delete请求一般用于删除数据,而且是安全和幂等的 => 安全与幂等 。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @DeleteMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @DeleteMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {text/plain", "application/*} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, “application/*”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
  2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.DELETE) = @DeleteMapping(“user”)
  3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)


User : 实体类

package com.springboot.annotation.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

UserController : 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    private static List<User> users = new ArrayList<>();

    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "张三", "男", 20,new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21,new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22,new String[]{"唱歌", "看电影"}));
    }

     /**
     * 根据id删除对应User
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete", produces = "application/json;charset=UTF-8")//http://localhost:8080/user/delete?id=3
    public List<User> deleteUser(@RequestParam(value = "id") int id) {
        Iterator<User> it = users.iterator();
        while (it.hasNext()) {
            User next = it.next();
            if (next.getId() == id) {
                it.remove();
            }
        }
        return users;
    }
}

Step1: Postman第一次请求  http://localhost:8080/user/delete?id=1

Step2: Postman第二次请求  http://localhost:8080/user/delete?id=2

Step3: Postman第三次请求  http://localhost:8080/user/delete?id=3


6. @PatchMapping Patch方式请求资源目录


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  1. 配置http请求(url访问地址、请求头等),指定请求方式为Patch。
  2. Patch请求一般用于更新部分数据,不是安全和幂等的 => 安全与幂等 。

c.参数
  1. name:为这个映射分配一个名称;
  2. ⭐️value:映射的资源路径,与 path() 等价;
    @PatchMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
    @PatchMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
  3. path:映射的资源路径,与 value() 等价;
  5. params:映射的请求参数;
  6. headers:映射的请求头;
  7. consumes:映射的Content-type请求信格式,例如
    consumes = “text/plain” => HTML格式
    consumes = {“text/plain”, “application/"} => 纯文本格式
    consumes = MediaType.TEXT_PLAIN_VALUE => ?
  8. produces:映射的返回数据的类型以及编码;
    produces = “text/plain” => HTML格式
    produces = {“text/plain”, "application/”} => 纯文本格式
    produces = MediaType.TEXT_PLAIN_VALUE => ?
    produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
    produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)

d.相关注解:
  1. 常见组合:
  2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.Patch) = @PutMapping (“user”)
  3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)


无示例…


2.5 对比


1. @Controller 和 @RestController


  • @Controller
    • 在对应的方法上,视图解析器可以解析return 的jsp,html页面
    • 使用@Controller 这个注解,就不能返回JSON,XML或自定义mediaType内容到页面
    • 适用场景:跳转页面

  • @RestController
    • @RestController注解相当于@ResponseBody + @Controller
    • 返回对象(String、Integer)、json(entity会自动转为json对象)、xml、自定义media Type给浏览器
    • 使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
    • 适用场景:返回数据

2. @RequesetParam、@PathVariable、@RequestBody


@RequesetParam(“/xxx”)
  http://localhost:8080/param?id=1&type=苹果&discount=80%&price=3元

@PathVariable(“/xxx/{param1}/{param2…}”)
  http://localhost:8080/param/2/苹果/0.5/3元 (不能传特殊符号./\%#等,=> 处理方式)

  • 在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
  • @RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
注解支持类型支持的请求类型支持的Content-Type请求示例默认值
@RequestParamurlGetall/orders?name=abc
BodyPost/Put/Delete/Patchform-data,x-www.form-urlencoded见下图(Postman请求示例1
@RequestBodyBodyPost/Put/Delete/Patchjson{"id":1,"name":"abc"}(Postman请求示例2×
@PathVariableurlGetall/orders/{id}×

Postman请求示例1:

Postman请求示例2:


3.@Get/Post/Put/Delete/Patch Mapping


REST模式:POST,GET,PUT,DELETE,PATCH的含义与区别


三、Service层(服务层) (放入ioc)


3.1 类注解 TYPE


1. @Service 标记服务类->自动bean注册⭐️


a.作用域:
  ElementType.TYPE:类、接口、枚举。

b.功能:
  1. 将ioc容器中指定的service对象放入spring ioc容器。
  2. 在实现类上(Impl)加@Service注解,一个接口可以有多个实现类。
  3. 一般按照以下方式分层使用。
   1) service层:业务逻辑接口;

	public interface UserService {
		List<User> get();
	}

   2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service;

    @Service
	public class UserServiceImpl implements UserService{
		public List<User> get(){...调用dao层查询Userreturn...};
	}

 &emsp ;3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出;

   @RestController
   @RequestMapping("/user")
   public class UserController {
   @Autowired
   private UserService userService;
   @GetMapping("/get")//http://localhost:8080/action/get
   public List<User> get() {
       return userService.get();
   }

c.参数:
  1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Component.value等价;

d.相关注解:
  1. 常见组合:@Service(SerivceImpl中) + @Autowired(Controller中)
  2. 对比注解:@Service — @Component — @Configuration + Bean(3.4.1)


具体用法参看@Autowired


2. @Component 标记组件类->自动bean注册⭐️

a.作用域:
  ElementType.TYPE:类、接口、枚举。

d.相关注解:
  @Service 和 @Component从功能角度来说效果相同,区别在于,按照约定使用在不同场合:
    1. @Service标记的是服务层,只和需求相关,仅由Controller层调用
    2. @Component标记的是组件(比如工具类),可以被Service,Controller等任何调用


3. @Configuration 注入容器(手动) -> 自定义组件


a.作用域:
  ElementType.TYPE:类、接口、枚举。

b.功能:
  被标记的类会被Spring扫描,该类中被@Bean注解的实例化方法,会放入ioc容器(手动Bean注册)

c.参数:
  1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Component.value等价;

d.相关注解:
  1. 常见组合:@Configuration (类) + @Bean(方法)
  2. 对比注解:@Service — @Component — @Configuration + Bean(3.4.1)


Step1: 手动创建一个MyBeans类,将需要注入ioc容器的方法用@Bean注解(具体使用方法查看3.4.1)


MyBeans: 自定义实体类,通过@Configuration+@BEan方式手动注入ioc容器

package com.springboot.annotation.cfg;

import com.springboot.annotation.impl.AdminServiceImpl;
import com.springboot.annotation.impl.UserServiceImpl;
import com.springboot.annotation.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBeans {
    /**手动注入spring ioc容器,指定对象名称admin
     * @return AdminServiceImpl对象*/
    @Bean
    public UserService admin() {
        return new AdminServiceImpl();
    }

    @Bean
    public UserService user() {
        return new UserServiceImpl();
    }
}

UserService: 服务层接口

package com.springboot.annotation.service;
import com.springboot.annotation.entity.User;
import java.util.List;


public interface UserService {
    List<User> get();
    List<User> getByGenderB(String gender);
}

AdminServiceImpl: 服务层实现类1

package com.springboot.annotation.impl;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class AdminServiceImpl implements UserService {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;
    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "admin1", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "admin2", "女", 21, new String[]{"舞蹈"}));
        users.add(new User(3, "admin3", "女", 22, new String[]{"唱歌", "看电影"}));
    }
    /**
     * 查询用户
     * @return
     */
    @Override
    public List<User> get() {
        return users;
    }

    /**
     * 通过性别查找用户的方法(@PathVariable传参)
     * @param gender
     * @return
     */
    @Override
    public List<User> getByGenderB(String gender) {
        returnUser = new ArrayList<>();
        for (User user : users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }
}

UserServiceImpl: 服务层实现类2,与实现类1相比,查询的用户不同

package com.springboot.annotation.impl;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;
    static {
        users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌", "看电影"}));
    }

    @Override
    public List<User> get() {
        return users;
    }

    @Override
    public List<User> getByGenderB(String gender) {
        returnUser = new ArrayList<>();
        for (User user : users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }
}

UserActionController: 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/action")
public class UserActionController {
    //使用MyBeans中手动注入ioc的对象
    @Resource(name = "user")
    private UserService userService;

	@Resource(name = "admin")
    private UserService adminService;

    /**
     * 查询user用户
     * @return 当前所有用户
     */
    @GetMapping("/getUser")//http://localhost:8080/action/getUser
    public List<User> getUser() {
        return userService.get();//
    }

    /**
     * 查询admin用户
     * @return 当前所有用户
     */
    @GetMapping("/getAdmin")//http://localhost:8080/action/getAdmin
    public List<User> getAdmin() {
        return adminService.get();//
    }
}

Step2: Postman请求实现类1   http://localhost:8080/action/getUser

按照如下顺序找到对应的实现类 UserServiceImpl(Service接口有两个实现类,返回内容不一样)

Step3: Postman请求实现类2   http://localhost:8080/action/getAdmin

按照如下顺序找到对应的实现类 AdminServiceImpl

Step4: 还可以通过@Autowired + @Qualifier组合使用来指定MyBeans中自定义的对象


3.2 方法注解 METHOD


1. @Bean 手动Bean注册


a.作用域:
  1. ElementType.METHOD:方法。
  2. ElementType.ANNOTATION_TYPE:注解。

b.功能:
  手动注入ioc容器,指定实例化对象,和ioc容器中实例对象名称


3.3 注解的注解 ANNOTATION_TYPE


1. @Bean => 3.2.1 🚕


3.4 对比


1. @Service — @Component — @Configuration + Bean


@Service 和 @Component从功能角度来说效果相同,区别在于,按照约定使用在不同场合;

而@Configuration在功能上有一些差别了 => @Component和@Configuration作为配置类的差别:

1. @Service
  1. 将实例化对象自动放入Spring ioc容器
  2. 按照约定,@Service标记的是业务层,仅由Controller层调用

2. @Component
  1. 将实例化对象自动放入Spring ioc容器
  2. 按照约定,@Component标记的是组件类,可以被Service,Controller等任何调用

3. @Configuration + @Bean
  1. 将实例化对象手动放入Spring ioc容器
  2. 手动通过@Bean进行注册


MyBeans: 自定义实体类,通过@Configuration+@BEan方式手动注入ioc容器

@Configuration
public class MyBeans {
    /**手动注入spring ioc容器,指定对象名称admin
     * @return AdminServiceImpl对象*/
    @Bean
    public UserService admin() {
        return new AdminServiceImpl();
    }

    @Bean
    public UserService user() {
        return new UserServiceImpl();
    }
}

UserService: 服务层接口

package com.springboot.annotation.service;
import com.springboot.annotation.entity.User;
import java.util.List;


public interface UserService {
    List<User> get();
    List<User> getByGenderB(String gender);
}

AdminServiceImpl: 服务层实现类1

package com.springboot.annotation.impl;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class AdminServiceImpl implements UserService {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;
    //静态代码块--存储用户信息
    static {
        users.add(new User(1, "admin1", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "admin2", "女", 21, new String[]{"舞蹈"}));
        users.add(new User(3, "admin3", "女", 22, new String[]{"唱歌", "看电影"}));
    }
    /**
     * 查询用户
     * @return
     */
    @Override
    public List<User> get() {
        return users;
    }

    /**
     * 通过性别查找用户的方法(@PathVariable传参)
     * @param gender
     * @return
     */
    @Override
    public List<User> getByGenderB(String gender) {
        returnUser = new ArrayList<>();
        for (User user : users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }
}

UserServiceImpl: 服务层实现类2,与实现类1相比,查询的用户不同

package com.springboot.annotation.impl;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    private static List<User> users = new ArrayList<>();
    private static List<User> returnUser;
    static {
        users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
        users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
        users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌", "看电影"}));
    }

    @Override
    public List<User> get() {
        return users;
    }

    @Override
    public List<User> getByGenderB(String gender) {
        returnUser = new ArrayList<>();
        for (User user : users) {
            if (user.getGender().equals(gender)) {
                returnUser.add(user);
            }
        }
        System.out.println(returnUser);
        return returnUser;
    }
}

UserActionController: 处理器

package com.springboot.annotation.controller;

import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/action")
public class UserActionController {
    //使用MyBeans中手动注入ioc的对象
    @Resource(name = "user")
    private UserService userService;

	@Resource(name = "admin")
    private UserService adminService;

    /**
     * 查询user用户
     * @return 当前所有用户
     */
    @GetMapping("/getUser")//http://localhost:8080/action/getUser
    public List<User> getUser() {
        return userService.get();//
    }

    /**
     * 查询admin用户
     * @return 当前所有用户
     */
    @GetMapping("/getAdmin")//http://localhost:8080/action/getAdmin
    public List<User> getAdmin() {
        return adminService.get();//
    }
}

请求接口1: Postman请求实现类1   http://localhost:8080/action/getUser

按照如下顺序找到对应的实现类 UserServiceImpl(Service接口有两个实现类,返回内容不一样)

请求接口2: Postman请求实现类2   http://localhost:8080/action/getAdmin

按照如下顺序找到对应的实现类 AdminServiceImpl


四、注入bean(从ioc取)


4.1 字段注解 FIELD


1. @Autowired 容器ioc->获取bean⭐️


a.作用域:
  1. ElementType.FIELD:字段(包括枚举常量)。
  2. ElementType.METHOD:方法。
  3. ElementType.PARAMETER:参数。
  4. ElementType.CONSTRUCTOR:构造器。
  5. ElementType.ANNOTATION_TYPE:注解。

b.功能:
  1. 自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时。使用要注入的对象变量名称作为bean的id,在spring容器中查找,找到了注入成功,找不到就报错。
  2. 将ioc容器中指定的service对象从ioc容器中取出。
  3. 接口单个实现时,注入时加@Autowired 即可。
  4. 接口多个实现时,注入时加@Autowired + @Qualifier配合使用(或者使用@Resource代替@Autowired,在参数name中指定bean的名称 ),指定具体的实现类。
  5. 一般按照以下方式分层使用
   1) service层:业务逻辑接口

	public interface UserService {
		List<User> get();
	}

   2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service

    @Service
	public class UserServiceImpl implements UserService{
		public List<User> get(){...调用dao层查询Userreturn...};
	}

   3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出

   @RestController
   @RequestMapping("/user")
   public class UserController {
   	@Autowired
       private UserService userService;
       @GetMapping("/get")//http://localhost:8080/user/get
       public List<User> get() {
           return userService.get();
       }
   }

c.参数
  required:请求时该参数是否必传,默认required = true

d.相关注解:
  1. 常见组合:@Service(类-注入ioc)+ @Autowired(字段-从ioc取出Bean)
  2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
  3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)


场景1: @Autowired 注入Service,Service只有单个实现类

场景2: @Autowired 注入Service,Service有多个实现类(指定AdminServiceImpl 还是 UserServiceImpl,不同实现类会返回不同处理结果)

场景3: 通过@Autowired + @Qualifier组合使用来指定@Configuration + @Bean 中的bean


2. @Resource 容器ioc->获取bean


a.作用域:
  1. ElementType.TYPE:类、接口、枚举。
  2. ElementType.FIELD:字段(包括枚举常量)。
  3. ElementType.METHOD:方法。

b.功能:
  1. 直接按照Bean的id注入。它也只能注入其他Bean类型。
  2. name属性是指定Bean的id ,Bean的id是首字母小写的对象名。</font
  3. 将ioc容器中指定的service对象(一个服务接口有多个实现时)从ioc容器中取出 。
  4. 接口单个实现时,注入时加@Resource 即可。
  5. 接口多个实现时,注入时加@Resource(name = “beanid”)(在参数name中指定bean的名称 ),指定具体的实现类。
  6. 一般按照以下方式分层使用(不指定Bean id)
   1) service层:业务逻辑接口

	public interface UserService {
		List<User> get();
	}

   2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service

    @Service
	public class UserServiceImpl implements UserService{
		public List<User> get(){...调用dao层查询Userreturn...};
	}

   3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出

   @RestController
   @RequestMapping("/user")
   public class UserController {
   	@Resource 
       private UserService userService;
       @GetMapping("/get")//http://localhost:8080/user/get
       public List<User> get() {
           return userService.get();
       }
   }

  7. (不指定Bean id)
   1) service层:业务逻辑接口()
   2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service

 @Service
 public class UserServiceImpl implements UserService{...}
 @Service
 public class AdminServiceImpl implements UserService{...}

   3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出 ,需要指定Bean id,id为Bean对象的首字母小写。

 @Resource(name = "userServiceImpl")
 private UserService userService;

 @Resource(name = "adminServiceImpl")
 private UserService adminService;

c.参数
  1.⭐️name:指定从ioc容器中要取出的名称(Bean的id),默认为空。
  2. lookup
  3. type
  4. authenticationType
  5. shareable
  6. mappedName
  7. description:对该资源的描述。该描述预计将使用部署应用程序的系统的默认语言。可以将描述呈现给部署人员,以帮助选择正确的资源。

d.相关注解:
  1. 常见组合:@Service(多个类-注入ioc)+ @Resource( name = “BeanId” )
  2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
  3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)


3. @Qualifier 容器ioc->(获取时)指定bean


a.作用域:
  1. ElementType.TYPE:接口、类、枚举。
  2. ElementType.FIELD:字段(包括枚举常量)。
  3. ElementType.METHOD:方法。
  4. ElementType.PARAMETER:参数。
  5. ElementType.ANNOTATION_TYPE:注解。

b.功能:
  1. 在自动按照类型注入(@Autowired)的基础上,再按照Bean的id注入。它在给字段注入时不能单独使用
  2. 必须和@Autowire一起使用;但是给方法参数注入时,可以单独使用。
  3. value属性是指定Bean的id,Bean的id是首字母小写的对象名。

    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userService;
    
    @Autowired
    @Qualifier("adminServiceImpl")
    private UserService adminService;

c.参数
  value:指定从ioc容器中要取出的名称(Bean的id),默认为空。

d.相关注解:
  1. 常见组合:@Service(多个类-注入ioc)+ @Autowired(字段-从ioc取出Bean)+ @Qualifier(匹配到多个Bean实例时,指定Bean的id)
  2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
  3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)


4.2 类注解 TYPE


1. @Resource => 4.1.2 🚕

2. @Qualifier => 4.1.3 🚕


4.3 方法注解 METHOD


1. @Autowired => 4.1.1 🚕

2. @Resource => 4.1.2 🚕

3. @Qualifier => 4.1.3 🚕


4.4 参数注解 PARAMETER


1. @Autowired => 4.1.1 🚕

1. @Qualifier => 4.1.3 🚕



4.5 构造器注解 CONSTRUCTOR


1. @Autowired => 4.1.1 🚕


4.6 注解的注解 ANNOTATION_TYPE


1. @Autowired => 4.1.1 🚕

2. @Qualifier => 4.1.3 🚕


4.6 对比


1. @Autowired — @Autowired + @Qualifier — @Resource

1.使用语法不同: 当有注入Bean时有多个匹配类型,通过以下三种方式指定Bean的id

	//写法1
	@Autowired
	@Qualifier("userServiceImpl")
    private UserService userService;
    @Autowired
    @Qualifier("adminServiceImpl")
    private UserService adminService;
    
    //写法2
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private AdminServiceImpl adminService;
    
 	//写法3(建议此方式)
    @Resource(name = "userServiceImpl")
    private UserService userService;
    @Resource(name = "adminServiceImpl")
    private UserService adminService;

1. 使用语法不同: 当有注入Bean时只有单个匹配类型

    //写法1
    @Autowired
    private UserService userService;
 	//写法2(建议此方式)
    @Resource
    private UserService userService;

2. 底层加载方式不同: => @Autowired 与@Resource的区别


五、其他


1. @Alisfor 注解属性等价⭐️


a.作用域:
  ElementType.METHOD:方法。

b.功能:
  可以使两个注解的属性互为别名(完全等价)。同一注解下可以指定任意两个注解,跨注解时表示两个注解的同名属性相等;(Alisfor标记的两个注解同时赋不同值时会报错)

c.备注:
  等价的意思可以理解为多个属性(实例对象),但指向内存中同一地址


@Aliasfor源码:

场景1: 同注解中,两个属性等价

场景2: 跨注解时,两个同名属性等价(*.class只能是注解类)

场景3: 跨注解时,多个属性等价(*.class只能是注解类)


测试1: @RequestMapping的 只有一个属性时(仅有一个属性且为value时可以省略)

正常访问

测试2: @RequestMapping的 value 和 path属性相同时

正常访问

测试3: @RequestMapping的 value 和 path属性不同时

编译阶段不通过,启动项目时报错


2. @Value 从配置文件中取参数


a.作用域:
  1. ElementType.FIELD:字段(包括枚举常量)。
  2. ElementType.METHOD:方法。
  3. ElementType.PARAMETER:参数。
  4. ElementType.ANNOTATION_TYPE:注解。

b.功能:
  从配置文件(application.properties)中取参数,注入基本数据类型和String类型数据。


application.properties: 添加配置参数

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html

##freeMarker
#后缀
spring.freemarker.suffix=.html
#指定资源(页面)默认路径,默认指向templates路径
spring.freemarker.template-loader-path=classpath:/static/

#@Value相关测试
view.page=view
local.user.username=admin
local.user.password=123456

ValueController: 测试从配置文件中取值

package com.springboot.annotation.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author GroupiesM
 * @date 2021/07/07
 * @introduction @Value相关测试
 *
 */
@RestController
@RequestMapping("/value")
public class ValueController {

    @Value("${view.page}")
    private String page;

    @Value("${local.user.username}")
    private String username;

    @Value("${local.user.password}")
    private String password;

    @GetMapping("val")//localhost:8080/value/val
    public String getValue() {
        System.out.println(page + "..." + username + "..." + password);
        return page + "..." + username + "..." + password;
    }
}

Step1: 注意导包时选择springfreamwork包下的Value

Step2: 重启springboot项目,使用Postman访问接口,成功获取配置文件的值


六、lombok插件

SpringBoot - Lombok使用详解2(@Setter、@Getter、@ToString、@EqualsAndHashCode)

SpringBoot中lombok使用,自动生成getter、setter、构造器、toString()、equals()等

a. lombok简介
  Lombok想要解决了的是在我们实体Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不会用到,但是某些时候仍然需要复写,以期方便使用的方法;在使用Lombok之后,将由其来自动帮你实现代码生成,注意,其是 在运行过程中,帮你自动生成的 。就是说,将极大减少你的代码总量。

b. lombok作用
  1. 消除模板代码
  2. getter、setter、构造器、toString()、equals()
  3. 便捷的生成比较复杂的代码,例如一个POJO要转化成构建器模式的形式,只需要一个注解。

c. 常用注解
  1. @Data : 注解在类上, 为类提供@Getter、@Setter, 此外还提供了 equals()、hashCode()、toString() 方法
  2. @NoArgsConstructor : 注解在类上, 为类提供无参构造
  3. @AllArgsConstructor : 注解在类上, 为类提供全参构造
  4. @Getter/@Setter : 注解在类上, 为类提供读写属
  5. @ToString : 注解在类上, 为类提供 toString() 方法
  6. @Slf4j : 注解在类上, 为类提供一个属性名为 log 的 log4j 的日志对象
  7. @Log4j : 注解在类上, 为类提供一个属性名为 log 的 log4j 的日志对象


Step1: pom.xml添加lombok的jar包依赖(maven仓库)

<!-- https://mvnrepository/artifact/org.projectlombok/lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.10</version>
</dependency>

Step2: 编写一个实体类 User,使用@Data注解

@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {  
 	private String name;  
 	private int age;
}

Step2: 或者@Setter和@Getter(注意是lombok包下的Getter)


6.1 类注解


1. @Data 实体类常用功能打包⭐️

User: 实体类

package com.springboot.annotation.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
   private int id;//身份证
   private String name;//姓名
   private String gender;//性别
   private int age;//年龄
   private String[] hobbies;//爱好
}

TestUser: 编写测试方法,测试@Data是否起作用(测试了set方法和构造器)

@Test
public void TestUser(){  
  User user1 = new User();  
  user1.setName("AnyCode");  
  user1.setAge(20);  
  System.err.println(user.toString());
    
  User user1 = new User("张三",30);  
}

2. @NoArgsConstructor 无参构造⭐️

3. @AllArgsConstructor 全参构造⭐️

4. @Getter​ ​get方法⭐️

5. @Setter set方法⭐️


6.2 lombok失效问题


  问题描述: 运行项目时会出现大量报错,原因是使用lombok的类中的get、set方法全部失效


报错类中都使用了lombok注解@Data,由于lombok注解失效,导致编译不通过

  运行环境:

mac M1 2021版本

maven依赖(没有版本号,使用springboot版本下默认对应lombok版本)

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.5</version>
		<relativePath/>
	</parent>
	...
	...
	<dependency>
	      <groupId>org.projectlombok</groupId>
	      <artifactId>lombok</artifactId>
	      <optional>true</optional>
	</dependency>

  问题解决: 1. Preference -> Build,Execution,Deployment -> Compiler -> Annotation Processors 勾选

  • Enable annotation processing

  问题解决: 2. 如果还是不能启动项目,继续修改下图位置 ,Preference -> Build,Execution,Deployment -> Compiler中添加配置 -Djps.track.ap.dependencies=false


附录:springboot常见分层(AOP)


  备注: 这里的案例不涉及mybaties,没有和数据库交互查询数据的步骤,数据是在静态代码块中添加到userList中来模拟数据库课的;通常情况下Serviceimpl还需要调用dao层,dao层负责和数据库的交互;

测试1: 调用get方法 http://localhost:8080/action/get

测试2: 调用getbygender方法 http://localhost:8080/action/getbygender/男


1. controller层 @Controller

  概述: controller层叫控制器层,负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
  不存放业务逻辑,通过调用Service层实现业务逻辑


2. service层 @Service

  概述: service层叫业务逻辑层,存放业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供controller层调用的方法。
  implService是接口的实现类,实现业务逻辑,impl通过@Service注解注入ioc容器


3. dao层(mapper层) @Repository

  概述: dao层也叫mapper层,数据持久层,个人比较喜欢mapper层。
对数据库进行持久化操作,他的方法是针对数据库操作的,基本用到的就是增删改查。它只是个接口,只有方法名字,具体实现在mapper.xml中。

  既然mapper层是直接与数据库相挂钩的,所以要先连接数据库。
  可以在sqlMapConfig.xml文件或者application.properties文件里添加数据库属性等,如下所示:


sqlMapConfig.xml:添加属性

<!-- 加载属性文件 -->
<properties resource="/config/db.properties"></properties>

<!-- 和spring整合后environment配置将废除 -->
<environments default="development">
    <environment id="development">
        <!-- 使用jdbc事务管理 -->
        <transactionManager type="JDBC" />
        <!-- 数据库连接池,由mybatis管理 -->
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
        </dataSource>
    </environment>
</environments>

application.properties:添加属性

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123

5. model层 @Data


  概述: model层也叫pojo层或者entity层。一般数据库的一张表对应一个pojo类,并且表中所有字段都在pojo类都一一对应。

 1. POJO:Plain Ordinary Java Object 无规则简单Java对象。一个中间对象,可以转化为VO、DTO、PO。
 2. VO:View Object 表示层对象。对应页面显示的数据对象,可以和表对应,也可以不对应。一般在Controller层使用。
 3. DTO:Data Transfer Object 数据传输对象。传递数据。如PO有100个属性,页面VO只显示10个,那么DTO就也传输10个。一般在Service层使用。
 4. PO:Persistent Object 持久化对象。它跟数据表形成一一对应的映射关系。一般在Dao层使用。
 5. Entity: 实体,和PO的功能类似,和数据表一一对应,一个实体一张表。


6. common层


概述: 通用模块,不依赖其它任何模块,主要有utils


21/07/15

M

更多推荐

3.2.4_1 SpringBoot常用注解、lombok常用注解