[ SpringBoot ]

📅 2026/8/18 17:21:58
[ SpringBoot ]
一. 概述1.为什么使用SpringBootSpring虽然有很多优点, 但是Spring框架的搭建非常麻烦1. 配置麻烦,而且很多都是模版化的配置(固定的)2. 需要添加很多依赖, 例如web层依赖jackson组件,需要我们自己添加, 版本也可能不匹配基于以上两点,spring官方推出了SpringBoot .目的不是代替spring ,而是简化spring应用的初始搭建2. 搭建springboot 自带Tomcat 不需要再勾选JavaEE 直接新建new project ---- java ----Maven(1)pom.xml配置添加父工程 (不放在dependencies里面)!--依赖的父级工程--parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.6.6/versionrelativePath//parent添加依赖!--添加基本的springweb依赖--dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency/dependencies添加打包插件(不放在dependencies里面)!--打包插件--buildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversion2.6.6/version/plugin/plugins/build(2)创建包news 并添加启动类NewsApplicationpackage 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); } }(3)创建web层 service层 dao层 model层 config层(配置层) interceptor层(拦截器)在resources下创建applicantion.yml文件(配置值的文件)3. 配置值文件application.properties属性文件格式,内容为键值对 server.port8080properties 格式比较简单,没有什么难度,在此我们以第二种 yaml 格式为例.application.yml(重要)yml 是 YAMLYAML Ain’t Markup Language语言的文件以数据为中心.1.yaml 基本语法语法结构key空格 value; 注意: 空格不能省略2. 以空格的缩进来控制层级关系只要是左边对齐的一列数据都是同一个层级的;3. 字面量直接写在后面就可以字符串默认不用加上双引号或者单引号4. 以#作为注释符号.5. 使用Value 注解标签将配置文件中的内容映射到类中的属性. Value(${user.name})4. Spring数据访问管理数据源配置为了连接数据库需要引入 jdbc 支持在 pom.xml 中添加依赖 (记得添加 mysql 驱动依赖)dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-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?serverTimezoneAsia/Shanghaiurl: jdbc:mysql://192.168.244.128:3306/newsdb?serverTimezoneAsia/Shanghaiusername: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource #指定数据库连接管理类initialSize: 5maxActive: 20添加阿里数据源依赖!-- 阿里数据源 --dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.10/version/dependency复制一个前端项目, 删除里面不需要的文件和配置5. 解决跨域问题出现此错误需要解决跨域问题添加配置类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); //设置头部信息 MapString,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); //设置头部信息 MapString,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组件--dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion3.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;charsetutf-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表,并填充几个数据查询基本的管理员列表为列表添加查询条件功能前端( 注意: 添加在el-card下面就好了 )!-- 查询条件-- el-row :gutter20 el-col :span6 el-input placeholder账号 v-modelform.account/el-input /el-col el-col :span6 el-input placeholder电话 v-modelform.phone/el-input /el-col el-col :span6 el-button typeprimary iconel-icon-search clickfindList() 查询/el-button /el-col /el-row后端:大部分和基础查询的写法一致,少部分有改变 例如:将数据封装在admin对象里面,同时添加判断resultMap idadminMap typeAdmin id columnid propertyid/id result columnaccount propertyaccount/result result columngender propertygender/result result columnphone propertyphone/result result columntype propertytype/result result columnoper_time propertyoperTime/result !--封装操作人对象数据-- association propertyadmin javaTypeAdmin result columnoper_account propertyaccount/result /association /resultMap select idadmins parameterTypeAdmin resultMapadminMap 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 testaccount! and a.account#{account} /if if testphone! and a.phone#{phone} /if /select8. 分页组件1. 后端使用mybatis分页组件, 快捷实现后端分页功能添加分页组件依赖!-- pagehelper依赖 --dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactIdversion1.2.5/version/dependencyapplicantion.yml中spring: main: allow-circular-references: true #开始支持spring循环依赖public PageInfoAdmin admins(Admin admin){ //告诉分页组件,当前页数,页数大小,会自动算出开始位置,并且会在sql后面自动添加limit语句 PageHelper.startPage(admin.getPageNo(), admin.getPageSize()); ArrayListAdmin admins adminDao.admins(admin); //会再生成一条sql 查询总条数 会把与分页相关的数据封装到PageInfo中 PageInfoAdmin pageInfo new PageInfo(admins); return pageInfo; }2. 前端使用elementui!-- 分页组件--el-paginationsize-changehandleSizeChangecurrent-changehandleCurrentChange:current-pageform.pageNo:page-sizes[2,4,6,8]:page-sizeform.pageSizelayouttotal, sizes, prev, pager, next, jumper:totaltotal/el-pagination9. 新增管理员对话框导入导入--注册组件--使用组件添加方法,打开对话框(this.$refs.add.dialogVisible true;)----调用方法修改之前的div内容(例如this. form)10.动态显示菜单数据(1)搭建静态菜单信息顺序: controller层---service层---dao层---mapper层注意: menu是以ArrayList数组的形式返回简单的数据直接以注解的形式在dao层查询, 不用到mapper层(2)动态查询菜单信息组件格式可以通过elementUI查找 (这里只展示部分代码)11.新增并保存管理员(1)后端接收注意: token需要添加注解 RequestHeader(token)1.为管理员生成默认密码并加密密码2.从token中获取当前管理员id3.保存管理员信息到数据库的admin表,并拿到管理员id4.保存给管理员分配的权限数据12. 删除管理员注意: 先删除关系表, 再删除管理员13.修改管理员14.添加登录时密码加密修改登录修改jwt密码加密15. 动态循环查询菜单注意: 两个参数以上时传递参数需要使用注解