spring boot(学习笔记第二十课) vue + spring boot前后端分离项目练习

spring boot(学习笔记第二十课)

  • vue + spring boot前后端分离项目练习

学习内容:

  • 后端程序构建
  • 前端程序构建

1. 后端程序构建

  1. 前后端分离结构
    前后端就是前端程序和后端程序独立搭建,通过Restful API进行交互,进行松耦合的设计。在这里插入图片描述
  2. 后端程序构建
    在网上看到高手构建的示例程序,边学习边在本地构筑。
    光看不练,永远都是停留在表面学习
    • 高手的示例程序。在此感谢高手(江南一点雨)的分享
      示例程序lenve。一个示例的前后端分离示例。
    • copy该工程到本地,之后看到分别的前端构建和后端构建,这里为了使学习过程单纯一点,基本流用后端的构建。前端进行从头的构建练习。 在这里插入图片描述
    • 理解后端构建module结构。
      maven project -> maven module -> maven project。通过maven module的定义,可以
      • 在父maven project里面,定义子的maven module,作为maven sub project
      • 在各个子maven sub project,可以定义dependency关系。
        在这里插入图片描述
    • 本地构建mysql数据库。
      • 本地数据需要建立一系列的表,DDL在DDL定义。注意由于vhr.sql没有考虑表之间的依赖关系,所有不调整顺序的话,在mysql数据库中执行会报错。
      • 调整好的版本调整版,在mysql中执行,创建必要的表。
        在这里插入图片描述
    • 为数据库的连接用户赋予系统表的select权限。
      GRANT SELECT ON performance_schema.user_variables_by_thread TO 'finlay'@'localhost';
      否则,spring boot执行的时候会报错。
    • disable flyway
      设置spring.flyway.enabled=false在文件application.yml中。
      在这里插入图片描述
    • 重新配置vhr-web这个moduleSecurityConfig.java
      在这里插入图片描述
      @Configuration
      @EnableGlobalMethodSecurity(prePostEnabled=true)
      public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredHrService hrService;@AutowiredCustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;@AutowiredCustomUrlDecisionManager customUrlDecisionManager;@AutowiredAuthenticationDeniedHandler authenticationDeniedHandler;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(hrService);}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/css/**", "/js/**", "/index.html","/img/**", "/fonts/**", "/favicon.ico", "/verifyCode");}@BeanSessionRegistryImpl sessionRegistry() {return new SessionRegistryImpl();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {@Overridepublic <O extends FilterSecurityInterceptor> O postProcess(O object) {object.setAccessDecisionManager(customUrlDecisionManager);object.setSecurityMetadataSource(customFilterInvocationSecurityMetadataSource);return object;}}).and().formLogin().loginPage("/login_p").loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password").failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response,AuthenticationException exception) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");RespBean respBean = null;if(exception instanceof BadCredentialsException|| exception instanceof UsernameNotFoundException){respBean = RespBean.error("用户名或者密码输入错误");}else if(exception instanceof LockedException) {respBean = RespBean.error("用户名被锁定,请联系管理员");}else {respBean = RespBean.error("登陆失败");}respBean.setStatus(401);ObjectMapper om = new ObjectMapper();PrintWriter printWriter = response.getWriter();printWriter.write(om.writeValueAsString(respBean));printWriter.flush();printWriter.close();}}).successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");RespBean respBean = RespBean.ok("登陆成功", HrUtils.getCurrentHr());ObjectMapper om = new ObjectMapper();PrintWriter printWriter = response.getWriter();printWriter.write(om.writeValueAsString(respBean));printWriter.flush();printWriter.close();}}).permitAll().and().csrf().disable().exceptionHandling()//没有认证时,在这里处理结果,不要重定向.accessDeniedHandler(authenticationDeniedHandler);}
      }
      
    • 认证处理如下所示。在这里插入图片描述
    • mailserver中加入必要的依赖。
       <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
      </dependency>
      
    • 启动后端程序需要的redis
      sudo -i
      systemctl restart redis
      
    • 配置redis
      application.yml(spring.redis)
        redis:host: 192.168.12.135database: 0port: 6379password: 123456
      
      在这里插入图片描述
    • 启动后端程序vhr
      注意端口使用8081,之后的前端端口默认8080避免冲突 在这里插入图片描述 * 首先启动postman进行测试,使用admin这个user
      在这里插入图片描述

2. 前端程序构建

  1. 构建前端工程
    前端采用Vue进行构建。
    • 执行npm进行搭建
      执行以下命令,建立vue工程
      npm install -g vue-cli
      vue init webpack vuehr
      cd vuehr
      npm run dev
      
      默认是8080端口 注意,后端工程的端口必须和前端工程的端口分开,这里后端采用的是8081
  2. 构建前端的认证画面和路由
    • 前端使用Element(画面表示)和AxiosAjax后端交互)
      npm i element-ui -S
      npm i axios -S
      
    • 修改axios的默认版数
      默认的axios版数,在之后的练习中会编译错误,所以改修成"axios": "^0.19.0"
      修改
      "dependencies": {"axios": "^0.19.0",},
      ```![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c95f0d23e2714fad9d588a14b85e5b24.png)
      
    • 导入必要的代码
      • 在main.js中加入Element
        import ElementUI from 'element-ui'
        import 'element-ui/lib/theme-chalk/index.css'
        Vue.use(ElementUI)
        
      • 在项目中加入/utils/api
        从前面clone下来的代码中,将utils/api这个代码,都copy到新的代码段中。在这里插入图片描述
        • 在main.js中加入/utils/api
        import { getRequest, postRequest, deleteRequest, putRequest } from './utils/api'Vue.prototype.getRequest = getRequest
        Vue.prototype.postRequest = postRequest
        Vue.prototype.deleteRequest = deleteRequest
        Vue.prototype.putRequest = putRequest
        
        • 开发login页面
        <template><el-form :rules="rules" class="login-container" label-position="left"label-width="0px" v-loading="loading"><h3 class="login_title">系统登陆</h3><el-form-item prop="account"><el-input type="text" v-model="loginForm.username"auto-complete="off" placeholder="账号"></el-input></el-form-item><el-form-item prop="checkPass"><el-input type="password" v-model="loginForm.password"auto-complete="off" placeholder="密码"></el-input></el-form-item><el-checkbox class="login_remember" v-model="checked"label-position="left">记住密码</el-checkbox><el-form-item style="width: 100%"><el-button type="primary" style="width: 100%"@click="submitClick">登录</el-button></el-form-item></el-form>
        </template>
        <script>
        export default{data () {return {rules: {account: [{required: true, message: '请输入用户名', trigger: 'blur'}],checkPass: [{required: true, message: '请输入密码', trigger: 'blur'}]},checked: true,loginForm: {username: 'admin',password: '123'},loading: false}},methods: {submitClick: function () {var _this = thisthis.loading = truethis.postRequest("/login?username=" + this.loginForm.username +"&password=" + this.loginForm.password).then((resp) => {_this.loading = falseif (resp && resp.status === 200) {var data = resp.data//_this.$store.commit('login', data.obj)var path = _this.$route.query.redirect_this.$router.replace({path: path === '/' || path === undefined ? '/home' : path})}})}}
        }
        </script>
        <style>.login-container {border-radius: 15px;background-clip: padding-box;margin: 150px auto;width: 350px;padding: 35px 35px 15px 35px;background: #fff;border: 1px solid #cac6c6;box-shadow: 0 0 25px #cac6c6;}.login_title {margin: 0px auto 40px auto;text-align: center;color: #505458;}.login_remember {margin: 0px 0px 35px 0px;text-align: left;}
        </style>
        
        • 修改路由表route/index.js
        import Vue from 'vue'
        import Router from 'vue-router'
        import HelloWorld from '@/components/HelloWorld'
        import Login from '@/components/Login'Vue.use(Router)export default new Router({routes: [{path: '/',name: 'Login',component: Login,hidden: true}, {path: '/home',name: '主页',component: HelloWorld}]
        })
        
        • 修改主程序入口src/App.vue
        <template><div id="app"><router-view/></div>
        </template><script>
        export default {name: 'App'
        }
        </script><style>
        #app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
        }
        </style>
        
        • 配置前端转发config/index.js
          前端8080和后端8081在不同的端口,这里必须要在前端设置后端的端口。
        proxyTable: {'/': {target: 'http://localhost:8081',changeOrigin: true,pathRewrite: {'^/': ''}},'/ws/*': {target: 'ws://127.0.0.1:8081',ws: true}},
        
    • 启动前端程序
      shell npm run dev
      在这里插入图片描述
      • 输入和数据库hr表里面的用户名和密码
        登录成功,进入到home画面。在这里插入图片描述hr表的用户名和密码,登录系统。
    • 前端Vue工程的结构

      接下来对系统管理的菜单页面进行练习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542151.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

WebGL入门(一)绘制一个点

源码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><scr…

【开源免费】基于SpringBoot+Vue.JS教师工作量管理系统(JAVA毕业设计)

本文项目编号 T 043 &#xff0c;文末自助获取源码 \color{red}{T043&#xff0c;文末自助获取源码} T043&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

【C++】内联函数(inline function)详解

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、前言 语法: 在函数定义前加上关键字 inli…

学不会最短路问题?看这篇就够了

数据结构入门学习&#xff08;全是干货&#xff09;——图论问题之最短路径 1 最短路径问题概述 最短路径问题的定义 在一个网络&#xff08;图&#xff09;中&#xff0c;求解两个顶点之间所有路径中边的权值之和最小的路径。这条路径称为最短路径。 源点(Source)&#xff…

ClickHouse-Kafka Engine 正确的使用方式

Kafka 是大数据领域非常流行的一款分布式消息中间件&#xff0c;是实时计算中必不可少的一环&#xff0c;同时一款 OLAP 系统能否对接 Kafka 也算是考量是否具备流批一体的衡量指标之一。ClickHouse 的 Kafka 表引擎能够直接与 Kafka 系统对接&#xff0c;进而订阅 Kafka 中的 …

openEuler系统安装内网穿透工具实现其他设备公网环境远程ssh连接

目录 前言 1. 本地SSH连接测试 2. openEuler安装Cpolar 3. 配置 SSH公网地址 4. 公网远程SSH连接 5. 固定连接SSH公网地址 6. SSH固定地址连接测试 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊openEuler系统安装内网穿透工具实现其他…

深度学习之微积分预备知识点(2)

极限&#xff08;Limit&#xff09; 定义&#xff1a;表示某一点处函数趋近于某一特定值的过程&#xff0c;一般记为 极限是一种变化状态的描述&#xff0c;核心思想是无限靠近而永远不能到达 公式&#xff1a; 表示 x 趋向 a 时 f(x) 的极限。 知识点口诀解释极限的存在左…

语言RPA流程组件介绍--获取网页信息

&#x1f6a9;【组件功能】&#xff1a;获取浏览器中显示网页的网页标题、源代码、网址、编码等信息 配置预览 配置说明 获取 网页源代码/标题/网址/编码 iframe 支持T或# 若获取的信息是框架iframe中的信息&#xff0c;需要手动填写框架名称&#xff0c;框架使用方法:框架…

文档图像恢复

文档图像恢复是指通过技术手段对损坏或质量不佳的文档图像进行修复&#xff0c;以提高其可读性和可用性。这种修复可以包括去除图像的噪声、畸变、阴影、模糊等多种问题&#xff0c;使文档图像更清晰、易于阅读。 文档图像恢复通常使用各种图像处理技术&#xff0c;包括但不限…

一个基于Vue3 + Arco Design + Vite3 + Pinia开箱即用的高质量中后台管理系统(附源码)

前言 随着业务的发展与复杂性的增加&#xff0c;现有的中后台管理系统面临着越来越多的挑战&#xff0c;如开发效率低下、系统性能瓶颈、项目扩展性差等问题。这些问题不仅影响了开发者的日常工作&#xff0c;还可能成为项目长期发展的障碍。那么&#xff0c;是否有一款软件能…

LabVIEW提高开发效率技巧----利用第三方库和工具

LabVIEW开发不仅依赖于自身强大的图形化编程能力&#xff0c;还得益于其庞大的用户社区和丰富的第三方库。这些工具和库能够帮助开发者快速解决问题&#xff0c;提升开发效率&#xff0c;避免从头开始编写代码。 1. LabVIEW工具网络&#xff08;NI Tools Network&#xff09; …

一些硬件知识(二十二)

搅拌机的转子是裸露在外面的&#xff0c;因此有一个安全开关&#xff0c;当上杯放上去后会按压安全开关&#xff0c;这样可以启动转子&#xff0c;否则是无法启动转子的&#xff0c;所以有些设备不通电或者转子不动是因为安全开关损坏&#xff1a; 、如下图&#xff0c;装上杯子…

详细分析Spring的动态代理机制

文章目录 1. JDK动态代理和CGLIB动态代理的区别1.1 适用范围1.2 生成的代理类1.3 调用方式 2. 问题引入3. 创建工程验证 Spring 默认采用的动态代理机制3.1 引入 Maven 依赖3.2 UserController.java3.3 UserService.java3.4 UserServiceImpl.java&#xff08;save方法添加了Tra…

JAVA开源项目 房屋租赁系统 计算机毕业设计

本文项目编号 T 041 &#xff0c;文末自助获取源码 \color{red}{T041&#xff0c;文末自助获取源码} T041&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

Linux中使用cp命令的 -f 选项,但还是提醒覆盖的问题

问题&#xff1a; linux 在执行cp的命令的时候&#xff0c;就算是执行 cp -f 也还是会提醒是否要进行替换。 问题原因&#xff1a; 查看别名&#xff0c;alias命令&#xff0c;看到cp的别名为cp -i&#xff0c;那就是说cp本身就是自带覆盖提醒&#xff0c;就算我们加上-f 的…

CentOS中使用DockerCompose方式部署带postgis的postgresql(附kartoza/docker-postgis镜像下载)

场景 CentOS中使用Docker部署带postgis的postgresql&#xff1a; CentOS中使用Docker部署带postgis的postgresql_centos postgis插件在容器中如何安装-CSDN博客 上面使用Docker搜索和拉取kartoza/postgis时并没有任何限制。 当下如果不能科学上网时&#xff0c;大部分镜像源…

JavaEE: 创造无限连接——网络编程中的套接字

文章目录 Socket套接字TCP和UDP的区别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP api的使用UDPDatagramSocketDatagramPacketInetSocketAddress练习 TCPServerSocketSocket练习 Socket套接字 Socket是计算机网络中的一种通信机制&#xff0…

《机器人SLAM导航核心技术与实战》第1季:第9章_视觉SLAM系统

视频讲解 【第1季】9.第9章_视觉SLAM系统-视频讲解 【第1季】9.1.第9章_视觉SLAM系统_ORB-SLAM2算法&#xff08;上&#xff09;-视频讲解 【第1季】9.1.第9章_视觉SLAM系统_ORB-SLAM2算法&#xff08;下&#xff09;-视频讲解 【第1季】9.2.第9章_视觉SLAM系统_LSD-SLAM算法…

项目集成 与封装

1.element-plus 硅谷甄选运营平台,UI组件库采用的element-plus&#xff0c;因此需要集成element-plus插件&#xff01;&#xff01;&#xff01; 官网地址:https://element-plus.gitee.io/zh-CN/ 由于是后台管理系统 所以我们全部引入 pnpm install element-plus import {…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…