From 54c0542870d6e501e1bd16a9c1739e76a685634a Mon Sep 17 00:00:00 2001 From: ytChen <1650611030@qq.com> Date: Thu, 7 Mar 2024 09:58:08 +0800 Subject: [PATCH] saas --- .../admin/boot/aspect/WebLogAspect.java | 8 + .../admin/boot/config/InterceptConfig.java | 7 +- .../admin/boot/filter/RequestWrapper.java | 7 + .../boot/interceptor/JwtInterceptor.java | 25 +++- .../auth/controller/AuthController.java | 6 +- .../common/base/result/ResultCode.java | 3 + .../recovery/order/aspect/WebLogAspect.java | 85 +++++++++++ .../com/recovery/order/config/CorsConfig.java | 36 +++++ .../order/config/InterceptConfig.java | 30 ++++ .../order/config/ds/DataSourceConfig.java | 95 ++++++++++++ .../config/ds/TeachingDataSourceConfig.java | 58 ++++++++ .../order/controller/testController.java | 31 ++++ .../order/exception/BusinessException.java | 38 +++++ .../exception/GlobalExceptionHandler.java | 38 +++++ .../recovery/order/filter/RequestWrapper.java | 140 ++++++++++++++++++ .../order/interceptor/JwtInterceptor.java | 96 ++++++++++++ .../listener/InitResourcePermissionCache.java | 27 ++++ .../com/recovery/order/rest/UserRest.java | 17 +++ .../com/recovery/order/util/UserUtil.java | 34 +++++ hoe-order/src/main/resources/bootstrap.yml | 4 +- hoe-order/src/main/resources/logback-bak.xml | 4 +- .../src/main/resources/logback-spring.xml | 2 +- .../src/main/resources/mapper/UserMapper.xml | 12 ++ 23 files changed, 788 insertions(+), 15 deletions(-) create mode 100644 hoe-order/src/main/java/com/recovery/order/aspect/WebLogAspect.java create mode 100644 hoe-order/src/main/java/com/recovery/order/config/CorsConfig.java create mode 100644 hoe-order/src/main/java/com/recovery/order/config/InterceptConfig.java create mode 100644 hoe-order/src/main/java/com/recovery/order/config/ds/DataSourceConfig.java create mode 100644 hoe-order/src/main/java/com/recovery/order/config/ds/TeachingDataSourceConfig.java create mode 100644 hoe-order/src/main/java/com/recovery/order/controller/testController.java create mode 100644 hoe-order/src/main/java/com/recovery/order/exception/BusinessException.java create mode 100644 hoe-order/src/main/java/com/recovery/order/exception/GlobalExceptionHandler.java create mode 100644 hoe-order/src/main/java/com/recovery/order/filter/RequestWrapper.java create mode 100644 hoe-order/src/main/java/com/recovery/order/interceptor/JwtInterceptor.java create mode 100644 hoe-order/src/main/java/com/recovery/order/listener/InitResourcePermissionCache.java create mode 100644 hoe-order/src/main/java/com/recovery/order/rest/UserRest.java create mode 100644 hoe-order/src/main/java/com/recovery/order/util/UserUtil.java create mode 100644 hoe-order/src/main/resources/mapper/UserMapper.xml diff --git a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/aspect/WebLogAspect.java b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/aspect/WebLogAspect.java index 7dc2273..1682e07 100644 --- a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/aspect/WebLogAspect.java +++ b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/aspect/WebLogAspect.java @@ -23,6 +23,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import java.net.MalformedURLException; import java.net.URL; /** @@ -54,6 +55,8 @@ public class WebLogAspect { StringBuffer urlBuf = request.getRequestURL(); URL url = new URL(urlBuf.toString()); String path = url.getPath(); + log.info("获取请求地址:" + path); + log.info("获取请求ip:" + getIPAddress(request)); HttpServletResponse response = (HttpServletResponse)attributes.getResponse(); String hospitalHost = request.getHeader("hospitalHost"); // if(StringUtils.isEmpty(hospitalHost)){ @@ -72,6 +75,11 @@ public class WebLogAspect { HspHostUtil.switchDB(hospitalHost,"admin",stringRedisTemplate); } + public String getIPAddress(HttpServletRequest request) { + String ipAddress = request.getRemoteAddr(); + return ipAddress; + } + //执行完切面后,将线程共享中的数据源名称清空 @After("webLog()") public void after(JoinPoint joinPoint){ diff --git a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/InterceptConfig.java b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/InterceptConfig.java index 092ef34..d24c8a9 100644 --- a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/InterceptConfig.java +++ b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/InterceptConfig.java @@ -2,17 +2,22 @@ package com.recovery.admin.boot.config; import com.recovery.admin.boot.interceptor.JwtInterceptor; +import com.recovery.common.base.util.RedisUtil; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import javax.annotation.Resource; + @Configuration public class InterceptConfig implements WebMvcConfigurer { + @Resource + RedisUtil redisUtil; @Override public void addInterceptors(InterceptorRegistry registry) { //添加拦截器 - registry.addInterceptor(new JwtInterceptor()) + registry.addInterceptor(new JwtInterceptor(redisUtil)) //拦截的路径 需要进行token验证的路径 .addPathPatterns("/**") //放行的路径 diff --git a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/filter/RequestWrapper.java b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/filter/RequestWrapper.java index 20ad03c..4d8a7d3 100644 --- a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/filter/RequestWrapper.java +++ b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/filter/RequestWrapper.java @@ -71,6 +71,7 @@ public class RequestWrapper extends HttpServletRequestWrapper { StringBuffer urlBuf = req.getRequestURL(); try { logger.info("获取请求地址:" + new URL(urlBuf.toString()).getPath()); + logger.info("获取请求ip:" + getIPAddress(req)); } catch (MalformedURLException e) { throw new RuntimeException(e); } @@ -78,6 +79,12 @@ public class RequestWrapper extends HttpServletRequestWrapper { return sb.toString(); } + public String getIPAddress(HttpServletRequest request) { + String ipAddress = request.getRemoteAddr(); + return ipAddress; + } + + /** * @date: 2023/2/6 12:46 * @author: zhouzhaodong diff --git a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/interceptor/JwtInterceptor.java b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/interceptor/JwtInterceptor.java index 1afc8e4..a032c55 100644 --- a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/interceptor/JwtInterceptor.java +++ b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/interceptor/JwtInterceptor.java @@ -8,6 +8,7 @@ import com.recovery.admin.boot.exception.BusinessException; import com.recovery.admin.boot.filter.RequestWrapper; import com.recovery.common.base.constant.Constants; import com.recovery.common.base.result.ResultCode; +import com.recovery.common.base.util.RedisUtil; import com.recovery.common.base.utils.JwtUtils; import lombok.extern.slf4j.Slf4j; @@ -15,6 +16,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -23,18 +25,29 @@ import java.util.HashMap; @Slf4j public class JwtInterceptor implements HandlerInterceptor { + + @Resource + RedisUtil redisUtil; + + public JwtInterceptor(RedisUtil redisUtil) { + this.redisUtil = redisUtil; + } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HashMap map=new HashMap<>(); - //获取请求参数 - RequestWrapper requestWrapper = new RequestWrapper(request); - //这里getBodyString()方法无参数 - log.info("RequestBody: {}", requestWrapper.getBodyString()); +// //获取请求参数 +// RequestWrapper requestWrapper = new RequestWrapper(request); +// //这里getBodyString()方法无参数 +// log.info("RequestBody: {}", requestWrapper.getBodyString()); //从http请求头获取token - String token = requestWrapper.getHeader(Constants.LOGIN_USRE_TOKEN); + String token = request.getHeader(Constants.LOGIN_USRE_TOKEN); if (StringUtils.isEmpty(token)) { - throw new BusinessException(ResultCode.TOKEN_INVALID_OR_EXPIRED); + throw new BusinessException(ResultCode.LOGIN_ERROR); + } + boolean rest = redisUtil.hasKey("userToken:" +token); + if (!rest) { + throw new BusinessException(ResultCode.LOGIN_EXPIRE_ERROR); } //把变量放在request请求域中,仅可以被这次请求,即同一个requerst使用 request.setAttribute(Constants.LOGIN_USRE_TOKEN,token); diff --git a/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java b/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java index ae5ff67..c99d74f 100644 --- a/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java +++ b/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java @@ -48,8 +48,8 @@ public class AuthController { // @GetMapping("/public-key") // public Map getPublicKey() { -// RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); -// RSAKey key = new RSAKey.Builder(publicKey).build(); -// return new JWKSet(key).toJSONObject(); +// //单例模式 +// +// return “吃啥; // } } diff --git a/hoe-common/common-base/src/main/java/com/recovery/common/base/result/ResultCode.java b/hoe-common/common-base/src/main/java/com/recovery/common/base/result/ResultCode.java index c142291..7b8632a 100644 --- a/hoe-common/common-base/src/main/java/com/recovery/common/base/result/ResultCode.java +++ b/hoe-common/common-base/src/main/java/com/recovery/common/base/result/ResultCode.java @@ -19,6 +19,9 @@ import java.io.Serializable; public enum ResultCode implements IResultCode, Serializable { SUCCESS("200", "成功"), + LOGIN_ERROR("1001", "未登录"), + + LOGIN_EXPIRE_ERROR("1002", "登录过期,请重新登录!"), SYSTEM_EXECUTION_ERROR("999999", "系统执行出错"), USERNAME_OR_PASSWORD_ERROR("A00100", "用户名或密码错误"), USER_NOT_EXIST("A00101", "用户不存在"), diff --git a/hoe-order/src/main/java/com/recovery/order/aspect/WebLogAspect.java b/hoe-order/src/main/java/com/recovery/order/aspect/WebLogAspect.java new file mode 100644 index 0000000..3af2fe2 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/aspect/WebLogAspect.java @@ -0,0 +1,85 @@ +package com.recovery.order.aspect; + + +import com.recovery.common.base.ds.DataSourceContextHolder; +import com.recovery.common.base.util.HspHostUtil; +import com.recovery.common.base.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.net.URL; + +/** + * Web层日志切面 + * + * @author RyanWang + * @version 1.0.0 + * @date 16/5/17 上午10:42. + */ +@Aspect +@Order(0) +@Slf4j +@Component +public class WebLogAspect { + @Resource + private StringRedisTemplate stringRedisTemplate; +// + @Pointcut("execution(public * com.recovery.order.controller..*.*(..)) || execution(public * com.recovery.order.rest.*.*(..))") + public void webLog(){} + + @Before("webLog()") + public void doBefore(JoinPoint joinPoint) throws Throwable { + + // 接收到请求,记录请求内容 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + //获取请求的域名 + HttpServletRequest request = attributes.getRequest(); + // 根据域名获取网站信息 + StringBuffer urlBuf = request.getRequestURL(); + URL url = new URL(urlBuf.toString()); + String path = url.getPath(); + log.info("获取请求地址:" + path); + log.info("获取请求ip:" + getIPAddress(request)); + HttpServletResponse response = (HttpServletResponse)attributes.getResponse(); + String hospitalHost = request.getHeader("hospitalHost"); +// if(StringUtils.isEmpty(hospitalHost)){ +// return; +// } + + //切割获取访问目标模块 + String[] split = path.split("/"); + String module = split[0]; + log.info("切换库:"+RedisUtils.getDBInfoByHostAndModule(stringRedisTemplate,hospitalHost,"order")); + //根据域名和请求的模块名查询目标数据库 + HttpSession session = request.getSession(); + /** + * 切换为动态数据源实例 + */ + HspHostUtil.switchDB(hospitalHost,"order",stringRedisTemplate); + + } + public String getIPAddress(HttpServletRequest request) { + String ipAddress = request.getRemoteAddr(); + return ipAddress; + } + + //执行完切面后,将线程共享中的数据源名称清空 + @After("webLog()") + public void after(JoinPoint joinPoint){ + DataSourceContextHolder.clearDBType(); + } +} + diff --git a/hoe-order/src/main/java/com/recovery/order/config/CorsConfig.java b/hoe-order/src/main/java/com/recovery/order/config/CorsConfig.java new file mode 100644 index 0000000..dbb8a7f --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/config/CorsConfig.java @@ -0,0 +1,36 @@ +package com.recovery.order.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +//跨越请求配置类 +@Configuration +public class CorsConfig { + + private CorsConfiguration buildConfig() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + // 你需要跨域的地址 注意这里的 127.0.0.1 != localhost + // * 表示对所有的地址都可以访问 + corsConfiguration.addAllowedOrigin("*"); // 1 + // 跨域的请求头 + corsConfiguration.addAllowedHeader("*"); // 2 + // 跨域的请求方法 + corsConfiguration.addAllowedMethod("*"); // 3 + //加上了这一句,大致意思是可以携带 cookie + //最终的结果是可以 在跨域请求的时候获取同一个 session + corsConfiguration.setAllowCredentials(true); + return corsConfiguration; + } + @Bean + public CorsFilter corsFilter() { + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + //配置 可以访问的地址 + source.registerCorsConfiguration("/**", buildConfig()); + return new CorsFilter(source); + } + +} diff --git a/hoe-order/src/main/java/com/recovery/order/config/InterceptConfig.java b/hoe-order/src/main/java/com/recovery/order/config/InterceptConfig.java new file mode 100644 index 0000000..da1dd73 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/config/InterceptConfig.java @@ -0,0 +1,30 @@ +package com.recovery.order.config; + + +import com.recovery.admin.boot.interceptor.JwtInterceptor; +import com.recovery.common.base.util.RedisUtil; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; + + +@Configuration +public class InterceptConfig implements WebMvcConfigurer { + @Resource + RedisUtil redisUtil; + @Override + public void addInterceptors(InterceptorRegistry registry) { + //添加拦截器 + registry.addInterceptor(new JwtInterceptor(redisUtil)) + //拦截的路径 需要进行token验证的路径 + .addPathPatterns("/**") + //放行的路径 + .excludePathPatterns("/api/rest/users/getUserByUsername") + .excludePathPatterns("/api/user/sendMsg") + .excludePathPatterns("/api/user/loginPhone") + //放行swagger 测试验证 + .excludePathPatterns("/api/user/get"); + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/config/ds/DataSourceConfig.java b/hoe-order/src/main/java/com/recovery/order/config/ds/DataSourceConfig.java new file mode 100644 index 0000000..62a7df3 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/config/ds/DataSourceConfig.java @@ -0,0 +1,95 @@ +package com.recovery.order.config.ds; + +import com.alibaba.druid.pool.DruidDataSource; +import com.recovery.common.base.ds.DynamicDataSource; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by YHYR on 2017-12-25 + */ +@Slf4j +@Configuration +@MapperScan(basePackages = DataSourceConfig.PACKAGE, sqlSessionFactoryRef = "commonSqlSessionFactory") +public class DataSourceConfig { + + // 精确到模块目录,以便跟其他数据源隔离 + static final String PACKAGE = "com.recovery.admin.boot.mapper"; + static final String MAPPER_LOCATION = "classpath:mapper/*.xml"; + + @Value("${master.datasource.url}") + private String masterDBUrl; + + @Value("${master.datasource.username}") + private String masterDBUser; + + @Value("${master.datasource.password}") + private String masterDBPassword; + + @Value("${master.datasource.driverClassName}") + private String masterDBDreiverName; + + + @Bean(name = "commonDataSource") + @Primary + public DynamicDataSource dynamicDataSource(){ + DynamicDataSource dynamicDataSource = DynamicDataSource.getInstance(); + + DruidDataSource masterDataSource = new DruidDataSource(); + try { + masterDataSource.setUrl(masterDBUrl); + masterDataSource.setUsername(masterDBUser); + masterDataSource.setPassword(masterDBPassword); + masterDataSource.setDriverClassName(masterDBDreiverName); + }catch (Exception e){ + log.error(e.getMessage()); + } + + Map map = new HashMap<>(); + map.put("master", masterDataSource); + dynamicDataSource.setTargetDataSources(map); + + return dynamicDataSource; + } + + @Bean(name = "commonSqlSessionFactory") + @Primary + public SqlSessionFactory sqlSessionFactory( + @Qualifier("commonDataSource") DataSource dynamicDataSource) + throws Exception { + SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); + bean.setDataSource(dynamicDataSource); + bean.setMapperLocations(new PathMatchingResourcePatternResolver() + .getResources(DataSourceConfig.MAPPER_LOCATION)); + return bean.getObject(); + + } + + @Bean(name = "commonTransactionManager") + @Primary + public DataSourceTransactionManager commonTransactionManager() { + return new DataSourceTransactionManager(dynamicDataSource()); + } + + + @Bean(name = "commonSqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate( + @Qualifier("commonSqlSessionFactory") SqlSessionFactory sqlSessionFactory) + throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/config/ds/TeachingDataSourceConfig.java b/hoe-order/src/main/java/com/recovery/order/config/ds/TeachingDataSourceConfig.java new file mode 100644 index 0000000..85217c6 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/config/ds/TeachingDataSourceConfig.java @@ -0,0 +1,58 @@ +package com.recovery.order.config.ds; + +import com.alibaba.druid.pool.DruidDataSource; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +//@Configuration +//// 扫描 Mapper 接口并容器管理 +//@MapperScan(basePackages = TeachingDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "teachingSqlSessionFactory") +public class TeachingDataSourceConfig { + // 精确到 course 目录,以便跟其他数据源隔离 + static final String PACKAGE = "com.recovery.order.mapper"; + static final String MAPPER_LOCATION = "classpath:mapper/*.xml"; + + @Value("${admin.datasource.url}") + private String url; + + @Value("${admin.datasource.username}") + private String user; + + @Value("${admin.datasource.password}") + private String password; + + @Value("${admin.datasource.driverClassName}") + private String driverClass; + + @Bean(name = "adminDataSource") + public DataSource cpdDataSource() { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setDriverClassName(driverClass); + dataSource.setUrl(url); + dataSource.setUsername(user); + dataSource.setPassword(password); + return dataSource; + } + + @Bean(name = "adminTransactionManager") + public DataSourceTransactionManager courseTransactionManager() { + return new DataSourceTransactionManager(cpdDataSource()); + } + + @Bean(name = "adminSqlSessionFactory") + public SqlSessionFactory cpdSqlSessionFactory(@Qualifier("adminDataSource") DataSource cpdDataSource) + throws Exception { + final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(cpdDataSource); + sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() + .getResources(TeachingDataSourceConfig.MAPPER_LOCATION)); + return sessionFactory.getObject(); + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/controller/testController.java b/hoe-order/src/main/java/com/recovery/order/controller/testController.java new file mode 100644 index 0000000..b757004 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/controller/testController.java @@ -0,0 +1,31 @@ +package com.recovery.order.controller; + + +import com.recovery.common.base.result.ApiResult; +import com.recovery.common.base.util.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +@RestController +@RequestMapping("/api/v1/test") +@Slf4j +public class testController { + + @Resource + RedisUtil redisUtil; + + /** + * cs + */ + @GetMapping("/cs") + public ApiResult cs(@RequestParam String name, HttpServletRequest request) { + + return ApiResult.ok("cs"); + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/exception/BusinessException.java b/hoe-order/src/main/java/com/recovery/order/exception/BusinessException.java new file mode 100644 index 0000000..5771df4 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/exception/BusinessException.java @@ -0,0 +1,38 @@ +package com.recovery.order.exception; + + + +import com.recovery.common.base.result.IResultCode; +import lombok.Data; + + +/** + * 自定义异常类 + */ +@Data +public class BusinessException extends RuntimeException{ + + private String code; + + private String msg; + + + public BusinessException(IResultCode apiCode) { + super(apiCode.getMsg()); + this.code = apiCode.getCode(); + this.msg = apiCode.getMsg(); + } + + public BusinessException(String code, String message) { + super(code+":"+message); + this.code = code; + this.msg = message; + } + + public BusinessException(String message) { + super("5001"+":"+message); + this.code = "5001"; + this.msg = message; + } + +} diff --git a/hoe-order/src/main/java/com/recovery/order/exception/GlobalExceptionHandler.java b/hoe-order/src/main/java/com/recovery/order/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..cd58578 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/exception/GlobalExceptionHandler.java @@ -0,0 +1,38 @@ +package com.recovery.order.exception; + + +import com.recovery.common.base.result.ApiResult; +import com.recovery.common.base.result.ResultCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理 + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + //自定义异常 + @ExceptionHandler(BusinessException.class) + public ApiResult systemExceptionHandler(BusinessException e) { + log.error("BusinessException全局异常:{}",e); + return ApiResult.failed(e.getCode(), e.getMsg()); + } + + //系统异常 + @ExceptionHandler(Exception.class) + public ApiResult exceptionHandler(Exception e) { + log.error("Exception全局异常:{}",e); + return ApiResult.failed(ResultCode.SYSTEM_EXECUTION_ERROR.getCode(), e.getMessage()); + } + + //Security +// @ExceptionHandler(value = AccessDeniedException.class) +// public void accessDeniedException(AccessDeniedException e) { +// throw e; +// } + + +} diff --git a/hoe-order/src/main/java/com/recovery/order/filter/RequestWrapper.java b/hoe-order/src/main/java/com/recovery/order/filter/RequestWrapper.java new file mode 100644 index 0000000..c2b13fa --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/filter/RequestWrapper.java @@ -0,0 +1,140 @@ +package com.recovery.order.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +public class RequestWrapper extends HttpServletRequestWrapper { + private final Logger logger = LoggerFactory.getLogger(RequestWrapper.class); + private final byte[] body; + + public RequestWrapper(HttpServletRequest request) { + super(request); + String sessionStream = getBodyString(request); + body = sessionStream.getBytes(StandardCharsets.UTF_8); + } + + public String getBodyString() { + return new String(body, StandardCharsets.UTF_8); + } + + /** + * @date: 2023/2/6 12:46 + * @author: zhouzhaodong + * @description: 获取请求Body + */ + public String getBodyString(final ServletRequest request) { + StringBuilder sb = new StringBuilder(); + InputStream inputStream = null; + BufferedReader reader = null; + try { + inputStream = cloneInputStream(request.getInputStream()); + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + // 接收到请求,记录请求内容 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + //获取请求的域名 + HttpServletRequest req = attributes.getRequest(); + // 根据域名获取网站信息 + StringBuffer urlBuf = req.getRequestURL(); + try { + logger.info("获取请求地址:" + new URL(urlBuf.toString()).getPath()); + logger.info("获取请求ip:" + getIPAddress(req)); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + logger.info("获取body请求参数:" + sb); + return sb.toString(); + } + + public String getIPAddress(HttpServletRequest request) { + String ipAddress = request.getRemoteAddr(); + return ipAddress; + } + + + /** + * @date: 2023/2/6 12:46 + * @author: zhouzhaodong + * @description: 复制输入流 + */ + public InputStream cloneInputStream(ServletInputStream inputStream) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + try { + while ((len = inputStream.read(buffer)) > -1) { + byteArrayOutputStream.write(buffer, 0, len); + } + byteArrayOutputStream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + } + + @Override + public BufferedReader getReader() { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() { + + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() { + + @Override + public int read() { + return bais.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + }; + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/interceptor/JwtInterceptor.java b/hoe-order/src/main/java/com/recovery/order/interceptor/JwtInterceptor.java new file mode 100644 index 0000000..5c7db61 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/interceptor/JwtInterceptor.java @@ -0,0 +1,96 @@ +package com.recovery.order.interceptor; + + +import com.alibaba.fastjson.JSONObject; +import com.auth0.jwt.interfaces.DecodedJWT; + +import com.recovery.common.base.constant.Constants; +import com.recovery.common.base.result.ResultCode; +import com.recovery.common.base.util.RedisUtil; +import com.recovery.common.base.utils.JwtUtils; +import com.recovery.order.exception.BusinessException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; + +@Slf4j +public class JwtInterceptor implements HandlerInterceptor { + + @Resource + RedisUtil redisUtil; + + public JwtInterceptor(RedisUtil redisUtil) { + this.redisUtil = redisUtil; + } + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + HashMap map=new HashMap<>(); +// //获取请求参数 +// RequestWrapper requestWrapper = new RequestWrapper(request); +// //这里getBodyString()方法无参数 +// log.info("RequestBody: {}", requestWrapper.getBodyString()); + //从http请求头获取token + + String token = request.getHeader(Constants.LOGIN_USRE_TOKEN); + if (StringUtils.isEmpty(token)) { + throw new BusinessException(ResultCode.LOGIN_ERROR); + } + boolean rest = redisUtil.hasKey("userToken:" +token); + if (!rest) { + throw new BusinessException(ResultCode.LOGIN_EXPIRE_ERROR); + } + //把变量放在request请求域中,仅可以被这次请求,即同一个requerst使用 + request.setAttribute(Constants.LOGIN_USRE_TOKEN,token); + try { + //如果验证成功放行请求 + DecodedJWT verify = JwtUtils.verifyToken(token); + return true; + } + catch (Exception exception) + { + throw new BusinessException(ResultCode.TOKEN_INVALID_OR_EXPIRED); + } + } + /** + * @date: 2023/2/6 12:46 + * @author: zhouzhaodong + * @description: 访问控制器方法后执行 + */ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { + log.info(new Date() + "--postHandle:" + request.getRequestURL()); + } + + /** + * @date: 2023/2/6 12:46 + * @author: zhouzhaodong + * @description: postHandle方法执行完成后执行,一般用于释放资源 + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + log.info(new Date() + "--afterCompletion:" + request.getRequestURL()); + } + + public void renderJson(HttpServletResponse response, Object object) { + response.reset(); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Methods", "*"); + response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type"); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + try { + response.getWriter().print(JSONObject.toJSONString(object)); + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/hoe-order/src/main/java/com/recovery/order/listener/InitResourcePermissionCache.java b/hoe-order/src/main/java/com/recovery/order/listener/InitResourcePermissionCache.java new file mode 100644 index 0000000..8251f54 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/listener/InitResourcePermissionCache.java @@ -0,0 +1,27 @@ +package com.recovery.order.listener; + + + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * @author: + */ +@Component +@Slf4j +@AllArgsConstructor +public class InitResourcePermissionCache implements CommandLineRunner { + /** + * 启动时操作 + * @param args + */ + + @Override + public void run(String... args) { + log.info("刷新权限------------------------------"); +// iSysPermissionService.refreshPermRolesRules(); + } +} diff --git a/hoe-order/src/main/java/com/recovery/order/rest/UserRest.java b/hoe-order/src/main/java/com/recovery/order/rest/UserRest.java new file mode 100644 index 0000000..8d24088 --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/rest/UserRest.java @@ -0,0 +1,17 @@ +package com.recovery.order.rest; + + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author: + */ +@RestController +@RequestMapping("/api/rest/users") +@Slf4j +public class UserRest { + + +} diff --git a/hoe-order/src/main/java/com/recovery/order/util/UserUtil.java b/hoe-order/src/main/java/com/recovery/order/util/UserUtil.java new file mode 100644 index 0000000..329aecd --- /dev/null +++ b/hoe-order/src/main/java/com/recovery/order/util/UserUtil.java @@ -0,0 +1,34 @@ +package com.recovery.order.util; + + + +import com.recovery.common.base.constant.Constants; +import com.recovery.common.base.dto.UserAuthorityDto; +import com.recovery.common.base.result.ResultCode; +import com.recovery.common.base.util.RedisUtil; +import com.recovery.order.exception.BusinessException; +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.http.HttpServletRequest; + +@Slf4j +public class UserUtil { + + /** + * 获取登录用户信息 + * @param request + * @param redisUtil + * @return + */ + public static UserAuthorityDto getLoginUserInfo(HttpServletRequest request, RedisUtil redisUtil){ + String loginUserToken = (String) request.getHeader(Constants.LOGIN_USRE_TOKEN); + Boolean rest = redisUtil.hasKey("userToken:" +loginUserToken); + log.info("缓存key:"+"userToken:" +loginUserToken); + log.info("缓存中是否有这条用户:"+rest); + if (!rest) { + throw new BusinessException(ResultCode.TOKEN_INVALID_OR_EXPIRED); + } + UserAuthorityDto userAuthorityDto = (UserAuthorityDto) redisUtil.get("userToken:" +loginUserToken); + return userAuthorityDto; + } +} diff --git a/hoe-order/src/main/resources/bootstrap.yml b/hoe-order/src/main/resources/bootstrap.yml index 53f6548..a4dece1 100644 --- a/hoe-order/src/main/resources/bootstrap.yml +++ b/hoe-order/src/main/resources/bootstrap.yml @@ -1,7 +1,7 @@ spring: application: - name: hoe-order + name: hoe-admin main: allow-bean-definition-overriding: true profiles: @@ -16,7 +16,7 @@ spring: config: server-addr: localhost:8848 file-extension: yaml - prefix: hoe-order + prefix: hoe-admin group: dev namespace: 11bfd099-10d6-4f2c-b969-58b76e435cce server: diff --git a/hoe-order/src/main/resources/logback-bak.xml b/hoe-order/src/main/resources/logback-bak.xml index d895647..76945c1 100644 --- a/hoe-order/src/main/resources/logback-bak.xml +++ b/hoe-order/src/main/resources/logback-bak.xml @@ -43,11 +43,11 @@ - + - + \ No newline at end of file diff --git a/hoe-order/src/main/resources/logback-spring.xml b/hoe-order/src/main/resources/logback-spring.xml index 20a4666..d2f4072 100644 --- a/hoe-order/src/main/resources/logback-spring.xml +++ b/hoe-order/src/main/resources/logback-spring.xml @@ -157,7 +157,7 @@ - + diff --git a/hoe-order/src/main/resources/mapper/UserMapper.xml b/hoe-order/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..fdd9792 --- /dev/null +++ b/hoe-order/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,12 @@ + + + + + + +