feat(新增): knife4j无法访问问题,将排出选项放入配置文件中

This commit is contained in:
bunny 2024-03-23 14:35:02 +08:00
parent 5bcd1428c2
commit 56f7d4a8a5
26 changed files with 201 additions and 61 deletions

View File

@ -11,7 +11,7 @@
<packaging>jar</packaging>
<name>common-service</name>
<url>http://maven.apache.org</url>
<url>https://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -34,5 +34,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>common-util</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,15 @@
package com.atguigu.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
@Configuration
@Slf4j
public class ResourceConfiguration extends WebMvcConfiguration {
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("ResourceConfiguration===>设置静态资源映射......");
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@ -1,22 +1,71 @@
package com.atguigu.config;
import com.atguigu.constant.LocalDateTimeConstant;
import com.atguigu.interceptor.LoginAuthInterceptor;
import com.atguigu.json.JacksonObjectMapper;
import com.atguigu.properties.InterceptorsProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.text.SimpleDateFormat;
import java.util.List;
@Component
public class WebMvcConfiguration implements WebMvcConfigurer {
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired
private LoginAuthInterceptor loginAuthInterceptor;
@Autowired
private InterceptorsProperties interceptorsProperties;
/**
* * 解决跨域
*
* @param registry 跨域注册表
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
protected void addCorsMappings(CorsRegistry registry) {
log.info("开始跨域注册表...");
registry.addMapping("/**")// 添加路径规则
.allowCredentials(true)// 是否允许在跨域的情况下传递Cookie
.allowedOriginPatterns("*")// 允许请求来源的域规则
.allowedMethods("*")
.allowedHeaders("*");// 允许所有的请求头
.allowedMethods("*").allowedHeaders("*");// 允许所有的请求头
}
/**
* 注册自定义拦截器
*
* @param registry InterceptorRegistry
*/
protected void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
// 需要拦截的
String[] addPathPatters = {"/admin/**"};
registry.addInterceptor(loginAuthInterceptor).addPathPatterns(addPathPatters)
.excludePathPatterns(interceptorsProperties.getNoAuthUrls());
System.out.println(interceptorsProperties.getNoAuthUrls());
}
/**
* 扩展Spring MVC框架的消息转化器
*
* @param converters 转换器
*/
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器...");
// 创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 需要为消息转换器设置一个对象转换器对象转换器可以将Java对象序列化为json数据
converter.setObjectMapper(new JacksonObjectMapper());
// 添加条件判断只应用于特定的请求路径
converter.getObjectMapper().setDateFormat(new SimpleDateFormat(LocalDateTimeConstant.DEFAULT_DATE_TIME_SECOND_FORMAT));
// 将自己的消息转化器加入容器中
converters.add(converter);
}
}

View File

@ -0,0 +1,83 @@
package com.atguigu.interceptor;
import com.alibaba.fastjson.JSON;
import com.atguigu.context.BaseContext;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.result.Result;
import com.atguigu.spzx.model.vo.result.ResultCodeEnum;
import com.atguigu.utils.InterceptorUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;
@Configuration
@Slf4j
public class LoginAuthInterceptor implements HandlerInterceptor {
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Override
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
String method = request.getMethod();
String token = request.getHeader("token");
// 判断当前拦截到的是Controller方法还是其它资源
if ("OPTIONS".equals(method) || !(handler instanceof HandlerMethod)) return true;
// 当前token为空
if (StringUtils.isEmpty(token)) {
InterceptorUtil.unLoginInterceptor(response);
return false;
}
// 获取用户信息不存在
String userinfoString = (String) redisTemplate.opsForValue().get(token);
if (StringUtils.isEmpty(userinfoString)) {
InterceptorUtil.unLoginInterceptor(response);
return false;
}
// 将用户信息放到ThreadLocal中
SysUser sysUser = JSON.parseObject(userinfoString, SysUser.class);
BaseContext.setSysUser(sysUser);
// 更新Redis过期时间
redisTemplate.expire(token, 7, TimeUnit.DAYS);
// 放行
return true;
}
/**
* 请求完成后删除ThreadLocal
*/
@Override
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, @Nullable Exception ex) throws Exception {
log.info("删除ThreadLocal...");
BaseContext.removeSysUser();
}
// 响应208状态码给前端
private void responseNoLoginInfo(HttpServletResponse response) {
Result<ResultCodeEnum> result = Result.error(ResultCodeEnum.LOGIN_AUTH);
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
try (PrintWriter writer = response.getWriter()) {
writer.print(JSON.toJSONString(result));
} catch (IOException e) {
log.error("出错了===>{}", e.getMessage());
}
}
}

View File

@ -24,6 +24,11 @@
<artifactId>spzx-model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>com.atguigu</groupId> -->
<!-- <artifactId>common-service</artifactId> -->
<!-- <version>1.0-SNAPSHOT</version> -->
<!-- </dependency> -->
<!-- Spring-Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -40,10 +45,5 @@
<artifactId>minio</artifactId>
<version>8.5.9</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -24,6 +24,12 @@
<artifactId>common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>common-util</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- spring boot web开发所需要的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -54,11 +60,5 @@
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>common-util</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,5 +1,6 @@
package com.atguigu.spzx.manger.controller;
import com.atguigu.context.BaseContext;
import com.atguigu.spzx.manger.service.SysUserService;
import com.atguigu.spzx.manger.service.ValidateCodeService;
import com.atguigu.spzx.model.dto.system.LoginDto;
@ -37,8 +38,8 @@ public class IndexController {
@Operation(summary = "获取登录用户信息", description = "获取当前登录用户信息")
@GetMapping("getUserInfo")
public Result<SysUser> getUserInfo(@RequestHeader(name = "token") String token) {
SysUser sysUser = sysUserService.getUserInfo(token);
public Result<SysUser> getUserInfo() {
SysUser sysUser = BaseContext.getSysUser();
return Result.success(sysUser);
}

View File

@ -1,7 +1,6 @@
package com.atguigu.spzx.manger.service;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.system.LoginVo;
public interface SysUserService {
@ -13,14 +12,6 @@ public interface SysUserService {
*/
LoginVo login(LoginDto loginDto);
/**
* * 获取当前登录用户信息
*
* @param token token值
* @return 用户信息
*/
SysUser getUserInfo(String token);
/**
* * 用户退出接口
*

View File

@ -1,13 +1,14 @@
package com.atguigu.spzx.manger.service.impl;
import com.alibaba.fastjson.JSON;
import com.atguigu.constant.ExceptionConstant;
import com.atguigu.exception.BunnyException;
import com.atguigu.exception.EnumException;
import com.atguigu.lib.MD5;
import com.atguigu.spzx.manger.mapper.SysUserMapper;
import com.atguigu.spzx.manger.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.system.LoginVo;
import com.atguigu.utils.MD5;
import com.atguigu.utils.StringEmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
@ -40,50 +41,36 @@ public class SysUserServiceImpl implements SysUserService {
String key = loginDto.getCodeKey();
// 得到Redis中验证码
String code = (String) redisTemplate.opsForValue().get(key);
stringEmptyUtil.isEmpty(userName, EnumException.USERNAME_IS_EMPTY);
stringEmptyUtil.isEmpty(password, EnumException.PASSWORD_IS_EMPTY);
stringEmptyUtil.isEmpty(captcha, EnumException.CAPTCHA_IS_EMPTY);
stringEmptyUtil.isEmpty(key, EnumException.KEY_IS_EMPTY);
stringEmptyUtil.isEmpty(code, EnumException.VERIFICATION_CODE_IS_EMPTY);
stringEmptyUtil.isEmpty(userName, ExceptionConstant.USERNAME_IS_EMPTY);
stringEmptyUtil.isEmpty(password, ExceptionConstant.PASSWORD_IS_EMPTY);
stringEmptyUtil.isEmpty(captcha, ExceptionConstant.CAPTCHA_IS_EMPTY);
stringEmptyUtil.isEmpty(key, ExceptionConstant.KEY_IS_EMPTY);
stringEmptyUtil.isEmpty(code, ExceptionConstant.VERIFICATION_CODE_IS_EMPTY);
// 验证码不匹配
assert code != null;
if ((!Objects.equals(code.toLowerCase(), captcha.toLowerCase()))) {
throw new BunnyException(EnumException.VERIFICATION_CODE_DOES_NOT_MATCH);
throw new BunnyException(ExceptionConstant.VERIFICATION_CODE_DOES_NOT_MATCH);
}
// 比较完成后删除验证码
redisTemplate.delete(key);
// 根据username查询用户信息
SysUser sysUser = sysUserMapper.selectByUsername(userName);
if (sysUser == null) {
throw new BunnyException(EnumException.USER_NOT_FOUND);
throw new BunnyException(ExceptionConstant.USER_NOT_FOUND);
}
String encryptedPassword = MD5.encrypt(password);
// 比较密码
if (!encryptedPassword.equals(sysUser.getPassword())) {
throw new BunnyException(EnumException.PASSWORD_ERROR);
throw new BunnyException(ExceptionConstant.PASSWORD_ERROR);
}
// 登录成功
String token = UUID.randomUUID().toString().replaceAll("-", "");
redisTemplate.opsForValue().set(token, userName, 7, TimeUnit.DAYS);
redisTemplate.opsForValue().set(token, JSON.toJSONString(sysUser), 7, TimeUnit.DAYS);
// 返回loginVo对象
return LoginVo.builder().token(token).build();
}
/**
* * 获取当前登录用户信息
*
* @param token token值
* @return 用户信息
*/
@Override
public SysUser getUserInfo(String token) {
String username = (String) redisTemplate.opsForValue().get(token);
SysUser sysUser = sysUserMapper.selectByUsername(username);
sysUser.setPassword("******");
return sysUser;
}
/**
* * 用户退出接口
*

View File

@ -30,7 +30,7 @@ public class ValidateCodeServiceImpl implements ValidateCodeService {
// 2. 验证码存储到Redis中Redis的key为UUID值为验证码的值
String key = UUID.randomUUID().toString();
// 3. 返回ValidateCodeVo
redisTemplate.opsForValue().set(key, code, 1, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(key, code, 10, TimeUnit.MINUTES);
return ValidateCodeVo.builder().codeKey(key).codeValue(base64Image).build();
}
}

View File

@ -11,6 +11,11 @@ bunny:
port: 6379
database: 2
spzx:
noAuthUrls:
- /admin/system/index/login
- /admin/system/index/generateValidateCode
# jackson:
# date-format: yyyy-MM-dd HH:mm:ss
# time-zone: GMT+8

View File

@ -11,6 +11,11 @@ bunny:
port: 6379
database: 2
spzx:
noAuthUrls:
- /admin/system/index/login
- /admin/system/index/generateValidateCode
# jackson:
# date-format: yyyy-MM-dd HH:mm:ss
# time-zone: GMT+8

View File

@ -1,4 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>

View File

@ -1,6 +1,5 @@
package com.atguigu.spzx.model.entity.base;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -13,15 +12,14 @@ public class BaseEntity implements Serializable {
@Schema(description = "唯一标识")
private Long id;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "修改时间")
private Date updateTime;
@Schema(description = "是否删除")
private Integer isDeleted;
}

View File

@ -12,7 +12,7 @@ public enum ResultCodeEnum {
USE_NOT_EXIST(500, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
LOGIN_AUTH(208, "登陆"),
LOGIN_AUTH(208, "需要先登陆"),
LOGIN_MOBLE_ERROR(208, "登录验证失败"),
ACCOUNT_DEACTIVATION(208, "账户停用"),
PERMISSION(209, "没有权限");