首页 > 其他分享 >SpringBoot——测试

SpringBoot——测试

时间:2024-04-09 10:36:08浏览次数:16  
标签:web SpringBoot springframework 测试 org test import servlet

SpringBoot测试

源码在test-springboot

测试无非就是设定预期值与真实值比较,相同则测试通过,不同则测试失败

Ctrl+鼠标左键看源码,再按ctrl:f12查看方法

0、环境

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/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.2.5.RELEASE</version>
    </parent>

    <groupId>com.lmcode</groupId>
    <artifactId>lmcode</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>17</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>
    </dependencies>

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

</project>

package com.lmcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/** 可以通过args传入一些属性进行临时配置 */
@SpringBootApplication
public class TestSpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestSpringbootApplication.class, args);
    }
}
test.prop=testValue
server.port=9090

1、当前测试类专用属性

在小范围测试环境(例如当前测试类)有效,比多环境开发中的测试环境影响范围更小;

package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;


/**
 * 只在当前测试类中有效,加一个临时属性:properties
 * */
@SpringBootTest(properties = {"test.prop=testValue---properties"})
public class demo1_PropertiesTests {

    @Value("${test.prop}")
    private String msg;

    @Test
    public void testProperties(){
        System.out.println(msg);
    }
}
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;


/**
 * 只在当前测试类中有效,加一个临时属性:args
 * 优先级币properties高
 * 相对于在idea工具中写参数的好处是配置一直存在,不会因为换平台而消失
 * */
@SpringBootTest(properties = {"test.prop=testValue---properties"},
                args = {"--test.prop=testValue---args"})
public class demo2_ArgsTests {

    @Value("${test.prop}")
    private String msg;

    @Test
    void testArgs(){
        System.out.println(msg);
    }
}

2、 当前测试类专用配置

使用@Import加载当前测试类专用配置

package com.lmcode.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MsgConfig {

    @Bean
    public String msg(){
        return "bean---msg";
    }
}
package com.lmcode;

import com.lmcode.config.MsgConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;

/**
 * 局部的配置导入,仅在当前测试类生效
 * 临时加载bean,服务于测试【不能下载源码(main)中】
 * */
@SpringBootTest
@Import({MsgConfig.class})
public class demo3_ConfigurationTests {

    @Autowired
    private String msg;

    @Test
    void testConfiguration(){
        System.out.println(msg);
    }
}

3、模拟Web环境测试表现层

可以匹配Status、Error message、Headers、Content type、Body、Forwarded URL、Redirected URL、Cookies等都可以匹配

package com.lmcode.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping
    public String getById(){
        System.out.println("getById run success");
        return "success";
    }
}
3.1 测试类中启动web环境,发送虚拟请求并匹配响应执行状态
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;


/**
 * 属性是枚举类,其中RANDOM_PORT是随机端口
 * 可以通过把请求地址故意写错看预计不通过的控制台输出
 * */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 开启虚拟调用
@AutoConfigureMockMvc
public class demo4_WebTest {

    @Test
    void testWeb(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mockMvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(ok);
    }
}
3.2 匹配响应体
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;


/**
 * 属性是枚举类,其中RANDOM_PORT是随机端口
 * 可以通过把请求地址故意写错看预计不通过的控制台输出
 * */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 开启虚拟调用
@AutoConfigureMockMvc
public class demo4_WebTest {

    @Test
    void testBody(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("success");
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(result);
    }
}
3.3 匹配响应体(json)
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
package com.lmcode.domain;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private int id;
    private String name;
    private String type;
    private String description;
}
package com.lmcode.controller;

import com.lmcode.domain.Book;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping
    public String getById(){
        System.out.println("getById run success");
        return "success";
    }

    @GetMapping("/getAll")
    public Book getAll(){
        Book book = new Book();
        book.setId(1);
        book.setName("SpringBoot");
        book.setType("technology");
        book.setDescription("I'm No.1");
        System.out.println("getAll run success");
        return book;
    }
}
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;


/**
 * 属性是枚举类,其中RANDOM_PORT是随机端口
 * 可以通过把请求地址故意写错看预计不通过的控制台输出
 * */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 开启虚拟调用
@AutoConfigureMockMvc
public class demo4_WebTest {

    @Test
    void testWeb(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mockMvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(ok);
    }

    @Test
    void testBody(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/getAll");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\n" +
                "    \"id\": 1,\n" +
                "    \"name\": \"SpringBoot\",\n" +
                "    \"type\": \"technology\",\n" +
                "    \"description\": \"I'm No.1\"\n" +
                "}");
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(result);
    }
}
3.4 匹配响应头
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.HeaderResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;


/**
 * 属性是枚举类,其中RANDOM_PORT是随机端口
 * 可以通过把请求地址故意写错看预计不通过的控制台输出
 * */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 开启虚拟调用
@AutoConfigureMockMvc
public class demo4_WebTest {

    @Test
    void testWeb(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mockMvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(ok);
    }

    @Test
    void testBody(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/getAll");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\n" +
                "    \"id\": 1,\n" +
                "    \"name\": \"SpringBoot\",\n" +
                "    \"type\": \"technology\",\n" +
                "    \"description\": \"I'm No.1\"\n" +
                "}");
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(result);
    }

    @Test
    void testContentType(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/getAll");
        ResultActions action = mockMvc.perform(builder);
        // 设定预期值
        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher result = header.string("Content-Type","application/json");
        // 对比真实值,添加预计值到本次调用过程进行匹配 并 断言
        action.andExpect(result);
    }
}

3.5 测试多匹配【规范】
package com.lmcode;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.HeaderResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class demo5_WebTestFinal {

    @Test
    void getAll(@Autowired MockMvc mockMvc) throws Exception {
        // 模拟虚拟的http请求 并 执行
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/getAll");
        // 设定预期值
        ResultActions action = mockMvc.perform(builder);

        // status
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);

        // body
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\n" +
                "    \"id\": 90901,\n" +
                "    \"name\": \"SpringBoot\",\n" +
                "    \"type\": \"technology\",\n" +
                "    \"description\": \"I'm No.1\"\n" +
                "}");
        action.andExpect(result);

        // contentType
        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher contentType = header.string("Content-Type","application/json");
        action.andExpect(contentType);
    }

}

4、业务层测试事物回滚

为测试用例添加事物,SpringBoot会对测试用例对应的事物提交操作进行回滚

如皋要提交事物,可以通过@Rollback配置

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mini_springmvc?serverTimezone=UTC
      username: root
      password: 1234
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tb_
      id_type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
package com.lmcode.domain;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer id;
    private String name;
    private String type;
    private String description;
}
package com.lmcode.controller;

import com.lmcode.domain.Book;
import com.lmcode.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping
    public String getById(){
        System.out.println("getById run success");
        return "success";
    }

    @GetMapping("/getAll")
    public Book getAll(){
        Book book = new Book();
        book.setId(90901);
        book.setName("SpringBoot");
        book.setType("technology");
        book.setDescription("I'm No.1");
        System.out.println("getAll run success");
        return book;
    }

    @Autowired
    private BookService bookService;
    @PostMapping("/save")
    public Boolean save(@RequestBody Book book){
        return bookService.save(book);
    }
}
package com.lmcode.service;

import com.lmcode.domain.Book;

public interface BookService {
    boolean save(Book book);
}
package com.lmcode.service.impl;

import com.lmcode.domain.Book;
import com.lmcode.mapper.BookMapper;
import com.lmcode.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookMapper bookMapper;
    @Override
    public boolean save(Book book) {
        return bookMapper.insert(book) > 0;
    }
}
package com.lmcode.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lmcode.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookMapper extends BaseMapper<Book> {
}
package com.lmcode;

import com.lmcode.domain.Book;
import com.lmcode.service.BookService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;


/** spring会自动识别,在测试类加事物自动回滚*/
@SpringBootTest
@Transactional
@Rollback(value = false)
//@Rollback(value = true)
public class demo6_ServiceTest {
    @Autowired
    private BookService bookService;

    @Test
    void testSave(){
        Book book = new Book();
        book.setName("傲慢与偏见");
        book.setType("文学类");
        book.setDescription("你要放下你的偏见");
        bookService.save(book);
    }
}

5、测试用例设置随机数据

测试用例数据通常采用随机值进行测试,可以通过配置使用SpringBoot提供的随机数为其赋值

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mini_springmvc?serverTimezone=UTC
      username: root
      password: 1234
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tb_
      id_type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# int,value(String),uuid(String),long(long,可以存时间)
testcase:
  book:
    id: ${random.int(90900,10000)}
    name: ${random.value}
    type: ${random.value}
    description: 描述${random.value}
package com.lmcode.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
// 未配置Spring Boot 配置注解处理器
@ConfigurationProperties(prefix = "testcase.book")
public class Book {
    private Integer id;
    private String name;
    private String type;
    private String description;
}
package com.lmcode;

import com.lmcode.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class demo7_UseTestCase {
    @Autowired
    private Book book;
    @Test
    void testCase(){
        System.out.println(book);
        /* md5加密字符串,32位
         Book(id=-552308655,
         name=ab6939419e9dbcb95d679d185d9595ea,
         type=70d0625bf03e57a3e8b7e312b0ac865c,
         description=描述be4dee034654bd1ecaab738073459fa2)
         */

    }
}
<!--配置Spring Boot 配置注解处理器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

标签:web,SpringBoot,springframework,测试,org,test,import,servlet
From: https://www.cnblogs.com/lm02/p/18123318

相关文章

  • SpringBoot集成jasypt,加密yml配置文件
    一、Jasypt简介Jasypt是一个Java简易加密库,用于加密配置文件中的敏感信息,如数据库密码。jasypt库与springboot集成,在实际开发中非常方便。1、JasyptSpringBoot为springboot应用程序中的属性源提供加密支持,出于安全考虑,Springboot配置文件中的敏感信息通常需要对它进......
  • springboot本地打war包
    1、pom.xml修改图里标注的①②,新增③,图片下面有我打包的pom.xml大家可以参考<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:s......
  • 强!推荐一款API 接口自动化测试平台!
    在项目开发,迭代交付过程中开发人员,测试人员需要针对系统微服务API做调试,回归测试,性能测试。自动化测试,一个好的平台本质上需要解决API测试的5大基本问题。1.支持不同的项目,角色,技术人员多人协作2.支持定义多个不同的测试环境3.支持定义各种被测系统,API,功能,性能用例4.支持功能......
  • 基于SpringBoot+MySQL+SSM+Vue.js的生鲜在线销售系统(附论文)
    演示视频基于SpringBoot+MySQL+SSM+Vue.js的生鲜在线销售系统技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的生鲜在线销售系统(附......
  • 基于SpringBoot+MySQL+SSM+Vue.js的招聘系统(附论文)
    演示视频基于SpringBoot+MySQL+SSM+Vue.js的招聘系统技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的招聘系统(附论文),用户,管理员......
  • java计算机毕业设计房地产公司员工工单管理系统(附源码+springboot+开题+论文+部署)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着房地产行业的迅猛发展,企业内部的运营和管理面临着越来越高的要求。特别是在员工工单管理方面,传统的纸质工单或简单的电子记录方式已经无法满足企......
  • java计算机毕业设计房产中介管理(附源码+springboot+开题+论文+部署)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在当前的房地产市场环境下,房产中介作为连接买卖双方的重要桥梁,其运营效率和服务质量直接影响到市场的健康发展和客户的满意度。然而,传统的房产中介管......
  • 【SpringBoot + Tomcat】请求到达后端服务进程后的处理过程
    1 前言这节我主要是想看下,Tomcat如何接收到请求并且是怎么一步步封装并交给SpringMVC处理的。这块之前一直没太深入的了解过,所以这节我们来看看。在看这节之前,你首先要清楚这两个问题,方便你更好的去理解。(1)SpringBoot启动的过程中,Tomcat的创建和启动时机是在什么时候呢?不......
  • SpringBoot通过token实现用户互踢功能
    认识token所谓token,既用户能够在一定时间内证明自己身份的一长串字符串。正常的使用流程为:用户第一次登入——》服务器为该用户签发一份token——》进行其他服务请求时携带上token——》服务器判断此token在有效期内——》放行此次请求。在上述过程中,用户只有在请求特定的接......
  • 校验ChatGPT 4真实性的三个经典问题:提供免费测试网站快速区分 GPT3.5 与 GPT4
    现在已经有很多ChatGPT的套壳网站,以下分享验明GPT-4真身的三个经典问题,帮助你快速区分套壳网站背后到底用的是GPT-3.5还是GPT-4。大家可以在这个网站测试:https://ai.hxkj.vip,免登录可以问三条,登录之后无限制。咱们使用免登录的额度测试就已经够用了测试问题1:Wha......