管理端:
用户端:
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。
项目中将前端静态资源部署到nginx上。
1. 版本号:1.20.2。
2. nginx.exe所在目录必须为非中文目录,且目录中不包含空格。
3. 将静态资源放在新建html目录下。(目录结构)
4. 修改nginx.conf配置文件:
(1)修改默认访问页面。
server {
# 监听端口为80,即nginx服务器默认端口
listen 80;
# 服务器名
server_name localhost;
# 静态资源定位,当访问http://localhost:80时,会定位到/html/sky目录下的index.html页面,不配置的话,只会默认访问到nginx的欢迎页面,即/html下的index.html页面。
location / {
root html/sky;
index index.html index.htm;
}
}
(2)设置反向代理相关配置。
# 反向代理到的服务集群
upstream webservers{
# 设置服务器IP,端口信息
server 127.0.0.1:8080 weight=90;
# server 127.0.0.1:8088 weight=10; 可由权重改变负载均衡,只有一个服务器的情况下,配置不生效。(详细可见nginx负载均衡策略)
}
# 反向代理,处理管理端发送的请求
location /api/ { # 拦截以/api开头地址
# 设置proxy_pass值为上面配置的对应服务器,加上访问路径。
proxy_pass http://localhost:8080/admin/;
#proxy_pass http://webservers/admin/; 可由webservers代替
}
若此时浏览器通过http://localhost/api/employee/login访问nginx服务器,即可以http://localhost:8080/admin/employee/login的url定位到tomcat服务器对应的地址。
5. 双击nginx.exe即可开启nginx服务。
6. 可在任务管理器里面关闭nginx进程,从而关闭nginx服务。
nginx 反向代理的好处:
提高访问速度
因为nginx本身可以进行缓存,如果访问的同一接口,并且做了数据缓存,nginx就直接可把数据返回,不需要真正地访问服务端,从而提高访问速度。
进行负载均衡
所谓负载均衡,就是把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器。
保证后端服务安全
因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
注册使用网址:
YApi Pro-高效、易用、功能强大的可视化接口管理平台
为了便于使用,Spring集成了Swagger,使用knife。
1. 在项目的pom.xml文件中导入knife依赖。
com.github.xiaoymin
knife4j-spring-boot-starter
2. 在配置类中加入 knife4j 相关配置。
/**
* 配置类,注册web层相关组件
*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
/**
* 通过knife4j生成接口文档
* @return
*/
@Bean
public Docket docket() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.select()
// 指定生成接口需要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
/**
* 设置静态资源映射, 主要是访问接口文档(html/css/js)
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
3. 通过http://localhost:8080/doc.html地址访问。
主要用于身份验证。
生成方法:
//登录成功后,生成jwt令牌
Map claims = new HashMap<>();
claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
String token = JwtUtil.createJWT(
jwtProperties.getAdminSecretKey(),
jwtProperties.getAdminTtl(),
claims);
EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
.id(employee.getId())
.userName(employee.getUsername())
.name(employee.getName())
.token(token)
.build();
jwt工具类:
public class JwtUtil {
/**
* 生成jwt
* 使用Hs256算法, 私匙使用固定秘钥
*
* @param secretKey jwt秘钥
* @param ttlMillis jwt过期时间(毫秒)
* @param claims 设置的信息
* @return
*/
public static String createJWT(String secretKey, long ttlMillis, Map claims) {
// 指定签名的时候使用的签名算法,也就是header那部分
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 生成JWT的时间
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
// 设置jwt的body
JwtBuilder builder = Jwts.builder()
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
.setClaims(claims)
// 设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
// 设置过期时间
.setExpiration(exp);
return builder.compact();
}
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @param token 加密后的token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
// 设置需要解析的jwt
.parseClaimsJws(token).getBody();
return claims;
}
}
在实体类上加了@Builder注解后,即可用该方法创建对象。
使用@ConfigurationProperties注解,加上属性值(prefix = "sky.jwt")
如以下配置:
yml文件
sky:
jwt:
# 设置jwt签名加密时使用的秘钥
admin-secret-key: itcast
# 设置jwt过期时间
admin-ttl: 7200000
# 设置前端传递过来的令牌名称
admin-token-name: token
配置类
@Component
// 以sky.jwt为前缀,匹配对应的配置参数
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {
/**
* 管理端员工生成jwt令牌相关配置
*/
private String adminSecretKey;
private long adminTtl;
private String adminTokenName;
// 当yml文件中以-来连接各单词时,配置类默认以驼峰命名匹配属性值。
}
定义异常的基类。
package com.sky.exception;
/**
* 业务异常
*/
public class BaseException extends RuntimeException {
public BaseException() {
}
public BaseException(String msg) {
super(msg);
}
}
再根据业务需求,定义各类异常,继承异常的基类做具体处理。
利用@RestControllerAdvice和@ExceptionHandler进行全局异常处理。
/**
* 全局异常处理器,处理项目中抛出的业务异常
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 捕获业务异常
* @param ex
* @return
*/
@ExceptionHandler
public Result exceptionHandler(BaseException ex){
log.error("异常信息:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
}