老规矩,冒个泡,不知道为啥最近也是懒,一点点动力都没有了,可能是由于几个星星导致的精神萎靡吧,也可能是财富岛太迷人了。那么今天也是带来第二个part,也就是如何快速基于renren-fast 完成后台管理项目的构建。那么今天的内容呢,有一下两点,第一是如何打通分布式微服务与前端之间的交互,第二个就是如何完成后台页面的搭建。当然最主要的就是如何完成后台的页面搭建嘛,第一个谁不会呀,无非是跨越嘛。今天的内容很简单也不多,但是混个期末作业绰绰有余。
首先是咱们的环境,这个环境包括了我一些组件的版本,然后就是我所使用的工具。
SpringBoot:2.3.2.RELEASE
SpringCloud:Hoxton.SR9
SpringCloudAlibaba:2.2.6.RELEASE
nacos:1.14
使用的开源项目是:
renren-fast
renren-fast-vue
renren-generation
这个renren-generation前面的博文有说道:
懒人方案–半天搞定一个SpringBoot单体项目
不过这里由于我们这边是分布式的一个项目,所以我们需要把renren-fast注册到我们的nacos里面,最新的renren-fast的版本呢和我们上面给的环境版本是不一样的,所以需要降低版本。不过这个是后话了,待会再说,现在先把对应的环境搭建起来。
我们先把对应的前端代码搞到手,打开项目地址,上次给的是github的一个玩意,现在发现在gitee也有,毕竟也是国人发起的项目嘛。其实你也可以直接试一试人家的renren-security的,当然有时间再体验了,都一样的。
下载解压,然后构建一下依赖,这样就把前端的项目构建好了,构建好之后大概是这样样子的。
不过验证码这里是不会有的你得把后端构建好。因为这个验证码和我们先前做的不一样还是后端给的,以前为我都是尽可能把一些东西给前端做的,验证码也是前端的,当然防君子不防小人了哈。不过也没啥,设置黑名单嘛。
后端的话也是类似的,首先下载代码。
idea打开,等待加载好就可以了。
然后打开你的数据库。
执行一下对应的sql语句,比如我是mysql我就执行里面的sql。
之后在配置文件里面配置一下数据库就好了
如果你的端口有冲突的话,换了端口那么需要在前端改一下地址。
这里主要默认地址是 127.0.0.1:8000/renren-fast 我这个是改了网关的哈。
之后是这样的:
到此我们就搭建好了。但是还不够,由于我们是 分布式的玩意,我们是有nacos注册中心的,之后我们是需要和我们的微服务之间调动的。
所以我们这边要做改动,首先第一点就是改依赖,现在官方给的配置是2.6.6的SpringBoot版本,然后也没有SpringCloud,所以我们要改动。
它这里的配置我改成了这样:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.2.RELEASEversion>
<relativePath />
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<mybatisplus.version>3.3.1mybatisplus.version>
<mysql.version>8.0.28mysql.version>
<mssql.version>4.0mssql.version>
<oracle.version>11.2.0.3oracle.version>
<druid.version>1.1.13druid.version>
<quartz.version>2.3.0quartz.version>
<commons.lang.version>2.6commons.lang.version>
<commons.fileupload.version>1.2.2commons.fileupload.version>
<commons.io.version>2.5commons.io.version>
<commons.codec.version>1.10commons.codec.version>
<commons.configuration.version>1.10commons.configuration.version>
<shiro.version>1.9.0shiro.version>
<jwt.version>0.7.0jwt.version>
<kaptcha.version>0.0.9kaptcha.version>
<qiniu.version>7.2.23qiniu.version>
<aliyun.oss.version>2.8.3aliyun.oss.version>
<qcloud.cos.version>4.4qcloud.cos.version>
<swagger.version>2.7.0swagger.version>
<joda.time.version>2.9.9joda.time.version>
<gson.version>2.8.5gson.version>
<fastjson.version>1.2.79fastjson.version>
<hutool.version>4.1.1hutool.version>
<lombok.version>1.18.4lombok.version>
<service-path>/work/renrenservice-path>
<pack-name>${project.artifactId}-${project.version}.jarpack-name>
<remote-addr>192.168.1.10:22remote-addr>
<remote-username>rootremote-username>
<remote-passwd>123456remote-passwd>
properties>
<dependencies>
<dependency>
<groupId>com.huterox.whitehole.commongroupId>
<artifactId>whiteholo-commonartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatisplus.version}version>
<exclusions>
<exclusion>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>com.oraclegroupId>
<artifactId>ojdbc6artifactId>
<version>${oracle.version}version>
dependency>
<dependency>
<groupId>com.microsoft.sqlservergroupId>
<artifactId>sqljdbc4artifactId>
<version>${mssql.version}version>
dependency>
<dependency>
<groupId>org.postgresqlgroupId>
<artifactId>postgresqlartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>${quartz.version}version>
<exclusions>
<exclusion>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>${commons.lang.version}version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>${commons.fileupload.version}version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>${commons.io.version}version>
dependency>
<dependency>
<groupId>commons-codecgroupId>
<artifactId>commons-codecartifactId>
<version>${commons.codec.version}version>
dependency>
<dependency>
<groupId>commons-configurationgroupId>
<artifactId>commons-configurationartifactId>
<version>${commons.configuration.version}version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>${shiro.version}version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>${shiro.version}version>
dependency>
<dependency>
<groupId>io.jsonwebtokengroupId>
<artifactId>jjwtartifactId>
<version>${jwt.version}version>
dependency>
<dependency>
<groupId>com.github.axetgroupId>
<artifactId>kaptchaartifactId>
<version>${kaptcha.version}version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>com.qiniugroupId>
<artifactId>qiniu-java-sdkartifactId>
<version>${qiniu.version}version>
dependency>
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>${aliyun.oss.version}version>
dependency>
<dependency>
<groupId>com.qcloudgroupId>
<artifactId>cos_apiartifactId>
<version>${qcloud.cos.version}version>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>joda-timegroupId>
<artifactId>joda-timeartifactId>
<version>${joda.time.version}version>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>${gson.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>${hutool.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
<build>
<finalName>${project.artifactId}finalName>
<extensions>
<extension>
<groupId>org.apache.maven.wagongroupId>
<artifactId>wagon-sshartifactId>
<version>2.8version>
extension>
extensions>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<fork>truefork>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<configuration>
<skipTests>trueskipTests>
configuration>
plugin>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>wagon-maven-pluginartifactId>
<version>1.0version>
<configuration>
<fromFile>target/${pack-name}fromFile>
<url>url>
<commands>
<command>kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'`command>
<command> ${service-path}/renren.log 2>&1 & ]]>command>
<command>command>
<command>command>
commands>
<displayCommandOutputs>truedisplayCommandOutputs>
configuration>
plugin>
<plugin>
<groupId>com.spotifygroupId>
<artifactId>docker-maven-pluginartifactId>
<version>0.4.13version>
<configuration>
<imageName>renren/fastimageName>
<dockerDirectory>${project.basedir}dockerDirectory>
<resources>
<resource>
<targetPath>/targetPath>
<directory>${project.build.directory}directory>
<include>${project.build.finalName}.jarinclude>
resource>
resources>
configuration>
plugin>
plugins>
build>
<repositories>
<repository>
<id>publicid>
<name>aliyun nexusname>
<url>https://maven.aliyun.com/repository/public/url>
<releases>
<enabled>trueenabled>
releases>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>publicid>
<name>aliyun nexusname>
<url>https://maven.aliyun.com/repository/public/url>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>falseenabled>
snapshots>
pluginRepository>
pluginRepositories>
这里的那个common依赖其实是上次的那篇博客里面的可以去看看,这个是我的需求,你自己看着提取出来。
原因有两个:
首先是老规矩嘛,由于我导入了common包,这个包里面我是已经有nacos的服务注册发现对应的依赖的,所以我就不用导入了。
然后重启服务就好了。
现在我们要做的是前后端分离,而且需要统一转发在前端。这个跨越的话,咱们以前也做过在前端也可以做,但是现在的话试一试在后端玩玩。不过不管是哪一个端咱们都需要统一api接口。
所以我们这里也是规定,所有的请求都需要带上api才转发,当然这个也是网关配置的一些需要嘛。
所以我这样做如下配置:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
service: gateway
gateway:
discovery:
locator:
enabled: true
routes:
#这里先做一个基本的服务转发
- id: activiy8000
uri: lb://activiy
predicates:
- Path=/api/activiy/**
filters:
- RewritePath=/api/activiy/(?>.*),/$\{segment}
- id: blog8050
uri: lb://blog
predicates:
- Path=/api/blog/**
filters:
- RewritePath=/api/blog/(?>.*),/$\{segment}
- id: community8100
uri: lb://community
predicates:
- Path=/api/community/**
filters:
- RewritePath=/api/community/(?>.*),/$\{segment}
- id: hole8150
uri: lb://hole
predicates:
- Path=/api/hole/**
filters:
- RewritePath=/api/hole/(?>.*),/$\{segment}
- id: quiz8200
uri: lb://quiz
predicates:
- Path=/api/quiz/**
filters:
- RewritePath=/api/quiz/(?>.*),/$\{segment}
- id: user8250
uri: lb://user
predicates:
- Path=/api/user/**
filters:
- RewritePath=/api/user/(?>.*),/$\{segment}
- id: admin_route
uri: lb://renren-fast # 网关负载均衡的发送到renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?>.*),/renren-fast/$\{segment} #实现路径重写
这里有6个微服务嘛,然后转发。
这部分的跨越咱们就在网关做了,记住注释掉renren-fast里面的跨越。
@Configuration
public class WhiteHoleCorsConfig {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
现在我们把基本的玩意都准备好了,在开始之前我们在做一个个性化处理。
ok,我们完成了基本的个性化处理,那么接下来我们来点实战。
这里我已经做好了两个模块,现在我再为文章管理做一个模块。
首先说明一下,咱们的这个代码也是通过renren-generation 生成的,这个在咱们之前有说过。在这篇博文:
懒人方案–半天搞定一个SpringBoot单体项目
在咱们的代码是生成了代码和vue文件已经sql的,然后我当时是暂时放在了这个地方:
第一个是sql语句,这个是用来生成菜单的,但是这个的话一般我们可能用不上,当然也可以直接用,那么是干嘛的呢,我们待会说。
然后就创建好了,那么我们来说一下刚刚的sql语句有什么用,我们打开我们的后台数据库。
你会发现这个菜单其实是写在了数据库里面的,是动态渲染出来的,所以那个sql就是做这个事情的,把菜单写在了表里面,但是为什么不直接用那个sql要自己手动创建呢,很简单,我们看一下那个sql语句你就明白了。
它生成的一些菜单名字是按照字段来的。这个肯定是不能直接用的。
我们在生成一下菜单,这里注意我填写的菜单路由。
然后刷新一下,页面会显示,然后数据库里面也会有对应的记录。
之后我们创建页面,我们刚刚填写的路由是blog/blog 所以我们找到/views/modules然后创建blog文件夹blog.vue。
这个vue里面不用填写name,也就是这样
<template>
<div>
我是博客查看
div>
template>
<script>
export default {
}
script>
<style scoped>
style>
这个时候你以为要自己写页面了嘛?有些确实是的,不过还记得我们先前生成的vue文件嘛。
每次,我们把这两个文件copy过来:
记住要对得到名字,也就是你的blog.vue的名字要对上,另一个弹窗的就无所谓了。
然后咱们有两个点要做,第一个是列表的名字,然后是对应的后端请求地址。
label的修改,没有注释就没有。
之后是请求地址修改,我这里的话按照网关的配置需要加上/blog前缀
这里的话,两个文件都要改一下。
之后把服务打开,然后刷新页面就是这样的,咱们这块还没有数据:
之后是后端的搜索实现。
所以我们回到对应的Blog对应的Service在后端。
所以我们只需要拿到key然后判断一下是不是空,如果不是的话就进行复杂查询就好了。
@Override
public PageUtils queryPage(Map<String, Object> params) {
String key = (String) params.get("key");
IPage<BlogEntity> page_params = new Query<BlogEntity>().getPage(params);
QueryWrapper<BlogEntity> blogEntityQueryWrapper = new QueryWrapper<>();
if(key!=null){
blogEntityQueryWrapper.like("userid",key).or().
like("blogid",key).or().
like("user_nickname",key).or().
like("blog_title",key);
}
IPage<BlogEntity> page = this.page(
page_params,
blogEntityQueryWrapper
);
return new PageUtils(page);
}
这里按照你的业务来哈。
然后我们验证一下,由于我这边是没有数据的,所以我用用户的这个模块来演示一下。
然后后端输出了sql日志:
当然我这里是配置了一下,你要看日志自己配置一下。