【黑马头条】-day01环境搭建SpringBoot-Cloud-Nacos


文章目录

  • 1 环境搭建及简介
  • 2 项目介绍
    • 2.1 应用
    • 2.2 业务说明
    • 2.3 技术栈
    • 2.4 收获
    • 2.5 大纲
  • 3 Nacos准备
    • 3.1 安装Nacos
  • 4 初始工程搭建
    • 4.1 环境准备
      • 4.1.1 导入项目
      • 4.1.2 设置本地仓库
      • 4.1.3 设置项目编码格式
    • 4.2 全局异常
      • 4.2.1 自动装配
    • 4.3 工程主体结构
  • 5 登录功能开发
    • 5.1 需求分析
      • 5.1.1 表结构分析
      • 5.1.2 实体类ApUser的导入
      • 5.1.3 表结构中salt的解释
        • 5.1.3.1 注册过程
        • 5.1.3.2 登录过程
  • 6 用户端微服务的搭建
    • 6.1 service模块的依赖说明
    • 6.2 创建用户微服务模块
      • 6.2.1 创建引导类
      • 6.2.2 创建controller.v1、service、mapper、config
      • 6.2.3 创建resources的配置文件
        • 6.2.3.1 bootstrap.yml
        • 6.2.3.2 logback.xml
    • 6.3 整体用户端框架
  • 7 登录接口实现
    • 7.1 app登录-接口定义
      • 7.1.1 DTO的LoginDto类
      • 7.1.2 Controller层ApUserLoginController类
      • 7.1.3 Mapper层ApUserMapper接口
      • 7.1.4 Service层ApUserService接口
      • 7.1.5 实现ApUserService接口
      • 7.1.6 完善业务层接口
    • 7.2 登录思路分析
      • 7.2.1 业务层登录实现
      • 7.2.2 Controller注入
      • 7.2.3 测试
  • 8 App端网关
    • 8.1 导入依赖
    • 8.2 微服务创建网关
      • 8.2.1 AppGateway
      • 8.2.2 创建配置文件bootstrap.yml
      • 8.2.3 在Nacos中创建配置中心
  • 9 认证过滤器
    • 9.1 全局过滤器
    • 9.2 测试
  • 10 app前端项目集成
    • 10.1 Nginx反向代理和静态资源配置


1 环境搭建及简介

在这里插入图片描述

在这里插入图片描述

2 项目介绍

2.1 应用

在这里插入图片描述

2.2 业务说明

在这里插入图片描述

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

2.3 技术栈

前端
在这里插入图片描述

后端

在这里插入图片描述

2.4 收获

在这里插入图片描述

2.5 大纲

在这里插入图片描述

3 Nacos准备

3.1 安装Nacos

在这里插入图片描述

1)拉取镜像

docker pull nacos/nacos-server:1.2.0

2)创建容器

docker run --env MODE=standalone --name nacos --restart=always -d -p 8848:8848 nacos/nacos-server:1.2.0

3)查看日志

docker logs -f nacos

在这里插入图片描述

4)访问当前Nacos

http://192.168.204.129:8848/nacos

4 初始工程搭建

4.1 环境准备

4.1.1 导入项目

在这里插入图片描述

解压heima-leadnews.zip,并且导入idea,设置jdk为1.8
在这里插入图片描述

4.1.2 设置本地仓库

respository_new.zip解压到本地仓库文件夹

打开idea-settings设置本地仓库
在这里插入图片描述

修改为
在这里插入图片描述

4.1.3 设置项目编码格式

在这里插入图片描述

4.2 全局异常

在这里插入图片描述

heima-leadnews-common模块下的com.heima.common.exception包下自定义异常类CustomException,如果我们手动抛出异常就需要抛出CustomException类

public class CustomException extends RuntimeException {private AppHttpCodeEnum appHttpCodeEnum;public CustomException(AppHttpCodeEnum appHttpCodeEnum){this.appHttpCodeEnum = appHttpCodeEnum;}public AppHttpCodeEnum getAppHttpCodeEnum() {return appHttpCodeEnum;}
}

另外一个类ExceptionCatch类,全局异常拦截类

注解@ControllerAdvice:ControllerAdvice本质上是一个Component,因此也会被当成组件扫描,一视同仁,扫扫扫。

  • 这个类是为那些声明了(@ExceptionHandler、@InitBinder 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的@Component , 以供多个 Controller类所共享。
@ControllerAdvice  //控制器增强类
@Slf4j
public class ExceptionCatch {/*** 处理不可控异常* @param e* @return*/@ExceptionHandler(Exception.class)@ResponseBodypublic ResponseResult exception(Exception e){e.printStackTrace();log.error("catch exception:{}",e.getMessage());return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);}/*** 处理可控异常  自定义异常* @param e* @return*/@ExceptionHandler(CustomException.class)@ResponseBodypublic ResponseResult exception(CustomException e){log.error("catch exception:{}",e);return ResponseResult.errorResult(e.getAppHttpCodeEnum());}
}

在heima-leadnews-model模块下的com.heima.model包下的common包下的enums包下有个枚举类AppHttpCodeEnum,用来存放对异常的说明

public enum AppHttpCodeEnum {// 成功段0SUCCESS(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;}
}

4.2.1 自动装配

resource下META-INF有spring.factories,只有有微服务引用了heima-leadnews-common,服务器初始化spring容器的时候就会找到spring.factories,把spring.factories中需要自动配置的文件加载到当前微服务的容器中,也就能用全局处理器了。

在这里插入图片描述

4.3 工程主体结构

在这里插入图片描述

5 登录功能开发

5.1 需求分析

在这里插入图片描述

5.1.1 表结构分析

打开本地sql工具,引入sql脚本,创建leadnews_user,有四张表

在这里插入图片描述

在这里插入图片描述

5.1.2 实体类ApUser的导入

在heima-leadnews-model模块下创建com.heima.model.user.pojos包下创建实体类ApUser

@TableName("ap_user"):表的映射

@TableId(value = "id", type = IdType.AUTO):主键的映射

@TableField("name"):其他字段的映射

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

5.1.3 表结构中salt的解释

salt:密码、通信等加密盐

5.1.3.1 注册过程

在这里插入图片描述

5.1.3.2 登录过程

在这里插入图片描述

6 用户端微服务的搭建

heima-leadnews-service模块是管理其他所有微服务模块

6.1 service模块的依赖说明

在这里插入图片描述

6.2 创建用户微服务模块

在heima-leadnews-service下创建模块

在这里插入图片描述

6.2.1 创建引导类

然后创建一个包com.heima.user,再创建一个引导类UserApplication

@SpringBootApplication: 启动类注解

@EnableDiscoveryClient :集成当前的注册中心,加入注册中心

@MapperScan("com.heima.user.mapper") :继承MybatisPlus,扫描Mapper接口,没有就在com.heima.user下创建mapper包

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.user.mapper")
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}

6.2.2 创建controller.v1、service、mapper、config

controller.v1是不同版本的controller

在这里插入图片描述

6.2.3 创建resources的配置文件

6.2.3.1 bootstrap.yml

若application.yml 和bootstrap.yml在同一目录下:bootstrap.yml 先加载 application.yml后加载,application.yml会覆盖

创建bootstrap.yml

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

这里面暂时只有Nacos的配置,关于数据库的等等都需要在Nacos的配置中心进行配置

在这里插入图片描述

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

发布查看

6.2.3.2 logback.xml

创建日志文件logback.xml

<?xml version="1.0" encoding="UTF-8"?><configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="D:\Code\JavaCode\HeimaToutiao\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>

6.3 整体用户端框架

在这里插入图片描述

7 登录接口实现

7.1 app登录-接口定义

在这里插入图片描述

7.1.1 DTO的LoginDto类

heima-leadnews-model模块下的com.heima.model.user.pojos.dtos包下创建LoginDto类

@Data
public class LoginDto {private String phone;private String password;
}

7.1.2 Controller层ApUserLoginController类

再在heima-leadnews-service模块下的com.heima.user.controller.v1下创建ApUserLoginController类

POST请求采用@RequestBody

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

7.1.3 Mapper层ApUserMapper接口

使用mybatisplus

在com.heima.user.mapper创建ApUserMapper接口

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

7.1.4 Service层ApUserService接口

public interface ApUserService extends IService<ApUser>{
}

7.1.5 实现ApUserService接口

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {
}

@Service标注业务层实现

@Transactional标注事务

7.1.6 完善业务层接口

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

实现方法

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {@Overridepublic ResponseResult login(LoginDto dto) {return null;}
}

7.2 登录思路分析

7.2.1 业务层登录实现

在这里插入图片描述

在ApUserServiceImpl类中实现思路

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {@Overridepublic ResponseResult login(LoginDto dto) {//1.正常登录 用户名、密码if(StringUtils.isNotBlank(dto.getPhone()) && StringUtils.isNotBlank(dto.getPassword())) {//1.1 查询用户信息,根据手机号查询用户信息ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));if(dbUser == null) {return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST, "用户不存在");}//1.2 比对密码String salt = dbUser.getSalt();String password = dto.getPassword();String pwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());if(!pwd.equals(dbUser.getPassword())) {return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR, "密码错误");}//1.3 没问题的话,返回数据,生成jwtString token = AppJwtUtil.getToken(dbUser.getId().longValue());Map<String,Object> map=new HashMap<>();map.put("token",token);//清空敏感信息,前端只要id,手机号,昵称ApUser userVO=new ApUser();userVO.setId(dbUser.getId());userVO.setPhone(dbUser.getPhone());userVO.setName(dbUser.getName());map.put("user",userVO);return ResponseResult.okResult(map);}else{//2.游客登录Map<String,Object> map=new HashMap<>();map.put("token",AppJwtUtil.getToken(0L));return ResponseResult.okResult(map);}}
}

加密采用DigestUtils.md5DigestAsHex传入字节流

生成JWT令牌是使用heima-leadnews-utils模块下的com.heima.utils.common包下的AppJWTUtil

public class AppJwtUtil {// TOKEN的有效期一天(S)private static final int TOKEN_TIME_OUT = 3_600;// 加密KEYprivate static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";// 最小刷新间隔(S)private static final int REFRESH_TIME = 300;// 生产IDpublic static String getToken(Long id){Map<String, Object> 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<Claims> 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());// 需要自动刷新TOKENif((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<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");Claims claims = jws.getBody();System.out.println(claims.get("id"));}}

7.2.2 Controller注入

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

7.2.3 测试

启动redis报错

修改bootstrap.yml文件,添加redis地址

redis:host: 127.0.0.1port: 6379database: 0

启动,Nacos的服务管理中有leadnews-user

访问http://localhost:51801/api/v1/login/login_auth

在这里插入图片描述

8 App端网关

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

8.1 导入依赖

在heima-leadnews-gateway导入以下依赖

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency>
</dependencies>

8.2 微服务创建网关

8.2.1 AppGateway

针对各个微服务创建相应的网关

在这里插入图片描述

创建引导类com.heima.app.gateway.AppGatewayApplication

@SpringBootApplication
@EnableDiscoveryClient
public class AppGatewayApplication {public static void main(String[] args) {SpringApplication.run(AppGatewayApplication.class, args);}
}

8.2.2 创建配置文件bootstrap.yml

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

8.2.3 在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
  • id: user: 这是此路由的唯一标识符。
  • uri: lb://leadnews-user: 当请求匹配到该路由时,它会被路由到"leadnews-user"服务的实例。URI的前缀"lb://"表示路由到负载均衡器。
  • predicates: 定义了路由的匹配规则。在这种情况下,请求路径必须以"/user/"开头才会匹配到此路由。
  • filters: 定义了路由的过滤器。在这里,使用了"StripPrefix"过滤器,该过滤器会将请求的路径中的一层前缀移除。具体来说,这里是将路径中的第一层"/user"移除,以便在转发请求到"leadnews-user"服务时去除不必要的前缀。

访问http://localhost:51601/user/api/v1/login/login_auth

在这里插入图片描述

9 认证过滤器

在这里插入图片描述

9.1 全局过滤器

要实现这个功能,要实现一个全局的过滤器

在heima-leadnews-gateway模块下创建com.heima.app.gateway.filter.AuthorizeFilter类用作全局过滤器

@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.获取当前请求的token信息String token = request.getHeaders().getFirst("token");//4.判断token是否存在if(StringUtils.isBlank(token)) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//5.判断token是否有效//5.1 解析tokentry{Claims body = AppJwtUtil.getClaimsBody(token);//5.2 判断token是否有效int result = AppJwtUtil.verifyToken(body);if(result == 1||result == 2) {//5.3 token过期response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}}catch (Exception e) {e.printStackTrace();//5.4 token无效response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//6.放行return chain.filter(exchange);}/*** 过滤器的执行顺序,返回值越小,执行优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}

把AppJwtUtil放入gateway的工具包中

在这里插入图片描述

9.2 测试

包含/login直接放行

在这里插入图片描述

10 app前端项目集成

10.1 Nginx反向代理和静态资源配置

在这里插入图片描述

在这里插入图片描述

访问http://localhost:80

在这里插入图片描述

将静态资源和nginx都放在工作目录下

在nginx的conf目录下创建文件夹leadnews.conf,新建文件heimi-leadnews-app.conf

nginx端口8801然后转发到gateway端口51601,gateway添加user路径后通过Nacos路由到leadnews-user也就是端口51801完成访问

静态资源存放在D:/Code/JavaCode/HeimaToutiao/app-web/展示其目录下的index.html

upstream  heima-app-gateway{server localhost:51601;
}server {listen 8801;location / {root D:/Code/JavaCode/HeimaToutiao/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;  #记录代理信息}
}

在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;
}

访问http://localhost:8801

在这里插入图片描述

访问成功

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echart多折线图堆叠 y轴和实际数据不对应

当使用 ECharts 绘制堆叠折线图时&#xff0c;有时会遇到 y 轴与实际数据不对应的问题。 比如明明值是50&#xff0c;但折线点在y轴的对应点却飙升到了二百多 解决办法&#xff1a; 查看了前端代码发现在echart的图表中有一个‘stack’的属性&#xff0c;尝试把他删除之后y轴的…

算法体系-11 第十一节:二叉树基本算法(上)

一 两链表相交 1.1 题目描述 给定两个可能有环也可能无环的单链表&#xff0c;头节点head1和head2。请实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的 第一个节点。如果不相交&#xff0c;返回null 【要求】 如果两个链表长度之和为N&#xff0c;时间复杂…

静电无处不在:揭秘液晶显示屏静电防护的“大师级“策略

静电&#xff0c;仿佛是电子产品制造过程中的隐形杀手&#xff0c;尤其对于液晶显示屏等精密电子元器件的影响更是不可小觑。然而&#xff0c;面对这一挑战&#xff0c;有些制造商采取了一系列超越寻常的静电防护措施。今天&#xff0c;我们将揭开他们的"大师级"策略…

利用Android studio 查看模拟器中数据文件

打开Android studio &#xff0c;然后按照下图选择 然后会在右侧打开一个这样子的管理弹窗 找到 data/data/your project file 你的缓存跟下载的文件就都在里面了

BigDecimal保留两位小数失败问题

文章目录 背景问题解决如何测试代码 背景 测试时发现在线swagger测试会自动处理BigDecimal小数点后面的数字&#xff0c;就是有零的会都给你去掉&#xff0c;比如9.000与9.500到最后都会被swagger处理成9跟9.5。使用postman测是最准的&#xff0c;测出来的就是9.000跟9.500。 …

数据库基本内容与安装MySQL数据库

目录 一.数据库基本内容 1.数据 &#xff08;1&#xff09;描述事物的符号记录 &#xff08;2&#xff09;包括数字&#xff0c;文字、图形、图像、声音、档案记录等 &#xff08;3&#xff09;以“记录”形式按统一的格式进行存储 2.表 &#xff08;1&#xff09;将不同…

【Linux】基础 IO(动静态库)-- 详解

一、前言 为什么要使用别人的代码&#xff1f; 主要是为了提高程序开发的效率和程序的健壮性。 当别人把功能都实现了&#xff0c;然后我们再基于别人的代码去做二次开发&#xff0c;那么效率当然就提高了。其次&#xff0c;这里基于的别人当然不是随便找的一个人&#xff0c;…

[Qt学习笔记]Qt鼠标事件mouseMoveEvent实时获取图像的坐标和像素值

目录 1、介绍2、效果展示3、实现过程3.1 图像的加载和显示3.2 设置鼠标跟踪事件激活3.3 实现代码 4、源码展示 1、介绍 上一篇介绍了使用OpenCV的setMouseCallback回调函数实现获取鼠标点击点的图像坐标和像素值&#xff0c;本篇使用鼠标事件mouseMoveEvent函数来实现实时获取…

OPPO 后端二面,凉凉。。。

美众议院通过 TikTok 法案 之前我们讲了 老美要求字节跳动在 165 天内剥离短视频应用 TikTok&#xff0c;当时的最新进度是 TikTok 给 1.7 亿美国用户发弹窗&#xff0c;发动用户群众给国会打电话进行抗议。 但显然这点力度的抗议并不会造成什么实质影响。 昨晚&#xff0c;美国…

精读《useRef 与 createRef 的区别》

1 引言 useRef 是常用的 API&#xff0c;但还有一个 createRef 的 API&#xff0c;你知道他们的区别吗&#xff1f;通过 React.useRef and React.createRef: The Difference 这篇文章&#xff0c;你可以了解到何时该使用它们。 2 概述 其实原文就阐述了这样一个事实&#xf…

【EDSR】《Enhanced Deep Residual Networks for Single Image Super-Resolution》

CVPR workshops-2017 首尔大学 code&#xff1a; https://github.com/limbee/NTIRE2017/tree/masterhttps://github.com/sanghyun-son/EDSR-PyTorch 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method4.1 Residual blocks4.2 Single…

盘点国内IP地址服务的功能及提供商

随着互联网的快速发展和普及&#xff0c;IP地址服务提供商在中国市场扮演着越来越重要的角色。这些代理软件提供商不仅为用户提供稳定的网络连接&#xff0c;还可以帮助用户实现IP地址切换、绕过地理限制等功能。虎观代理接下来将详解国内IP地址服务的主要功能&#xff0c;并对…

字符串函数---(1)

字符函数 文章目录 前言1.strlen 的使用和模拟实现2.strcpy 的使用和模拟实现3. strcat 的使用和模拟实现4. strcmp 的使用和模拟实现 前言 上一篇我们学习了字符函数&#xff0c;下来我们学习常见的字符串函数 1.strlen 的使用和模拟实现 size_t strlen(const char *str) 字…

DDOS攻击防御介绍

DDOS&#xff1a;分布式拒绝服务攻击 瞬间收到大量数据 总带宽是有限的 合法用户访问的时候&#xff0c;被非法方法流量占据 无法溯源 流量清洗&#xff1a;AntiDdos 边界&#xff0c;旁挂的 备用域名&#xff0c;ip更换 机房会提供解决方案 解决不了问题&#xff0c;就干…

【真实体会】花几百块买ChatGPT4.0账号一年值得吗?

GPT4.0使用体验及价值 性能提升: GPT4比GPT3.5在内容质量和数量上有显著提高&#xff0c;使得知乎等平台的收益增加。 功能丰富: GPT4支持文本、图片、文件问答&#xff0c;而GPT3.5仅支持文本。GPT4内置多种专业工具&#xff08;GPTS&#xff09;&#xff0c;如设计师LOGO的A…

Android Studio实现内容丰富的安卓视频管理平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号081 1. 开发环境 android stuido 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.本地视频 3.视频播放 4.收藏功能 5.网路视频 6.个人中心 7.我的收藏 8.浏览历史 3.系…

Redis高阶使用消息队列分布式锁排行榜等

一、前言 在大多数传统的web系统中&#xff0c;使用Redis一般都是作为缓存使用&#xff0c;在大数据查询时作为缓解性能的一种解决方案。博主的的系统中使用Redis也主要使用到缓存的作用&#xff0c;还有做了注册中心&#xff0c;分布式事务。其他的强大的功能&#xff0c;没有…

【哈希表】算法例题

目录 五、哈希表 39. 赎金信 ① 40. 同构字符串 ① 41. 单词规律 ① 42. 有效的字母异位词 ① 43. 字母异位词分组 ② 44. 两数之和 ① 45. 快乐数 ① 46. 存在重复元素 ① 47. 最长连续序列 ② 五、哈希表 39. 赎金信 ① 给你两个字符串&#xff1a;ransomNote 和 m…

Linux课程_____网络管理

一、查看接口信息 1. ifconfig 查看所有活动网络接口的信息 ifconfig -a 查看所有网络接口信息 ifconfig 直接加网络接口 查看指定网络接口信息 1.1查看指定接口IP [rootlocalhost ~]# ip addr show ens160 1.2设置网络接口的IP地址 # ifconfig eth0 192.168.152.133 …

全国各省市县统计年鉴/中国环境统计年鉴/中国工业企业数据库/中国专利数据库/污染排放数据库

统计年鉴是指以统计图表和分析说明为主&#xff0c;通过高度密集的统计数据来全面、系统、连续地记录年度经济、社会等各方面发展情况的大型工具书来获取统计数据资料。 统计年鉴是进行各项经济、社会研究的必要前提。而借助于统计年鉴&#xff0c;则是研究者常用的途径。目前国…