如果你追求一个局部的更好甚至完美,你有可能花费巨大的资源和时间;
从总体上看,这往往意味着总体的浪费和失败,这是传说中的“打赢了战役打输了战争”。

系列文章目录

  1. 项目搭建
  2. App登录及网关
  3. App文章
  4. 自媒体平台(博主后台)
  5. 自媒体文章审核
  6. 延迟任务
  7. kafka及文章上下架
  8. App端文章搜索
  9. 后台系统管理
  10. Long类型精度丢失问题
  11. 定时计算热点文章(xxl-Job)
  12. 热点文章-实时计算(kafkaStream)
  13. 项目部署_持续集成(Jenkins)

文章目录

  • 系列文章目录
  • 一、App登录
    • 1. 需求分析
    • 2. 表结构分析
      • ⑴. 导入数据库
      • ⑵. 库表
      • ⑶. 用户表(登录)
      • ⑷. 实体类
    • 3. 手动加密(md5+随机字符串)
    • 4. 运营端微服务搭建
      • ⑴. 创建模块
      • ⑵. 引导类
      • ⑶. 微服务配置文件
      • ⑷. 日志配置文件
      • ⑸. Nacos配置文件
      • ⑹. 微服务标准包结构
    • 5. 接口定义
      • ⑴. 接口返回类分析
        • ①. HttpCode枚举
        • ②. 通用的结果返回类
        • ③. 上面的返回类测试
        • ④. 分页返回类
      • ⑵. 实体类
      • ⑶. Controller
      • ⑷. Mapper
      • ⑸. service
      • ⑹. 实现类Impl
      • ⑺. Controller
  • 二、接口测试工具
    • 1. Postman
    • 2. Swagger
      • ⑴. 配置
        • ①. 引入依赖
        • ②. 配置类
        • ③. 自动配置
      • ⑵. 注解
        • ①. 常用注解
        • ②. 接口注解
        • ③. 参数注解
        • ④. 在线API文档
    • 3. Knife4j
      • ⑴. 配置
        • ①. 引入依赖
        • ②. 配置类
        • ③. 自动配置
      • ⑵. 文档(可下载离线文档)
  • 三、App网关
    • 1. gateway网关微服务
      • ⑴. 服务工程结构
      • ⑵. 配置
        • ①. 导入依赖
        • ②. 引导类
        • ③. 配置文件
        • ④. nacos配置
      • ⑶. 测试
    • 2. 认证过滤器
      • ⑴. 思路分析
      • ⑵. 全局过滤器
      • ⑶. 断点调试
  • 四、App前端项目集成
    • 1. nginx包
    • 2. 前端项目
    • 3. 配置nginx.conf文件1
    • 4. 配置nginx.conf文件2
    • 5. 重新加载nginx
    • 6. 运行测试

一、App登录

1. 需求分析

  • 登录: 登录后的用户权限较大,可以查看,也可以操作(点赞,关注,评论)
  • 不登录,先看看: 游客只有查看的权限

2. 表结构分析

⑴. 导入数据库

sql文件链接:https://pan.baidu.com/s/11ITsQZQkR0Yl20lT10omwQ?pwd=abcd

⑵. 库表

关于app端用户相关的内容较多,可以单独设置一个库leadnews_user

表名称 说明
ap_user APP用户信息表
ap_user_fan APP用户粉丝信息表
ap_user_follow APP用户关注信息表
ap_user_realname APP实名认证信息表

⑶. 用户表(登录)

登录需要用到的是 ap_user 表,表结构如下:

DDL文件:

CREATE TABLE `ap_user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`salt` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码、通信等加密盐',`name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名',`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码,md5加密',`phone` varchar(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像',`sex` tinyint(1) unsigned DEFAULT NULL COMMENT '0 男\r\n            1 女\r\n            2 未知',`is_certification` tinyint(1) unsigned DEFAULT NULL COMMENT '0 未\r\n            1 是',`is_identity_authentication` tinyint(1) DEFAULT NULL COMMENT '是否身份认证',`status` tinyint(1) unsigned DEFAULT NULL COMMENT '0正常\r\n            1锁定',`flag` tinyint(1) unsigned DEFAULT NULL COMMENT '0 普通用户\r\n            1 自媒体人\r\n            2 大V',`created_time` datetime DEFAULT NULL COMMENT '注册时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP用户信息表';

tinyint类型: 占1个字节,不指定unsigned(非负数),值范围(-128,127),指定了unsigned,值范围(0,255)
tinyint 通常表示小范围的数值,或者表示true或false,通常值为0表示false,值为1表示true

⑷. 实体类

新建 src/main/java/com/heima/model/user/pojos/ApUser.java 文件(app_user表对应的实体类):

/*** <p>* APP用户信息表* </p>** @author itheima*/
@Data
@TableName("ap_user")
public class ApUser implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** 密码、通信等加密盐*/@TableField("salt")private String salt;/*** 用户名*/@TableField("name")private String name;/*** 密码,md5加密*/@TableField("password")private String password;/*** 手机号*/@TableField("phone")private String phone;/*** 头像*/@TableField("image")private String image;/*** 0 男1 女2 未知*/@TableField("sex")private Boolean sex;/*** 0 未1 是*/@TableField("is_certification")private Boolean certification;/*** 是否身份认证*/@TableField("is_identity_authentication")private Boolean identityAuthentication;/*** 0正常1锁定*/@TableField("status")private Boolean status;/*** 0 普通用户1 自媒体人2 大V*/@TableField("flag")private Short flag;/*** 注册时间*/@TableField("created_time")private Date createdTime;}

3. 手动加密(md5+随机字符串)

md5是不可逆加密,md5相同的密码每次加密都一样,不太安全。在md5的基础上手动加盐(salt)处理

注册(生成盐)

登录(使用盐来配合验证)

4. 运营端微服务搭建

⑴. 创建模块

⑵. 引导类

新建 src/main/java/com/heima/user/UserApplication.java 文件:

@SpringBootApplication
@EnableDiscoveryClient // 集成当前的注册中心
@MapperScan("com.heima.user.mapper") // 集成myBatisPlus 扫描mapper
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);}
}

⑶. 微服务配置文件

新建 heima-leadnews-service/heima-leadnews-user/src/main/resources/bootstrap.yml 文件:

server:port: 51801
spring:application:name: leadnews-usercloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml

⑷. 日志配置文件

新建 heima-leadnews-service/heima-leadnews-user/src/main/resources/logback.xml 文件:

<?xml version="1.0" encoding="UTF-8"?><configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="e:/logs"/><!-- Console 输出设置 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern><charset>utf8</charset></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><fileNamePattern>${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步输出 --><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILE"/></appender><logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"><appender-ref ref="CONSOLE"/></logger><logger name="org.springframework.boot" level="debug"/><root level="info"><!--<appender-ref ref="ASYNC"/>--><appender-ref ref="FILE"/><appender-ref ref="CONSOLE"/></root>
</configuration>

⑸. Nacos配置文件

spring:redis:host: 192.168.200.130password: leadnewsport: 6379datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: 123456
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.user.pojos

⑹. 微服务标准包结构

5. 接口定义

⑴. 接口返回类分析

①. HttpCode枚举

查看 com/heima/model/common/enums/AppHttpCodeEnum.java 文件:

public enum AppHttpCodeEnum {// 成功段固定为200SUCCESS(200,"操作成功"),// 登录段1~50NEED_LOGIN(1,"需要登录后操作"),LOGIN_PASSWORD_ERROR(2,"密码错误"),// TOKEN50~100TOKEN_INVALID(50,"无效的TOKEN"),TOKEN_EXPIRE(51,"TOKEN已过期"),TOKEN_REQUIRE(52,"TOKEN是必须的"),// SIGN验签 100~120SIGN_INVALID(100,"无效的SIGN"),SIG_TIMEOUT(101,"SIGN已过期"),// 参数错误 500~1000PARAM_REQUIRE(500,"缺少参数"),PARAM_INVALID(501,"无效参数"),PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),SERVER_ERROR(503,"服务器内部错误"),// 数据错误 1000~2000DATA_EXIST(1000,"数据已经存在"),AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),DATA_NOT_EXIST(1002,"数据不存在"),// 数据错误 3000~3500NO_OPERATOR_AUTH(3000,"无权限操作"),NEED_ADMIND(3001,"需要管理员权限");int code;String errorMessage;AppHttpCodeEnum(int code, String errorMessage){this.code = code;this.errorMessage = errorMessage;}public int getCode() {return code;}public String getErrorMessage() {return errorMessage;}
}

②. 通用的结果返回类

查看 com/heima/model/common/dtos/PageResponseResult.java 文件:

/*** 通用的结果返回类* @param <T>*/
public class ResponseResult<T> implements Serializable {private String host;private Integer code;private String errorMessage;private T data;public ResponseResult() {this.code = 200;}public ResponseResult(Integer code, T data) {this.code = code;this.data = data;}public ResponseResult(Integer code, String msg, T data) {this.code = code;this.errorMessage = msg;this.data = data;}public ResponseResult(Integer code, String msg) {this.code = code;this.errorMessage = msg;}public static ResponseResult errorResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.error(code, msg);}public static ResponseResult okResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.ok(code, null, msg);}public static ResponseResult okResult(Object data) {ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getErrorMessage());if(data!=null) {result.setData(data);}return result;}public static ResponseResult errorResult(AppHttpCodeEnum enums){return setAppHttpCodeEnum(enums,enums.getErrorMessage());}public static ResponseResult errorResult(AppHttpCodeEnum enums, String errorMessage){return setAppHttpCodeEnum(enums,errorMessage);}public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){return okResult(enums.getCode(),enums.getErrorMessage());}private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage){return okResult(enums.getCode(),errorMessage);}public ResponseResult<?> error(Integer code, String msg) {this.code = code;this.errorMessage = msg;return this;}public ResponseResult<?> ok(Integer code, T data) {this.code = code;this.data = data;return this;}public ResponseResult<?> ok(Integer code, T data, String msg) {this.code = code;this.data = data;this.errorMessage = msg;return this;}public ResponseResult<?> ok(T data) {this.data = data;return this;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getErrorMessage() {return errorMessage;}public void setErrorMessage(String errorMessage) {this.errorMessage = errorMessage;}public T getData() {return data;}public void setData(T data) {this.data = data;}public String getHost() {return host;}public void setHost(String host) {this.host = host;}// 测试类public static void main(String[] args) {//前置/* AppHttpCodeEnum success = AppHttpCodeEnum.SUCCESS;System.out.println(success.getCode());System.out.println(success.getErrorMessage());*///查询一个对象/*Map map = new HashMap();map.put("name","zhangsan");map.put("age",18);ResponseResult result = ResponseResult.okResult(map);System.out.println(JSON.toJSONString(result));*///新增,修改,删除  在项目中统一返回成功即可/*ResponseResult result = ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);System.out.println(JSON.toJSONString(result));*///根据不用的业务返回不同的提示信息  比如:当前操作需要登录、参数错误/*ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"自定义提示信息");System.out.println(JSON.toJSONString(result));*///查询分页信息PageResponseResult responseResult = new PageResponseResult(1,5,50);List list = new ArrayList();list.add("itcast");list.add("itheima");responseResult.setData(list);System.out.println(JSON.toJSONString(responseResult));}}

③. 上面的返回类测试

④. 分页返回类

查看 com/heima/model/common/dtos/PageResponseResult.java 文件:

public class PageResponseResult extends ResponseResult implements Serializable {private Integer currentPage;private Integer size;private Integer total;public PageResponseResult(Integer currentPage, Integer size, Integer total) {this.currentPage = currentPage;this.size = size;this.total = total;}public PageResponseResult() {}public int getCurrentPage() {return currentPage;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public int getTotal() {return total;}public void setTotal(int total) {this.total = total;}
}

⑵. 实体类

新建 heima-leadnews-model/src/main/java/com/heima/model/user/dtos/LoginDto.java 文件:

@Data
public class LoginDto {/*** 手机号*/@ApiModelProperty(value = "手机号",required = true)private String phone;/*** 密码*/@ApiModelProperty(value = "密码",required = true)private String password;
}

⑶. Controller

新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java 文件:

@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {@PostMapping("/login_auth")public ResponseResult login(@RequestBody LoginDto dto) {return null;}
}

⑷. Mapper

新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/mapper/ApUserMapper.java 文件:

@Mapper
public interface ApUserMapper extends BaseMapper<ApUser> {}

⑸. service

新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/service/ApUserService.java 文件:

public interface ApUserService extends IService<ApUser>{/*** app端登录* @param dto* @return*/public ResponseResult login(LoginDto dto);}

⑹. 实现类Impl

  • 用户输入了用户名和密码进行登录,校验成功后返回jwt(基于当前用户的id生成)
  • 用户游客登录,生成jwt返回(基于默认值0生成)

新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/service/impl/ApUserServiceImpl.java 文件:

@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {@Overridepublic ResponseResult login(LoginDto dto) {//1.正常登录(手机号+密码登录)if (!StringUtils.isBlank(dto.getPhone()) && !StringUtils.isBlank(dto.getPassword())) {//1.1查询用户ApUser apUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));if (apUser == null) {return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户不存在");}//1.2 比对密码String salt = apUser.getSalt();String pswd = dto.getPassword();pswd = DigestUtils.md5DigestAsHex((pswd + salt).getBytes());if (!pswd.equals(apUser.getPassword())) {return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);}//1.3 返回数据  jwtMap<String, Object> map = new HashMap<>();map.put("token", AppJwtUtil.getToken(apUser.getId().longValue()));apUser.setSalt("");apUser.setPassword("");map.put("user", apUser);return ResponseResult.okResult(map);} else {//2.游客  同样返回token  id = 0Map<String, Object> map = new HashMap<>();map.put("token", AppJwtUtil.getToken(0l));return ResponseResult.okResult(map);}}
}

⑺. Controller

编辑 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java 文件:

@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录",tags = "app端用户登录")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")@ApiOperation("用户登录")public ResponseResult login(@RequestBody LoginDto dto){return apUserService.login(dto);}
}

二、接口测试工具

1. Postman

测试 账号错误密码错误游客登录用户登录 返回信息是否正确

2. Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(https://swagger.io/)。

⑴. 配置

①. 引入依赖

heima-leadnews-modelheima-leadnews-common 模块中引入该依赖

  <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId></dependency>

②. 配置类

新建 heima-leadnews-common/src/main/java/com/heima/common/swagger/SwaggerConfiguration.java 文件:

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {@Beanpublic Docket buildDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInfo()).select()// 要扫描的API(Controller)基础包.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();}private ApiInfo buildApiInfo() {Contact contact = new Contact("后海","","");return new ApiInfoBuilder().title("新闻头条-平台管理API文档").description("新闻头条后台api").contact(contact).version("1.0.0").build();}
}

③. 自动配置

编辑 heima-leadnews-common/src/main/resources/META-INF/spring.factories 文件:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration

⑵. 注解

①. 常用注解

在Java类中添加Swagger的注解即可生成Swagger接口文档,常用Swagger注解如下:

  • @Api:修饰整个类,描述Controller的作用
  • @ApiOperation:描述一个类的一个方法,或者说一个接口
  • @ApiParam:单个参数的描述信息
  • @ApiModel:用对象来接收参数
  • @ApiModelProperty:用对象接收参数时,描述对象的一个字段
  • @ApiResponse:HTTP响应其中1个描述
  • @ApiResponses:HTTP响应整体描述
  • @ApiIgnore:使用该注解忽略这个API
  • @ApiError :发生错误返回的信息
  • @ApiImplicitParam:一个请求参数
  • @ApiImplicitParams:多个请求参数的描述信息

@ApiImplicitParam属性:

属性 取值 作用
paramType 查询参数类型
path 以地址的形式提交数据
query 直接跟参数完成自动映射赋值
body 以流的形式提交 仅支持POST
header 参数在request headers 里边提交
form 以form表单的形式提交 仅支持POST
dataType 参数的数据类型 只作为标志说明,并没有实际验证
Long
String
name 接收参数名
value 接收参数的意义描述
required 参数是否必填
true 必填
false 非必填
defaultValue 默认值

②. 接口注解

编辑 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java 文件:

@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录", tags = "ap_user", description = "app端用户登录API")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")@ApiOperation("用户登录")public ResponseResult login(@RequestBody LoginDto dto){return apUserService.login(dto);}
}

③. 参数注解

编辑 heima-leadnews-model/src/main/java/com/heima/model/user/dtos/LoginDto.java 文件:

@Data
public class LoginDto {/*** 手机号*/@ApiModelProperty(value="手机号",required = true)private String phone;/*** 密码*/@ApiModelProperty(value="密码",required = true)private String password;
}

④. 在线API文档

启动user微服务,访问地址:http://localhost:51801/swagger-ui.html

3. Knife4j

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!(https://doc.xiaominfo.com/)

⑴. 配置

①. 引入依赖

编辑 heima-leadnews-common/pom.xml 文件:

        <!--knife4j接口文档--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId></dependency>

②. 配置类

新建 heima-leadnews-common/src/main/java/com/heima/common/swagger/Swagger2Configuration.java 文件:

@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {@Bean(value = "defaultApi2")public Docket defaultApi2() {Docket docket=new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())//分组名称.groupName("1.0").select()//这里指定Controller扫描包路径.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();return docket;}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("新闻头条API文档").description("新闻头条API文档").version("1.0").build();}
}

以上有两个注解需要特别说明:

注解 说明
@EnableSwagger2 该注解是Springfox-swagger框架提供的使用Swagger注解,该注解必须加
@EnableKnife4j 该注解是knife4j提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加

③. 自动配置

编辑 heima-leadnews-common/src/main/resources/META-INF/spring.factories 文件:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration,\com.heima.common.swagger.Swagger2Configuration

⑵. 文档(可下载离线文档)

接口文档: http://localhost:51801/doc.htm


三、App网关

1. gateway网关微服务

⑴. 服务工程结构

  • heima-leadnews-gateway 网关

    • heima-leadnews-admin-gateway 管理平台
    • heima-leadnews-wemedia-gateway 用户自媒体平台
    • heima-leadnews-app-gateway 用户移动APP

⑵. 配置

①. 导入依赖

新建 heima-leadnews-gateway/pom.xml 文件:

    <dependencies><!--gateway的staeter--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos的注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--nacos的配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--jwt解析jar包--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency></dependencies>

②. 引导类

新建 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/java/com/heima/app/gateway/AppGatewayApplication.java 文件:

@SpringBootApplication
@EnableDiscoveryClient  //开启注册中心
public class AppGatewayApplication {public static void main(String[] args) {SpringApplication.run(AppGatewayApplication.class,args);}
}

③. 配置文件

编辑 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/resources/bootstrap.yml 文件:

server:port: 51601
spring:application:name: leadnews-app-gatewaycloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml

④. nacos配置

nocos地址: http://192.168.200.130:8848/nacos

spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: useruri: lb://leadnews-userpredicates:- Path=/user/**filters:- StripPrefix= 1

⑶. 测试

启动项目网关和用户两个服务,使用postman进行测试

网关后的请求地址: localhost:51601/user/api/v1/login/login_auth

2. 认证过滤器

⑴. 思路分析

  • 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录
  • 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户
  • 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN
  • 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误

⑵. 全局过滤器

新建 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/java/com/heima/app/gateway/filter/AuthorizeFilter.java 文件:

@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取request和response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();//2.判断是否是登录if(request.getURI().getPath().contains("/login")){//放行return chain.filter(exchange);}//3.获取tokenString token = request.getHeaders().getFirst("token");//4.判断token是否存在if(StringUtils.isBlank(token)){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//5.判断token是否有效try {Claims claimsBody = AppJwtUtil.getClaimsBody(token);//是否是过期int result = AppJwtUtil.verifyToken(claimsBody);if(result == 1 || result  == 2){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}}catch (Exception e){e.printStackTrace();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//6.放行return chain.filter(exchange);}/*** 优先级设置  值越小  优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}

⑶. 断点调试

启动user服务,访问其他微服务,会提示需要认证才能访问,这个时候需要在heads中设置设置token才能正常访问。


四、App前端项目集成

  • 通过nginx的反向代理功能访问后台的网关资源
  • 通过nginx的静态服务器功能访问前端静态页面

1. nginx包

资源链接: https://pan.baidu.com/s/1gPfoG0FnLC3dIUjJhqlKSQ?pwd=abcd


解压包,运行nginx

2. 前端项目

资源链接: https://pan.baidu.com/s/1wqfxtQCj_aGqSZVxgADVTQ?pwd=abcd

解压包,记住前端项目存放路径

3. 配置nginx.conf文件1

(nginx包中)新建 D:\code\hm\leadnews\config\nginx-1.18.0\conf\leadnews.conf\heima-leadnews-app.conf 文件:

upstream  heima-app-gateway{server localhost:51601; # 根据网关去做的请求
}server {listen 8801;location / {root D:/code/hm/leadnews/config/app-web/; # 访问前端静态资源index index.html;}location ~/app/(.*) {proxy_pass http://heima-app-gateway/$1;proxy_set_header HOST $host;  # 不改变源请求头的值proxy_pass_request_body on;  #开启获取请求体proxy_pass_request_headers on;  #开启获取请求头proxy_set_header X-Real-IP $remote_addr;   # 记录真实发出请求的客户端IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #记录代理信息}
}

4. 配置nginx.conf文件2

(nginx包中)编辑 D:\code\hm\leadnews\config\nginx-1.18.0\conf\leadnews.conf\nginx.conf 文件:

#user  nobody;
worker_processes  1;events {worker_connections  1024;
}
http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;# 引入自定义配置文件include leadnews.conf/*.conf;
}

5. 重新加载nginx

# 重新加载nginx
nginx -s reload

6. 运行测试

前端地址: http://localhost:8801/

SpringCloud微服务项目实战 - 2.App登录及网关相关推荐

  1. SpringCloud微服务项目实战 - 5.自媒体文章审核

    愤怒归根结底是为了达成目的的一种工具和手段,大声呵斥乃至拍桌子,目的都是通过震慑对方,进而使其听自己的话,因为他们也找不到更好的办法. 系列文章目录 项目搭建 App登录及网关 App文章 自媒体平台 ...

  2. SpringCloud微服务项目实战 - 6.延迟任务

    我没有失约,我与春风共至,我与夏蝉共鸣,我与秋叶共舞,我与凛冬共至,唯独你背道而行! 系列文章目录 项目搭建 App登录及网关 App文章 自媒体平台(博主后台) 内容审核(自动) 延迟任务 - 精准 ...

  3. SpringCloud微服务架构实战库存管理与分布式文件系统

    库存管理与分布式文件系统 在电商平台的库存管理系统设计中,将涉及商品和本地图库的管理,这里我们将使用另一种数据开发框架 MyBatis进行数据库访问方面的设计,还将实现与分布式文件系统的对接使用. 本 ...

  4. SpringCloud微服务架构实战:商家权限体系设计及开发

    商家管理后台与sso设计 在本文的电商平台实例中,商家是这个平台的主角,商家管理后台是专门为这个主角提供的一个安全可靠的操作平台.在商家管理后台中,商家可以进行商品管理.订单管理.物流管理.会员管理. ...

  5. SpringCloud微服务架构实战:微服务治理

    微服务治理 Spring Cloud 工具套件为微服务治理提供了全面的技术支持.这些治理工具主要包括服务的注册与发现.负载均衡管理.动态路由.服务降级和故障转移.链路跟踪.服务监控等.微服务治理的主要 ...

  6. 微服务 前台调用后台的慢的原因_20年IT农民工分享SpringCloud微服务架构实战文档...

    前言 越来越多的企业使用 SpringCloud 实现微服务架构设计.我们可以看到这样一种现象:不管是全新开发,还是系统重构,大家似乎都在争先恐后地使用微服务.对于一个Java开发人员来说,学习微服务 ...

  7. springcloud微服务项目架构搭建第一天

    springcloud微服务项目架构搭建第一天 (一).项目简介 1.准备工作:idea创建springboot模板 2.后台应该涉及的技术(后期可能会有删改) Spring Framework 容器 ...

  8. Spring Cloud Alibaba 大型微服务项目实战

    作者介绍 程序员十三,多年一线开发经验,历任高级开发工程师.后端主程.技术部门主管等职位.同时也是开源项目的爱好者和贡献者.掘金优秀作者.CSDN 博客专家.实体图书作者.专栏作者.视频讲师. 小册介 ...

  9. 关于华为私有云部署若依springcloud微服务项目改造及部署

    关于华为私有云部署若依springcloud微服务项目改造及部署 1.项目介绍 ​ 当前微服务项目主流的注册中心为阿里巴巴的nacos,但介于甲方要求使用华为的注册中心,所以在接下来讲解项目改造: 2 ...

最新文章

  1. 游击式(移动)开发的两种方式
  2. rpm安装两个mysql_MySQL通过rpm安装及其单机多实例部署
  3. 1027. 打印沙漏(20)
  4. SQL Cookbook—数字、日期
  5. 大数据_Flink_流式处理_简介_认识一下什么是BI中的ETL---Flink工作笔记0005
  6. RMAN备份与恢复资料
  7. uiactionsheet 代理_iOS UIActionSheet (点击事件笔记)
  8. TCP/IP - ARP的作用、RARP协议
  9. 二元函数对xy同时求导_《高等数学》微课视频“二元函数的全微分求积”录音...
  10. JAVA数组内存分析 面向对象 类和对象 创建对象的内存分析 成员变量 局部变量
  11. 基于双目深度估计的深度学习技术研究
  12. java set方法无法使用_Java setBounds无法与JPanel一起使用
  13. 清华大学尹成 怎么样
  14. 关于我的专业(niit软件工程方向)
  15. c语言300行代码大作业,C语言300行代码
  16. UX术语详解:任务流,用户流,流程图以及其它全新术语
  17. 如何用php农场项目,2020全新亲测php农场游戏源码-金币菇种植理财区块链源码 带商城系统...
  18. 2019 年科技趋势最全汇总!
  19. 牛客网Java编程题总结
  20. STM32程序烧录---TTL

热门文章

  1. 多元统计分析 小总结 python实现
  2. java-求矩形(长方形)的周长和面积案例
  3. 基于matlab的陷波滤波器设计
  4. 基因驱动 CovEx 代码阅读(一)
  5. 光纤收发器的原理及应用_光纤收发器的作用原理
  6. 约数国王(A king)
  7. js事件-阻止默认操作
  8. 《Linux Device Driver》——时间、延迟及延缓操作
  9. 2022 年超详细过程步骤讲解 CentOS 7 安装Maven。以及Mavne配置文件的修改
  10. 《人机交互:软件工程视角》期末复习提纲