黑马头条微服务学习day01-环境搭建、SpringCloud微服务(注册发现、网关)
创始人
2025-01-10 22:37:02
0

文章目录

  • 项目介绍
    • 环境搭建
    • 项目背景
    • 业务功能
    • 技术栈说明
  • nacos
    • 服务器环境准备
    • nacos安装
  • 初始工程搭建
    • 环境准备
    • 主体结构
  • app登录
    • 需求分析
    • 表结构分析
    • 手动加密
    • 微服务搭建
    • 接口定义
    • 功能实现
      • 登录功能实现
    • Swagger使用
    • app端网关
    • nginx配置

项目介绍

环境搭建

在这里插入图片描述
在这里插入图片描述

项目背景

在这里插入图片描述

业务功能


在这里插入图片描述

技术栈说明

在这里插入图片描述
在这里插入图片描述

nacos

可以直接参照各种虚拟机安装centos7,不必拘泥于课程所给的镜像,只要保证能与外界ping通即可。后续环境可以自行安装。
同时使用mac的m系列芯片的同学可以直接不使用虚拟机直接在本地下载docker配置环境(注意要适配ARM架构)。

服务器环境准备

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

nacos安装

在这里插入图片描述
在这里插入图片描述

初始工程搭建

环境准备

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置Maven
在这里插入图片描述

主体结构

在这里插入图片描述
在这里插入图片描述

app登录

需求分析

在这里插入图片描述

表结构分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过逆向工程生成

package com.heima.model.user.pojos;  import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;  import java.io.Serializable; import java.util.Date;  /**  * 

* APP用户信息表 *

* * @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; }

手动加密

在这里插入图片描述
在这里插入图片描述

微服务搭建

在这里插入图片描述
在下面新建一个工程
在这里插入图片描述
bootstrap配置

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

使用nacos创建新集群
在这里插入图片描述

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

配置logback.xml

                                                          %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n             utf8                                                            ${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log                               %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n                                           0                  512                                                                                        

在这里插入图片描述

接口定义

在这里插入图片描述
在这里插入图片描述

功能实现

登录功能实现

下面分Controller,Service,ServiceImpl层,与Mapper层依次输入代码

@RestController @RequestMapping("/api/v1/login") public class ApUserLoginController {     @Autowired     private APUserService apUserService;     @PostMapping("/login_auth")     public ResponseResult login(@RequestBody LoginDto dto){         return apUserService.login(dto);     } } 
package com.heima.user.service;   import com.baomidou.mybatisplus.extension.service.IService; import com.heima.model.common.dtos.ResponseResult; import com.heima.model.common.user.dtos.LoginDto; import com.heima.model.common.user.pojos.ApUser;  public interface APUserService extends IService {      /**      * app端登录功能      * @param dto      * @return      */     public ResponseResult login(LoginDto dto); } 
@Service @Transactional @Slf4j /**  * ApUserMapper:这是一个 MyBatis-Plus 的 Mapper 接口,通常用于定义数据库操作的方法。  * ApUser:这是一个实体类,表示数据库中的一张表。  */ public class ApUserServiceImpl extends ServiceImpl implements APUserService {     /**      * app登录功能      * @param dto      * @return      */     @Override     public ResponseResult login(LoginDto dto) {         //1.正常登录用户用户名和密码         if (StringUtils.isNotEmpty(dto.getPhone())&&StringUtils.isNotEmpty(dto.getPassword())){             //1.1根据手机号从数据库中查询用户信息             ApUser dbUser = getOne(Wrappers.lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));             if (dbUser == null){                 return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户信息不存在");             }             //1.2比对密码             String salt = dbUser.getSalt();             String password = dto.getPassword();             String pswd = DigestUtils.md5DigestAsHex((password + salt).getBytes());             if (!pswd.equals(dbUser.getPassword())){                 return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);             }             //1.3 返回数据jwt user             String token = AppJwtUtil.getToken(dbUser.getId().longValue());             //跟接口返回值描述保持一致             Map map = new HashMap<>();             map.put("token",token);             dbUser.setSalt("");             dbUser.setPassword("");             map.put("user",dbUser);             return ResponseResult.okResult(map);         }else {             //2.游客登录             Map map = new HashMap<>();             map.put("token",AppJwtUtil.getToken(0L));             return ResponseResult.okResult(map);         }      } } 
@Mapper public interface ApUserMapper extends BaseMapper {  } 

使用接口工具类进行测试
在这里插入图片描述

Swagger使用

在这里插入图片描述
在这里插入图片描述

  • 引入依赖,在heima-leadnews-model和heima-leadnews-common模块中引入该依赖

         io.springfox     springfox-swagger2       io.springfox     springfox-swagger-ui  

只需要在heima-leadnews-common中进行配置即可,因为其他微服务工程都直接或间接依赖即可。

  • 在heima-leadnews-common工程中添加一个配置类

新增:com.heima.common.swagger.SwaggerConfiguration

package com.heima.common.swagger;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;  @Configuration @EnableSwagger2 public class SwaggerConfiguration {     @Bean    public 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模块中的resources目录中新增以下目录和文件

文件:resources/META-INF/Spring.factories

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

给Controller和DTO更新注解

@RestController @RequestMapping("/api/v1/login") @Api(value = "app端用户登录",tags = "app端用户登录") public class ApUserLoginController {     @Autowired     private ApUserService apUserService;     @PostMapping("/login_auth")     @ApiOperation("用户登录")     public ResponseResult login(@RequestBody LoginDto dto){         return apUserService.login(dto);     }   } 
@Data public class LoginDto {     /**      * 手机号      */     @ApiModelProperty(value = "手机号",required = true)     private String phone;     /**      * 密码      */     @ApiModelProperty(value = "密码",required = true)     private String password; } 

打开Swagger
在这里插入图片描述
在这里插入图片描述

app端网关

在这里插入图片描述
在这里插入图片描述
(1)在heima-leadnews-gateway导入以下依赖

pom文件

              org.springframework.cloud         spring-cloud-starter-gateway                   com.alibaba.cloud         spring-cloud-starter-alibaba-nacos-discovery                        com.alibaba.cloud             spring-cloud-starter-alibaba-nacos-config                       io.jsonwebtoken         jjwt       

(2)在heima-leadnews-gateway下创建heima-leadnews-app-gateway微服务

引导类:

package com.heima.app.gateway;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;  @SpringBootApplication @EnableDiscoveryClient  //开启注册中心 public class AppGatewayApplication {      public static void main(String[] args) {         SpringApplication.run(AppGatewayApplication.class,args);     } } 

bootstrap.yml

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

在nacos的配置中心创建dataid为leadnews-app-gateway的yml配置

spring:   cloud:     gateway:       globalcors:         add-to-simple-url-handler-mapping: true         corsConfigurations:           '[/**]':             allowedHeaders: "*"             allowedOrigins: "*"             allowedMethods:               - GET               - POST               - DELETE               - PUT               - OPTION       routes:         # 平台管理         - id: user           uri: lb://leadnews-user           predicates:             - Path=/user/**           filters:             - StripPrefix= 1 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

bootstrap

server:   port: 51601 spring:   application:     name: leadnews-app-gateway   cloud:     nacos:       discovery:         server-addr: localhost:8848       config:         server-addr: localhost:8848         file-extension: yml 

设置权限过滤器

package com.heima.app.gateway.filter;  import com.heima.app.gateway.util.AppJwtUtil; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;  @Component @Slf4j public class AuthorizeFilter implements Ordered, GlobalFilter {      @Override     public Mono 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.获取token         String 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      */     @Override     public int getOrder() {         return 0;     } }  
package com.heima.app.gateway.util;  import io.jsonwebtoken.*;  import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.*;  public class AppJwtUtil {      // TOKEN的有效期一天(S)     private static final int TOKEN_TIME_OUT = 3_600;     // 加密KEY     private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";     // 最小刷新间隔(S)     private static final int REFRESH_TIME = 300;      // 生产ID     public static String getToken(Long id){         Map claimMaps = new HashMap<>();         claimMaps.put("id",id);         long currentTime = System.currentTimeMillis();         return Jwts.builder()                 .setId(UUID.randomUUID().toString())                 .setIssuedAt(new Date(currentTime))  //签发时间                 .setSubject("system")  //说明                 .setIssuer("heima") //签发者信息                 .setAudience("app")  //接收用户                 .compressWith(CompressionCodecs.GZIP)  //数据压缩方式                 .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式                 .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间戳                 .addClaims(claimMaps) //cla信息                 .compact();     }      /**      * 获取token中的claims信息      *      * @param token      * @return      */     private static Jws getJws(String token) {             return Jwts.parser()                     .setSigningKey(generalKey())                     .parseClaimsJws(token);     }      /**      * 获取payload body信息      *      * @param token      * @return      */     public static Claims getClaimsBody(String token) {         try {             return getJws(token).getBody();         }catch (ExpiredJwtException e){             return null;         }     }      /**      * 获取hearder body信息      *      * @param token      * @return      */     public static JwsHeader getHeaderBody(String token) {         return getJws(token).getHeader();     }      /**      * 是否过期      *      * @param claims      * @return -1:有效,0:有效,1:过期,2:过期      */     public static int verifyToken(Claims claims) {         if(claims==null){             return 1;         }         try { //            claims.getExpiration() //                    .before(new Date());             // 需要自动刷新TOKEN             if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){                 return -1;             }else {                 return 0;             }         } catch (ExpiredJwtException ex) {             return 1;         }catch (Exception e){             return 2;         }     }      /**      * 由字符串生成加密key      *      * @return      */     public static SecretKey generalKey() {         byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());         SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");         return key;     }      public static void main(String[] args) {        /* Map map = new HashMap();         map.put("id","11");*/         System.out.println(AppJwtUtil.getToken(1102L));         Jws jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");         Claims claims = jws.getBody();         System.out.println(claims.get("id"));      }  }  

nginx配置

在这里插入图片描述
在这里插入图片描述
①:解压资料文件夹中的压缩包nginx-1.18.0.zip

②:解压资料文件夹中的前端项目app-web.zip

③:配置nginx.conf文件

在nginx安装的conf目录下新建一个文件夹leadnews.conf,在当前文件夹中新建heima-leadnews-app.conf文件

heima-leadnews-app.conf配置如下:

upstream  heima-app-gateway{     server localhost:51601; }  server { 	listen 8801; 	location / { 		root D:/workspace/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;   # 记录真实发出请求的客户端IP 		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #记录代理信息 	} } 

nginx.conf 把里面注释的内容和静态资源配置相关删除,引入heima-leadnews-app.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; } 

④ :启动nginx

​ 在nginx安装包中使用命令提示符打开,输入命令nginx启动项目

​ 可查看进程,检查nginx是否启动

​ 重新加载配置文件:nginx -s reload

⑤:打开前端项目进行测试 – > http://localhost:8801

​ 用谷歌浏览器打开,调试移动端模式进行访问
在这里插入图片描述

相关内容

热门资讯

3分钟知晓!wepoker有辅... 【福星临门,好运相随】;3分钟知晓!wepoker有辅助挂,wepoker德州作弊辅助挂,AI教程(...
透牌教程《德州版wpk透视辅助... 透牌教程《德州版wpk透视辅助》太坑了原来确实是有挂(讲解有挂);AI智能教程细节普及透牌教程《德州...
玩家必用《Wepoke识别》软... 玩家必用《Wepoke识别》软件透明挂!(辅助挂)外挂透明挂AI代打(2022已更新)(哔哩哔哩)是...
力荐教程《wpK透视辅助》太坑... 您好:这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌...
分享实测(智星德州菠萝)软件透... 您好,智星德州菠萝这款游戏可以开挂的,确实是有挂的,需要了解加微【136704302】很多玩家在这款...
七分钟了解(WPK打法)透视辅... 七分钟了解(WPK打法)透视辅助(wpk)辅助透视器(2020已更新)(哔哩哔哩);最新版2024是...
每日必看教程wepoke辅助透... 每日必看教程wepoke辅助透视是真的(辅助挂)软件透明挂(2023已更新)(哔哩哔哩);1、超多福...
第3个知道!wepoker透视... 第3个知道!wepoker透视脚本免费下载,WePoker辅助挂教程,可靠教程(有挂攻略)是一款休闲...
必赢方法《wPK透视辅助》太坑... 《软件透明挂》是一款多人竞技的辅助透视游戏,你将微扑克对手来到同一个战场,为至高无上的荣耀进行一次自...
科普常识《Wepoke德州》软... 亲,这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌,...