SpringBoot项目实战记录

SpringBoot项目实战记录

1:项目初始化

(1)新建项目
(2)给pox.xml添加依赖

首先就是添加项目下载仓库为阿里云仓库

<repositories>
    <repository>
        <id>nexus-aliyun</id>
        <name>nexus-aliyun</name>
        <url>http://aliyun.com/nexus/content/groups/public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>public</id>
        <name>aliyun nexus</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

并且在dependencies下添加baomidou

 <!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>
(3)编写配置文件application.yml

springBoot工程中是有一个application.yml配置文件的啊,其实application.yml的功能和application.properties是一样的,不过因为yml文件是树状结构,写起来有更好的层次感,更易于理解,所以很多人都选择了yml文件。

server:
// 修改端口为9090端口
  port: 9090

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    // ?serverTimezone=GMT%2b8表示时区为东八区
    url: jdbc:mysql://localhost:3306/party_building?serverTimezone=GMT%2b8
    username: root
    password: 528957

2:初步编写Mybatis

(1)添加实体entity

所有的实体类需要加上如下注释

@Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法

@AllArgsConstructor : 注在类上,提供类的全参构造

@NoArgsConstructor : 注在类上,提供类的无参构造

比如现在对于一个党建信息的实体类(com/example/entity/PartyInf.java)

package com.example.entity;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PartyInf {
    //  序号0
//    @TableId(type = IdType.AUTO)
    private Integer id;
    //  市(州)1
    private String shi;
    ......
    //  创建时间
    private LocalDateTime create_time;
}
(2)添加Mapper接口

重点就是这个mapper或者有些人命名为dao的接口需要一个@Mapper的注释声明这是一个mapper接口,如果使用mybatis这个接口时直接对接sql语句的。

(com/example/Mapper/PartyInfMapper.java)

package com.example.mapper;

import com.example.entity.PartyInf;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface PartyInfMapper {
    @Select("select * from party_inf")
    List<PartyInf> findAll();
}

但是现在这个没有被SpringBoot所管理,呗SpringBoot管理的都必须要有@Conponent

(3)添加控制器类Controller

控制器类主要就是使用@RestController声明这是一个控制器,然后使用 @Autowired调用Mapper里的方法。

package com.example.controller;

import com.example.entity.PartyInf;
import com.example.mapper.PartyInfMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class PartyInfController {
    @Autowired
    private PartyInfMapper partyInfMapper;

    @GetMapping("/party/findAll")
    public List<PartyInf> findAll(){
        return partyInfMapper.findAll();
    }
}
(4)服务类Service

加一个Service

Service需要注解@Service,和@Mapper一样需要这个注解把这个类注入到SpringBoot的容器内

package com.example.service;


import com.example.entity.PartyInf;
import com.example.mapper.PartyInfMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PartyInfService {
    @Autowired
    private PartyInfMapper partyInfMapper;
}

3:Mybatis实现增删改查

对用户表进行增删改查

首先就是实体类

com/example/entity/UserInf.java

package com.example.entity;

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

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInf {
    private Integer id;
    private String username;
    private String password;
    private Integer power;
    private String region;
}
之后Mapper数据库操作接口

com/example/mapper/UserInfMapper.java

package com.example.mapper;

import com.example.entity.UserInf;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface UserInfMapper {

    @Select("select * from user_inf")
    List<UserInf> findAll();
    @Insert("INSERT INTO user_inf(username,password,power,region) VALUES (#{username},#{password},#{power},#{region})")
    int insert(UserInf userInf);
    @Update("UPDATE user_inf SET username=#{username},password=#{password},power=#{power},region=#{region} WHERE id=#{id}")
    int update(UserInf userInf);
    @Delete("DELETE FROM user_inf WHERE id=#{id}")
    int delete(@Param("id") Integer id);
}
Service服务类

com/example/service/UserInfService.java

package com.example.service;

import com.example.entity.UserInf;
import com.example.mapper.UserInfMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserInfService {
    @Autowired
    private UserInfMapper userInfMapper;
    public int save(UserInf userInf){
        if (userInf.getId() == null){
            return userInfMapper.insert(userInf);
        }else {
            return userInfMapper.update(userInf);
        }
    }
}
Controller控制器类

com/example/controller/UserInfController.java

package com.example.controller;

import com.example.entity.UserInf;
import com.example.mapper.UserInfMapper;
import com.example.service.UserInfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserInfController {
    @Autowired
    private UserInfMapper userInfMapper;
    @Autowired
    private UserInfService userInfService;

    @GetMapping("/findAll")
    public List<UserInf> findAll(){
        return userInfMapper.findAll();
    }
    @PostMapping("/save")
    public Integer save(@RequestBody UserInf userInf){
        System.out.println(userInf);
        return userInfService.save(userInf);
    }
    @DeleteMapping("/delete/{id}")
    public Integer delete(@PathVariable Integer id){
        return userInfMapper.delete(id);
    }
}

4:SpringBoot解决跨域问题

后端接口写好了前端要用axios进行数据请求还需要配置跨域,跨域分为前端跨域和后端跨域,后端跨域是一种一劳永逸的做法,所以本次开发对后端进行跨域配置。

新建一个config类com/example/config/CorsConfig.java

package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("http://localhost:8080"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

5:Mybatis-Plus进行实现分页查询

(1)配置Mybatis-Plus

先在pom.xml下的dependencies标签下引入依赖

<!--  mybatis-plus    -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

之后创建一个Mybatis-Plus的Config插件

com/example/config/MybatisPlusConfig.java

package com.example.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//这个是Mapper层的代码存放目录,之后就可以把Mapper里面的@Mapper注释去掉,这样的好处就是所有的配置统一管理
@MapperScan("com/example/mapper")
public class MybatisPlusConfig {
    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor (DbType.MYSQL));
        return interceptor;
    }
}
(2)Mybatis-Plus修改原本的增删改查

首先就是修改mapper,Mybatis-Plus下的mapper需要继承BaseMapper<实体>。

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.UserInf;
import org.apache.ibatis.annotations.*;
import java.util.List;

//@Mapper
public interface UserInfMapper extends BaseMapper<UserInf> {
    @Select("select * from user_inf")
    List<UserInf> findAll();
    @Insert("INSERT INTO user_inf(username,password,power,region) VALUES (#{username},#{password},#{power},#{region})")
    int insert(UserInf userInf);
    @Update("UPDATE user_inf SET username=#{username},password=#{password},power=#{power},region=#{region} WHERE id=#{id}")
    int update(UserInf userInf);
    @Delete("DELETE FROM user_inf WHERE id=#{id}")
    int delete(@Param("id") Integer id);
}

之后修改服务类,Mybatis-Plus自带了一个save方法,所以原本的sava方法就不用了

package com.example.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.UserInf;
import com.example.mapper.UserInfMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserInfService extends ServiceImpl<UserInfMapper,UserInf> {
    public boolean saveUserInf(UserInf userInf){
        return saveOrUpdate(userInf);
    }
}

其他的都可以不变

分页查询代码

5:Vue使用axios进行api请求

(1)装配axios

先安装axios

yarn add axios@0.25.0

在前端项目的src文件夹下新建一个文件夹utils,之后新建文件request.js,request代码如下

src\utils\request.js

import axios from 'axios'

const request = axios.create({
      // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在
      //  页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
	baseURL: '/api',
    timeout: 5000
})

// request 拦截器(对请求头进行处理)
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
  
    // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器(对响应结果进行处理)
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)

export default request

最后在main.js中引入一下

import request from '@/utils/request'

Vue.prototype.request = request
(2)使用axios进行get和post请求

GET请求

this.request.get("http://127.0.0.1:9090/party/page", {
    params: {
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        xxmc: this.xxmc,
        xxlx: this.xxlx,
        dzzszxs: this.dzzszxs,
    }
}).then(res => {
    this.tableData = res.data.records
    this.total = res.data.total
})

POST请求

this.request.post("http://127.0.0.1:9090/party/save", this.form).then(res => {
    if (res.data) {
        this.$message.success("保存成功")
        this.dialogFormVisible = false
        this.load()
    } else {
        this.$message.error("保存失败")
        this.dialogFormVisible = false
        this.load()
    }
})

DELETE请求

this.request.delete("http://127.0.0.1:9090/party/delete/" + id).then(res => {
    if (res.data) {
        this.$message.success("删除成功")
        this.load()
    } else {
        this.$message.error("删除失败")
        this.load()
    }
})

6:SpringBoot+Vue登录

先写后端嘛

(1)SpringBoot创建接收登录参数的DTO

登录主要就只需要账号密码,在Controller项目包下创建一个项目包名为DTO

创建一个LogoinDto.java,需要#Date参数声明这是一个Date型类,

com/example/controller/dto/LoginDto.java代码如下:

package com.example.controller.dto;

import lombok.Data;

@Data
public class LoginDto {
    public String username;
    public String password;
}

之后编写登录验证函数

控制器类com/example/controller/UserInfController.java

@PostMapping("/login")
public Result login(@RequestBody LoginDto loginDto){
    String userneme = loginDto.getUsername();
    String password = loginDto.getPassword();
    if (StringUtils.isBlank(userneme) || StringUtils.isBlank(password)){
        return Result.error("404","账号或密码不可为空");
    }
    UserInf userInf = userInfService.login(loginDto);
    if (userInf == null){
        return Result.error("404","账号或密码错误");
    }
    return Result.success(userInfService.login(loginDto));
}

服务类com/example/service/UserInfService.java

public UserInf login(LoginDto loginDto) {
    QueryWrapper<UserInf> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username",loginDto.getUsername());
    queryWrapper.eq("password",loginDto.getPassword());
    UserInf userInf = getOne(queryWrapper);
    return userInf;
}

Postman测试一下可行,开始编写前端界面

(2)Vue axios调用登录接口
<template>
  <div id="Login" class="wrapper">
    <div style="margin:200px auto; background-color: #fff; width: 350px; height: 300px; padding: 20px; border-radius: 10px;">
      <div style="margin: 20px 0; text-align: center; font-size: 24px;"><b>Welcome</b></div>
      <el-form :rules="rules" :model="user" ref="userForm">
        <el-form-item prop="username" label="">
          <el-input placeholder="请输入账号" size="medium" style="margin:10px 0" prefix-icon="el-icon-user" v-model="user.username"></el-input>
        </el-form-item>
        <el-form-item prop="password" label="">
          <el-input placeholder="请输入密码" size="medium" style="margin:10px 0" prefix-icon="el-icon-lock" show-password v-model="user.password"></el-input>
        </el-form-item>
        <div style="margin: 10px 0;text-align:right">
          <el-button type="primary" size="small" autocomplete="off" @click="login">登录</el-button>
        </div>
      </el-form>
    </div>
  </div>
</template>

<script>
name:"Login"
export default {
  data(){
    return{
      adminLogin:'0',
      user: {
        username: "username",
        password: "123456"
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 3, max: 20, message: '用户名长度在 6 到 20 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 3, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' }
        ],
      }
    }
  },
  methods:{
    login(){
      this.$refs['userForm'].validate((valid) => {
        if (valid) {
          // 用户登录
          if (this.adminLogin === '0'){
            this.request.post("http://127.0.0.1:9090/user/login", this.user).then(res =>{
              if(res.code === '200'){
                this.$message.success('登录成功,欢迎使用!!!');
            //     localStorage.setItem("user", JSON.stringify(res.data))  // 存储用户信息到前端浏览器
            //     this.$router.push("/Manage/home")
              }else{
                this.$message.error(res.msg);
              }
              console.log(res)
            })
          }
        } else {
          this.$message.error('请以正确的方式输入登录信息!!');
          return false;
        }
      });
      
    }
  }
}
</script>
<style>
  .wrapper{
    height: 100vh;
    background-image: linear-gradient(to bottom right,#FC466B,#3F5EFB);
    overflow: hidden;
  }
</style>

7:SpringBoot集成JWT(Json Web Token)

(1)JWT简介

Jwt全称是:json web token。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

优点
  1. 简洁: 可以通过URL、POST参数或者在HTTP header发送,因为数据量小,传输速度也很快;
  2. 自包含:负载中可以包含用户所需要的信息,避免了多次查询数据库;
  3. 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持;
  4. 不需要在服务端保存会话信息,特别适用于分布式微服务。
缺点
  1. 无法作废已颁布的令牌;
  2. 不易应对数据过期。
(2)JWT组成

一个token分3部分,按顺序为

  1. 头部(header)
  2. 载荷(payload)
  3. 签证(signature)

三部分之间用“.”号做分隔。

/*不废话了,开始使用Token/

(3)JWT的使用
1)SpringBoot引入jwt

项目依赖pom.xml

<!--JWT-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>
<!--hutool-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.20</version>
</dependency>
2)编写token工具类

先写一个生成token的方法,将用户id作为载荷,用户密码作为密钥生成token

建立一个utils的插件包,创建一个TokenUtils代码如下:
com/example/utils/TokenUtils.java

package com.example.utils;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;

public class TokenUtils {
    public static String genToken(String userId, String sign) {
        return JWT.create().withAudience(userId) // 将 userId 保存到 token 里面,作为载荷
                .withExpiresAt(DateUtil.offsetDay (new Date(), 1)) // 设置1天(offsetDay)后token过期
                .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
    }
}
3)修改登录的返回值以及方法,把token一起作为返回值的返回到前端

com/example/controller/dto/UserDto.java

package com.example.controller.dto;

import lombok.Data;

@Data
public class UserDto {
    private Integer id;
    private String username;
    private String password;
    private Integer power;
    private String shi;
    private String xian;
    private String token;
}

com/example/controller/UserInfController.java

@PostMapping("/login")
public Result login(@RequestBody UserDto userDto){
    String userneme = userDto.getUsername();
    String password = userDto.getPassword();
    if (StringUtils.isBlank(userneme) || StringUtils.isBlank(password)){
        return Result.error("404","账号或密码不可为空");
    }
    if (userInfService.login(userDto) == null){
        return Result.error("404","账号或密码错误");
    }
    return Result.success(userInfService.login(userDto));
}

com/example/service/UserInfService.java

public UserDto login(UserDto userDto) {
    QueryWrapper<UserInf> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username",userDto.getUsername());
    queryWrapper.eq("password",userDto.getPassword());
    UserInf userInf = getOne(queryWrapper);
    if (userInf == null){
        return null;
    }else {
        BeanUtil.copyProperties(userInf,userDto,true);
        userDto.setToken(TokenUtils.genToken(userDto.getId().toString(),userDto.getPassword()));
        return userDto;
    }
}
4)前端在接收到登录时把返回参数保存下来,并且设置登陆之后的请求时带上token

先修改axios的配置文件,utils/request.js

import axios from 'axios'

const request = axios.create({
      // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在
      //  页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
	baseURL: 'http://127.0.0.1:9090',
    timeout: 5000
})

// request 拦截器(对请求头进行处理)
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
    if(user){
        config.headers['token'] = user.token;  // 设置请求头
    }
    
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器(对响应结果进行处理)
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)
export default request

之后修改一下登录的login方法。

this.request.post("/user/login", this.user).then(res =>{
              if(res.code === '200'){
                this.$message.success('登录成功,欢迎使用!!!');
                localStorage.setItem("user", JSON.stringify(res.data))// 存储用户信息到前端浏览器
                this.$router.push("/")
              }else{
                this.$message.error(res.msg);
              }
              console.log(res)
            })

if (response.config.responseType === ‘blob’) {
return res
}
// 兼容服务端返回的字符串数据
if (typeof res === ‘string’) {
res = res ? JSON.parse(res) : res
}
return res;
},
error => {
console.log(‘err’ + error) // for debug
return Promise.reject(error)
}
)
export default request


[外链图片转存中...(img-hs5Hiwcu-1667960992419)]

之后修改一下登录的login方法。

```js
this.request.post("/user/login", this.user).then(res =>{
              if(res.code === '200'){
                this.$message.success('登录成功,欢迎使用!!!');
                localStorage.setItem("user", JSON.stringify(res.data))// 存储用户信息到前端浏览器
                this.$router.push("/")
              }else{
                this.$message.error(res.msg);
              }
              console.log(res)
            })
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SpringBoot实战(第4版)清晰文字版,第 1 章 入门 ................................................ 1 1.1 Spring 风云再起 ........................................ 1 1.1.1 重新认识 Spring ............................ 2 1.1.2 Spring Boot 精要 ........................... 3 1.1.3 Spring Boot 不是什么 ................... 6 1.2 Spring Boot 入门 ....................................... 6 1.2.1 安装 Spring Boot CLI .................... 7 1.2.2 使用 Spring Initializr 初始化 Spring Boot 项目 .......................... 10 1.3 小结 ......................................................... 18 第 2 章 开发第一个应用程序 .................... 19 2.1 运用 Spring Boot ..................................... 19 2.1.1 查看初始化的 Spring Boot 新项目 .......................................... 21 2.1.2 Spring Boot 项目构建过程 解析 .............................................. 24 2.2 使用起步依赖 .......................................... 27 2.2.1 指定基于功能的依赖 ................... 28 2.2.2 覆盖起步依赖引入的传递依赖 .... 29 2.3 使用自动配置 .......................................... 30 2.3.1 专注于应用程序功能 ................... 31 2.3.2 运行应用程序 .............................. 36 2.3.3 刚刚发生了什么 ........................... 38 2.4 小结 ......................................................... 41 第 3 章 自定义配置 .................................... 42 3.1 覆盖 Spring Boot 自动配置 ..................... 42 3.1.1 保护应用程序 .............................. 43 3.1.2 创建自定义的安全配置 ............... 44 3.1.3 掀开自动配置的神秘面纱 ........... 48 3.2 通过属性文件外置配置 ........................... 49 3.2.1 自动配置微调 .............................. 50 3.2.2 应用程序 Bean 的配置外置 ......... 55 3.2.3 使用 Profile 进行配置 .................. 59 3.3 定制应用程序错误页面 ........................... 62 3.4 小结 ......................................................... 64 第 4 章 测试 ............................................... 66 4.1 集成测试自动配置 .................................. 66 4.2 测试 Web 应用程序 ................................. 68 4.2.1 模拟 Spring MVC ........................ 69 4.2.2 测试 Web 安全 ............................. 72 4.3 测试运行中的应用程序 ........................... 74 4.3.1 用随机端口启动服务器 ............... 75 4.3.2 使用 Selenium 测试 HTML 页面 ............................................. 76 4.4 小结 ......................................................... 78 第 5 章 Groovy 与 Spring Boot CLI ......... 80 5.1 开发 Spring Boot CLI 应用程序 .............. 80 5.1.1 设置 CLI 项目 .............................. 81 5.1.2 通过 Groovy 消除代码噪声 ......... 81 5.1.3 发生了什么 .................................. 85 5.2 获取依赖 .................................................. 86 5.2.1 覆盖默认依赖版本 ....................... 87 5.2.2 添加依赖仓库 .............................. 88 5.3 用 CLI 运行测试 ...................................... 89 5.4 创建可部署的产物 .................................. 91 5.5 小结 ......................................................... 91 第 6 章 在 Spring Boot 中使用 Grails ...... 93 6.1 使用 GORM 进行数据持久化 ................. 93 2 目 录 6.2 使用 Groovy Server Pages 定义视图 ....... 98 6.3 结合 Spring Boot 与 Grails 3 ................. 100 6.3.1 创建新的 Grails 项目 ................. 100 6.3.2 定义领域模型 ............................ 103 6.3.3 开发 Grails 控制器 ..................... 104 6.3.4 创建视图 .................................... 105 6.4 小结 ....................................................... 107 第 7 章 深入 Actuator .............................. 108 7.1 揭秘 Actuator 的端点 ............................ 108 7.1.1 查看配置明细 ............................ 109 7.1.2 运行时度量 ................................ 115 7.1.3 关闭应用程序 ............................ 121 7.1.4 获取应用信息 ............................ 121 7.2 连接 Actuator 的远程 shell .................... 122 7.2.1 查看 autoconfig 报告 ........... 123 7.2.2 列出应用程序的 Bean ............... 124 7.2.3 查看应用程序的度量信息 ......... 124 7.2.4 调用 Actuator 端点 .................... 125 7.3 通过 JMX 监控应用程序 ....................... 126 7.4 定制 Actuator......................................... 128 7.4.1 修改端点 ID ............................... 128 7.4.2 启用和禁用端点 ........................ 129 7.4.3 添加自定义度量信息 ................. 129 7.4.4 创建自定义跟踪仓库 ................. 132 7.4.5 插入自定义健康指示器 ............. 134 7.5 保护 Actuator 端点 ................................ 136 7.6 小结 ....................................................... 138 第 8 章 部署 Spring Boot 应用程序 ........ 139 8.1 衡量多种部署方式 ................................ 139 8.2 部署到应用服务器 ................................ 140 8.2.1 构建 WAR 文件 ......................... 141 8.2.2 创建生产 Profile ........................ 142 8.2.3 开启数据库迁移 ........................ 145 8.3 推上云端 ............................................... 150 8.3.1 部署到 Cloud Foundry ............... 150 8.3.2 部署到 Heroku ........................... 153 8.4 小结 ....................................................... 155 附录 A Spring Boot 开发者工具.............. 157 附录 B Spring Boot 起步依赖 ................. 163 附录 C 配置属性 ...................................... 169 附录 D Spring Boot 依赖 ......................... 202
当前课程中博客项目的实战源码是我在 GitHub上开源项目 My-Blog,目前已有 3000 多个 star:本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 个人博客项目功能的讲解,通过本课程的学习,不仅仅让你掌握基本的 Spring Boot 开发能力以及 Spring Boot 项目的大部分开发使用场景,同时帮你提前甄别和处理掉将要遇到的技术难点,认真学完这个课程后,你将会对 Spring Boot 有更加深入而全面的了解,同时你也会得到一个大家都在使用的博客系统源码,你可以根据自己的需求和想法进行改造,也可以直接使用它来作为自己的个人网站,这个课程一定会给你带来巨大的收获。作者寄语本课程录制于 2020 年,代码基于 Spring Boot 2.x 版本。到目前为止,Spring Boot 技术栈也有一些版本升级,比如 Spring Boot 2.7 发版、Spring Boot 3.x 版本发布正式版本。对于这些情况,笔者会在本课程实战项目的开源仓库中创建不同的代码分支,保持实战项目的源码更新,保证读者朋友们不会学习过气的知识点。课程特色 课程内容紧贴 Spring Boot 技术栈,涵盖大部分 Spring Boot 使用场景。开发教程详细完整、文档资源齐全、实验过程循序渐进简单明了。实践项目页面美观且实用,交互效果完美。包含从零搭建项目、以及完整的后台管理系统和博客展示系统两个系统的功能开发流程。技术栈新颖且知识点丰富,学习后可以提升大家对于知识的理解和掌握,对于提升你的市场竞争力有一定的帮助。实战项目预览    
当前课程中商城项目的实战源码是我发布在 GitHub 上的开源项目 newbee-mall (新蜂商城),目前已有 9900 多个 Star,本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 商城项目功能的讲解,让大家实际操作并实践上手一个大型的线上商城项目,并学习到一定的开发经验以及其中的开发技巧。商城项目所涉及的功能结构图整理如下: 作者寄语本课程录制于2019年,距今已有一段时间。期间,Spring Boot技术栈也有一些版本升级,比如Spring Boot 2.7.x发版、Spring Boot 3.x版本正式版本。对于这些情况,笔者会在本课程实战项目的开源仓库中创建不同的代码分支,保持实战项目的源码更新,保证读者朋友们不会学习过气的知识点。新蜂商城的优化和迭代工作不会停止,不仅仅是功能的优化,在技术栈上也会不断的增加,截止2023年,新蜂商城已经发布了 7 个重要的版本,版本记录及开发计划如下图所示。 课程特色 对新手开发者十分友好,无需复杂的操作步骤,仅需 2 秒就可以启动这个完整的商城项目最终的实战项目是一个企业级别的 Spring Boot 大型项目,对于各个阶段的 Java 开发者都是极佳的选择实践项目页面美观且实用,交互效果完美教程详细开发教程详细完整、文档资源齐全代码+讲解+演示网站全方位保证,向 Hello World 教程说拜拜技术栈新颖且知识点丰富,学习后可以提升大家对于知识的理解和掌握,可以进一步提升你的市场竞争力 课程预览 以下为商城项目的页面和功能展示,分别为:商城首页 1商城首页 2购物车订单结算订单列表支付页面后台管理系统登录页商品管理商品编辑

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Addam Holmes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值