一. 概述

1.為什麼使用SpringBoot

Spring雖然有很多優點, 但是Spring框架的搭建非常麻煩

1. 配置麻煩,而且很多都是模版化的配置(固定的)

2. 需要添加很多依賴, 例如web層依賴jackson組件,需要我們自己添加, 版本也可能不匹配

基於以上兩點,spring官方推出了SpringBoot .

2. 搭建

new project ---- java ----Maven

添加父工程 (不放在dependencies裏面)

<!--依賴的父級工程-->

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.6.6</version>

<relativePath/>

</parent>

添加依賴

<!--添加基本的 springweb 依賴-->

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

添加打包插件(不放在dependencies裏面)

<!--打包插件-->

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<version>2.6.6</version>

</plugin>

</plugins>

</build>

添加啓動類

package com.ffyc.news;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

/*springboot應用的啓動類*/

@SpringBootApplication
//@EnableScheduling
@MapperScan("com.ffyc.news.dao")
public class NewsApplication {

    public static void main(String[] args) {
        SpringApplication.run(NewsApplication.class);
    }
}

創建web層 service層 dao層 model層 config層(配置層) interceptor層(攔截器)

在resources下創建applicantion.yml文件(配置值的文件)

3. 配置值文件

application.properties

屬性文件格式,內容為鍵值對 server.port=8080

properties 格式比較簡單,沒有什麼難度,在此我們以第二種 yaml 格式為例.

application.yml(重要)

yml 是 YAML(YAML Ain’t Markup Language)語言的文件,以數據為中心.

1.yaml 基本語法: 語法結構:key:空格 value; ( 注意: 空格不能省略)

2. 以空格的縮進來控制層級關係,只要是左邊對齊的一列數據都是同一個層級的;

3. 字面量直接寫在後面就可以,字符串默認不用加上雙引號或者單引號;

4. 以#作為註釋符號.

5. 使用@Value 註解標籤將配置文件中的內容映射到類中的屬性. @Value("${user.name}")

4. Spring數據訪問管理

數據源配置

為了連接數據庫需要引入 jdbc 支持,在 pom.xml 中添加依賴  (記得添加 mysql 驅動依賴)

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

在 application.yml 中配置數據源信息(本次使用的是阿里數據源)

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    #url: jdbc:mysql://127.0.0.1:3306/newsdb?serverTimezone=Asia/Shanghai
    url: jdbc:mysql://192.168.244.128:3306/newsdb?serverTimezone=Asia/Shanghai
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource #指定數據庫連接管理類
    initialSize: 5
    maxActive: 20

添加阿里數據源依賴

<!-- 阿里數據源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

複製一個前端項目, 刪除裏面不需要的文件和配置

最全面的SpringBoot教程(一)——SpringBoot概述_#spring boot

5. 解決跨域問題

出現此錯誤需要解決跨域問題

最全面的SpringBoot教程(一)——SpringBoot概述_spring_02

添加配置類

package com.ffyc.news.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;
import java.util.Collections;



@Configuration//配置類,啓動時被掃描
public class CorsConfig {

    @Bean//等價於<bean id="" class=""/>配置我們的類(創建 配置 和返回對象),交給spring管理
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //1,允許任何來源
        corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
        //2,允許任何請求頭
        corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
        //3,允許任何方法
        corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
        //4,允許憑證
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(source);
    }


}

 雖然springboot簡化了spring應用的搭建,將一些常用的基礎組件自動配置
 但是項目中會用到各種各樣的組件,有的組件springboot沒有提供自動配置,
 需要我們自己來配置
 springboot不使用xml文件配置,而是使用Java代碼中配置

6.token攔截器

操作: 登錄成功後在後端生成token, 在前端瀏覽器保存token

  在util包下導入jwt(秘鑰獲得token),並添加依賴. 

package com.ffyc.news.util;


import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.ffyc.news.model.Admin;
import com.ffyc.news.model.User;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具類
 */
public class JWTUtil {

    /**
     * 根據用户id,賬號生成token
     * @param admin
     * @return
     */
    public static String getToken(Admin admin) {
        String token = "";
        try {
            //過期時間 為1970.1.1 0:0:0 至 過期時間  當前的毫秒值 + 有效時間
            Date expireDate = new Date(new Date().getTime() + 3600*1000);
            //秘鑰及加密算法
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            //設置頭部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //攜帶id,賬號信息,生成簽名
            token = JWT.create()
                    .withHeader(header)//第一部分
                    //第二部分
                    .withClaim("id",admin.getId())
                    .withClaim("account",admin.getAccount())
                    .withClaim("type",admin.getType())//在token裏面顯示管理員類型
                    .withExpiresAt(expireDate)//設置有效時間
                    .sign(algorithm);//第三部分
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
    }
    public static String getUserToken(User user) {
        String token = "";
        try {
            //過期時間 為1970.1.1 0:0:0 至 過期時間  當前的毫秒值 + 有效時間
            Date expireDate = new Date(new Date().getTime() + 3600*24*14*1000);
            //秘鑰及加密算法
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            //設置頭部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //攜帶id,賬號信息,生成簽名
            token = JWT.create()
                    .withHeader(header)//第一部分
                    //第二部分
                    .withClaim("id",user.getId())
                    .withClaim("email",user.getEmail())
                    .withExpiresAt(expireDate)//設置有效時間
                    .sign(algorithm);//第三部分
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
    }


    /**
     * 驗證token是否有效
     * @param token
     * @return
     */
    public static boolean verify(String token){
        try {
            //驗籤
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {//當傳過來的token如果有問題,拋出異常
            return false;
        }
    }

    /**
     * 獲得token 中playload部分數據,按需使用
     * @param token
     * @return
     */
    public static DecodedJWT getTokenInfo(String token){
        return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
    }
    public static  Admin getOperAdmin(String token){
        DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
        int adminid = decodedJWT.getClaim("id").asInt();
        Admin admin = new Admin();
        admin.setId(adminid);
        return  admin;
    }

}

<!--jwt組件-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.2</version>
</dependency>

操作: 在後端創建token驗證攔截器,並配置攔截器

添加攔截器

package com.ffyc.news.interceptor;

import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.news.model.Result;
import com.ffyc.news.util.JWTUtil;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//攔截器
public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token =request.getHeader("token");
        System.out.println("token 認證攔截器:"+token);
        if(JWTUtil.verify(token)){//認證token
            return true;//離開攔截器,繼續向後到達自定義處理器
        }else {
            response.setContentType("text/html;charset=utf-8");//設置響應內容的格式

            Result result = new Result(401,"token認證失敗",null);
            response.getWriter().write(new ObjectMapper().writeValueAsString(result));
            return false;//不繼續向後執行
        }
    }
}

配置攔截器

package com.ffyc.news.config;

import com.ffyc.news.interceptor.TokenInterceptor;
import com.ffyc.news.interceptor.UserTokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class WebConfig implements WebMvcConfigurer{
    //添加(配置)攔截器
	public void addInterceptors(InterceptorRegistry registry) {
		//添加(配置)管理員攔截器
		InterceptorRegistration inter =  registry.addInterceptor(new TokenInterceptor());//註冊自己的攔截器
		inter.addPathPatterns("/api/**"); //進入攔截器的地址 (管理員需要攔截的地址)
		inter.excludePathPatterns("/api/loginCtl/login");//不進入攔截器的地址
       //添加(配置)用户攔截器
		InterceptorRegistration userInter =  registry.addInterceptor(new UserTokenInterceptor());//註冊自己的攔截器
		userInter.addPathPatterns("/user/userCtl/**"); //進入攔截器的地址 (管理員需要攔截的地址)
		//以下不需要進入攔截器
		userInter.excludePathPatterns("/user/userCtl/createCode");//生成郵箱驗證碼不進入攔截器的地址
		userInter.excludePathPatterns("/user/userCtl/saveUser");//註冊保存不進入攔截器的地址
		userInter.excludePathPatterns("/user/userCtl/create");//生成圖形驗證碼不進入攔截器的地址
		userInter.excludePathPatterns("/user/userCtl/login");//用户登錄不進入攔截器的地址

	}

}

7. 管理員管理

數據初始化: 建一張admin表,並填充幾個數據

最全面的SpringBoot教程(一)——SpringBoot概述_攔截器_03

查詢基本的管理員列表

最全面的SpringBoot教程(一)——SpringBoot概述_spring_04

為列表添加查詢條件功能 

前端( 注意: 添加在el-card下面就好了 )

<!-- 查詢條件-->
		<el-row :gutter="20">
			<el-col :span="6">
				<el-input placeholder="賬號" v-model="form.account"></el-input>
			</el-col>
			<el-col :span="6">
				<el-input placeholder="電話" v-model="form.phone"></el-input>
			</el-col>
			<el-col :span="6">
				<el-button type="primary" icon="el-icon-search" @click="findList()" >查詢</el-button>
			</el-col>
		 </el-row>

最全面的SpringBoot教程(一)——SpringBoot概述_#java_05

後端:大部分和基礎查詢的寫法一致,少部分有改變 例如:

將數據封裝在admin對象裏面,同時添加判斷

<resultMap id="adminMap" type="Admin">
    <id column="id" property="id"></id>
    <result column="account" property="account"></result>
    <result column="gender" property="gender"></result>
    <result column="phone" property="phone"></result>
    <result column="type" property="type"></result>
    <result column="oper_time" property="operTime"></result>
        <!--封裝操作人對象數據-->
        <association property="admin" javaType="Admin">
            <result column="oper_account" property="account"></result>
        </association>

</resultMap>

<select id="admins" parameterType="Admin" resultMap="adminMap">
        select
            a.id,
            a.account,
            a.gender,
            a.phone,
            a.type,
            oa.account oper_account,
            a.oper_time

        from
            admin a
                inner join admin oa
                           on a.adminid = oa.id
        where a.type = 1
        <if test="account!=''">
            and a.account=#{account}
        </if>
        <if test="phone!=''">
            and a.phone=#{phone}
        </if>

    </select>

8. 分頁組件

1. 後端使用mybatis分頁組件, 快捷實現後端分頁功能

添加分頁組件依賴

<!-- pagehelper依賴 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>

applicantion.yml中

spring: main: allow-circular-references: true #開始支持spring循環依賴

public PageInfo<Admin> admins(Admin admin){
        //告訴分頁組件,當前頁數,頁數大小,會自動算出開始位置,並且會在sql後面自動添加limit語句
        PageHelper.startPage(admin.getPageNo(), admin.getPageSize());
        ArrayList<Admin> admins = adminDao.admins(admin);
        //會再生成一條sql 查詢總條數    會把與分頁相關的數據封裝到PageInfo中
        PageInfo<Admin> pageInfo = new PageInfo<>(admins);
        return  pageInfo;
    }

2. 前端使用elementui 

  <!-- 分頁組件-->
        <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="form.pageNo"
                :page-sizes="[2,4,6,8]"
                :page-size="form.pageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total">
        </el-pagination>

最全面的SpringBoot教程(一)——SpringBoot概述_#java_06

9. 新增管理員對話框

導入導入--註冊組件--使用組件

添加方法,打開對話框(this.$refs.add.dialogVisible =true;)----調用方法

修改之前的div內容(例如this. form)

10.動態顯示菜單數據

     (1)搭建靜態菜單信息

     順序: controller層---service層---dao層---mapper層

     注意: menu是以ArrayList數組的形式返回

              簡單的數據直接以註解的形式在dao層查詢, 不用到mapper層

     (2)動態查詢菜單信息

      組件格式可以通過elementUI查找 (這裏只展示部分代碼)

最全面的SpringBoot教程(一)——SpringBoot概述_#java_07

   

最全面的SpringBoot教程(一)——SpringBoot概述_#spring boot_08

11.新增並保存管理員

 (1)後端接收

注意: token需要添加註解   @RequestHeader("token")

1.為管理員生成默認密碼並加密密碼

2.從token中獲取當前管理員id

3.保存管理員信息到數據庫的admin表,並拿到管理員id

4.保存給管理員分配的權限數據

最全面的SpringBoot教程(一)——SpringBoot概述_spring_09

12. 刪除管理員

注意: 先刪除關係表, 再刪除管理員

最全面的SpringBoot教程(一)——SpringBoot概述_#spring_10

13.修改管理員

最全面的SpringBoot教程(一)——SpringBoot概述_#java_11

14.添加登錄時密碼加密

修改登錄

最全面的SpringBoot教程(一)——SpringBoot概述_#spring boot_12

修改jwt密碼加密

最全面的SpringBoot教程(一)——SpringBoot概述_#java_13

最全面的SpringBoot教程(一)——SpringBoot概述_#spring boot_14

15. 動態循環查詢菜單

最全面的SpringBoot教程(一)——SpringBoot概述_攔截器_15

注意: 兩個參數以上時傳遞參數需要使用註解

最全面的SpringBoot教程(一)——SpringBoot概述_#java_16