From 2a9c95df5ae288d4162d3eceefe839da126556b0 Mon Sep 17 00:00:00 2001 From: LiShu <2945621619@qq.com> Date: Fri, 29 Nov 2024 16:44:55 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sky/handler/GlobalExceptionHandler.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java diff --git a/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java b/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..7ffc45d --- /dev/null +++ b/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java @@ -0,0 +1,46 @@ +package com.sky.handler; + +import com.sky.constant.MessageConstant; +import com.sky.exception.BaseException; +import com.sky.result.Result; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.sql.SQLIntegrityConstraintViolationException; + +/** + * 全局异常处理器,处理项目中抛出的业务异常 + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + /** + * 捕获业务异常 + * @param ex + * @return + */ + @ExceptionHandler + public Result exceptionHandler(BaseException ex){ + log.error("异常信息:{}", ex.getMessage()); + return Result.error(ex.getMessage()); + } + + /* + * 处理sql异常 + * + * */ + @ExceptionHandler + public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){ + //Duplicate entry "zhangsan" for key '...' + String message = ex.getMessage(); + if(message.contains("Duplicate entry")){ + String[] split = message.split(" "); + String username = split[2]; + String msg = username + MessageConstant.ALREADY_EXISTS; + return Result.error(msg); + } + return Result.error(MessageConstant.UNKNOWN_ERROR); + } +} From 6b9a65b84206a2fdcd96341249c7dcda9b5ca937 Mon Sep 17 00:00:00 2001 From: LiShu <2945621619@qq.com> Date: Fri, 29 Nov 2024 16:45:38 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0JWT=E4=BB=A4=E7=89=8C?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=8B=A6=E6=88=AA=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inteceptor/JwtTokenAdminInterceptor.java | 63 +++++++++++++++++++ .../inteceptor/JwtTokenUserInterceptor.java | 63 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 sky-server/src/main/java/com/sky/inteceptor/JwtTokenAdminInterceptor.java create mode 100644 sky-server/src/main/java/com/sky/inteceptor/JwtTokenUserInterceptor.java diff --git a/sky-server/src/main/java/com/sky/inteceptor/JwtTokenAdminInterceptor.java b/sky-server/src/main/java/com/sky/inteceptor/JwtTokenAdminInterceptor.java new file mode 100644 index 0000000..ad58935 --- /dev/null +++ b/sky-server/src/main/java/com/sky/inteceptor/JwtTokenAdminInterceptor.java @@ -0,0 +1,63 @@ +package com.sky.inteceptor; + +import com.sky.constant.JwtClaimsConstant; +import com.sky.context.BaseContext; +import com.sky.properties.JwtProperties; +import com.sky.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * jwt令牌校验的拦截器 + */ +@Component +@Slf4j +public class JwtTokenAdminInterceptor implements HandlerInterceptor { + + @Autowired + private JwtProperties jwtProperties; + + /** + * 校验jwt + * + * @param request + * @param response + * @param handler + * @return + * @throws Exception + */ + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + System.out.println("当前线程的id:" + Thread.currentThread().getId()); + //判断当前拦截到的是Controller的方法还是其他资源 + if (!(handler instanceof HandlerMethod)) { + //当前拦截到的不是动态方法,直接放行 + return true; + } + + //1、从请求头中获取令牌 + String token = request.getHeader(jwtProperties.getAdminTokenName()); + + //2、校验令牌 + try { + log.info("jwt校验:{}", token); + Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token); + Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString()); + log.info("当前员工id:", empId); + BaseContext.setCurrentId(empId); + //3、通过,放行 + return true; + } catch (Exception ex) { + //4、不通过,响应401状态码 + response.setStatus(401); + return false; + } + } +} diff --git a/sky-server/src/main/java/com/sky/inteceptor/JwtTokenUserInterceptor.java b/sky-server/src/main/java/com/sky/inteceptor/JwtTokenUserInterceptor.java new file mode 100644 index 0000000..2b7be79 --- /dev/null +++ b/sky-server/src/main/java/com/sky/inteceptor/JwtTokenUserInterceptor.java @@ -0,0 +1,63 @@ +package com.sky.inteceptor; + +import com.sky.constant.JwtClaimsConstant; +import com.sky.context.BaseContext; +import com.sky.properties.JwtProperties; +import com.sky.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * jwt令牌校验的拦截器 + */ +@Component +@Slf4j +public class JwtTokenUserInterceptor implements HandlerInterceptor { + + @Autowired + private JwtProperties jwtProperties; + + /** + * 校验jwt + * + * @param request + * @param response + * @param handler + * @return + * @throws Exception + */ + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + System.out.println("当前线程的id:" + Thread.currentThread().getId()); + //判断当前拦截到的是Controller的方法还是其他资源 + if (!(handler instanceof HandlerMethod)) { + //当前拦截到的不是动态方法,直接放行 + return true; + } + + //1、从请求头中获取令牌 + String token = request.getHeader(jwtProperties.getUserTokenName()); + + //2、校验令牌 + try { + log.info("jwt校验:{}", token); + Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token); + Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString()); + log.info("当前用户id:", userId); + BaseContext.setCurrentId(userId); + //3、通过,放行 + return true; + } catch (Exception ex) { + //4、不通过,响应401状态码 + response.setStatus(401); + return false; + } + } +} From fe073568e1b16b36a01d8b76d26727402dd18875 Mon Sep 17 00:00:00 2001 From: LiShu <2945621619@qq.com> Date: Fri, 29 Nov 2024 16:46:36 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=98=BF=E9=87=8C?= =?UTF-8?q?=E4=BA=91=E3=80=81redis=E3=80=81SpringMVC=E3=80=81WebSocket?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sky/config/OssConfiguration.java | 23 ++++ .../com/sky/config/RedisConfigration.java | 23 ++++ .../com/sky/config/WebMvcConfiguration.java | 115 ++++++++++++++++++ .../sky/config/WebSocketConfiguration.java | 18 +++ 4 files changed, 179 insertions(+) create mode 100644 sky-server/src/main/java/com/sky/config/OssConfiguration.java create mode 100644 sky-server/src/main/java/com/sky/config/RedisConfigration.java create mode 100644 sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java create mode 100644 sky-server/src/main/java/com/sky/config/WebSocketConfiguration.java diff --git a/sky-server/src/main/java/com/sky/config/OssConfiguration.java b/sky-server/src/main/java/com/sky/config/OssConfiguration.java new file mode 100644 index 0000000..376276f --- /dev/null +++ b/sky-server/src/main/java/com/sky/config/OssConfiguration.java @@ -0,0 +1,23 @@ +package com.sky.config; + +import com.sky.properties.AliOssProperties; +import com.sky.utils.AliOssUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Slf4j +public class OssConfiguration { + @Bean + @ConditionalOnMissingBean + public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){ + log.info("开始创建阿里云上传文件工具类对象:{}",aliOssProperties); + return new AliOssUtil(aliOssProperties.getEndpoint(), + aliOssProperties.getAccessKeyId(), + aliOssProperties.getAccessKeySecret(), + aliOssProperties.getBucketName()); + } + +} diff --git a/sky-server/src/main/java/com/sky/config/RedisConfigration.java b/sky-server/src/main/java/com/sky/config/RedisConfigration.java new file mode 100644 index 0000000..94e9b18 --- /dev/null +++ b/sky-server/src/main/java/com/sky/config/RedisConfigration.java @@ -0,0 +1,23 @@ +package com.sky.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +@Slf4j +public class RedisConfigration { + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){ + log.info("开始创建redis末模板对象..."); + RedisTemplate redisTemplate = new RedisTemplate(); + //设置redis的连接工厂对象 + redisTemplate.setConnectionFactory(redisConnectionFactory); + //设置redis key的序列化器 + redisTemplate.setKeySerializer(new StringRedisSerializer()); + return redisTemplate; + } +} diff --git a/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java b/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java new file mode 100644 index 0000000..c60128e --- /dev/null +++ b/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java @@ -0,0 +1,115 @@ +package com.sky.config; + + +import com.sky.inteceptor.JwtTokenAdminInterceptor; +import com.sky.inteceptor.JwtTokenUserInterceptor; +import com.sky.json.JacksonObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.List; + +/** + * 配置类,注册web层相关组件 + */ +@Configuration +@Slf4j +public class WebMvcConfiguration extends WebMvcConfigurationSupport { + + @Autowired + private JwtTokenAdminInterceptor jwtTokenAdminInterceptor; + @Autowired + private JwtTokenUserInterceptor jwtTokenUserInterceptor; + /** + * 注册自定义拦截器 + * + * @param registry + */ + protected void addInterceptors(InterceptorRegistry registry) { + log.info("开始注册自定义拦截器..."); + registry.addInterceptor(jwtTokenAdminInterceptor) + .addPathPatterns("/admin/**") + .excludePathPatterns("/admin/employee/login"); + registry.addInterceptor(jwtTokenUserInterceptor) + .addPathPatterns("/user/**") + .excludePathPatterns("/user/user/login") + .excludePathPatterns("/user/shop/status"); + } + + /** + * 通过knife4j生成接口文档 + * @return + */ + @Bean + public Docket docket1() { + log.info("准备生成接口文档.."); + ApiInfo apiInfo = new ApiInfoBuilder() + .title("苍穹外卖项目接口文档") + .version("2.0") + .description("苍穹外卖项目接口文档") + .build(); + Docket docket = new Docket(DocumentationType.SWAGGER_2) + .groupName("管理端接口") + .apiInfo(apiInfo) + .select() + .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin")) + .paths(PathSelectors.any()) + .build(); + return docket; + } + + @Bean + public Docket docket2() { + log.info("准备生成接口文档.."); + ApiInfo apiInfo = new ApiInfoBuilder() + .title("苍穹外卖项目接口文档") + .version("2.0") + .description("苍穹外卖项目接口文档") + .build(); + Docket docket = new Docket(DocumentationType.SWAGGER_2) + .groupName("用户端接口") + .apiInfo(apiInfo) + .select() + .apis(RequestHandlerSelectors.basePackage("com.sky.controller.user")) + .paths(PathSelectors.any()) + .build(); + return docket; + } + /** + * 设置静态资源映射 + * @param registry + */ + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + log.info("开始设置静态资源映射.."); + registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + + /* + * 拓展spring MVC框架的消息转换器 + * + * */ + @Override + protected void extendMessageConverters(List> converters) { + log.info("拓展消息转化器"); + //创建一个消息转换器对象 + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + //需要为消息转换器设置一个对象转换器,对象转换器将java对象序列化为json数据 + converter.setObjectMapper(new JacksonObjectMapper()); + //将自己的消息转换器加入容器中 + converters.add(0,converter); + } +} diff --git a/sky-server/src/main/java/com/sky/config/WebSocketConfiguration.java b/sky-server/src/main/java/com/sky/config/WebSocketConfiguration.java new file mode 100644 index 0000000..a46c2cb --- /dev/null +++ b/sky-server/src/main/java/com/sky/config/WebSocketConfiguration.java @@ -0,0 +1,18 @@ +package com.sky.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * WebSocket配置类,用于注册WebSocket的Bean + */ +@Configuration +public class WebSocketConfiguration { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} From a9f2a69f937e5f1ccb0d541a470a6f5c74f0905a Mon Sep 17 00:00:00 2001 From: LiShu <2945621619@qq.com> Date: Fri, 29 Nov 2024 16:46:50 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sky/SkyApplication.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 sky-server/src/main/java/com/sky/SkyApplication.java diff --git a/sky-server/src/main/java/com/sky/SkyApplication.java b/sky-server/src/main/java/com/sky/SkyApplication.java new file mode 100644 index 0000000..389ecb1 --- /dev/null +++ b/sky-server/src/main/java/com/sky/SkyApplication.java @@ -0,0 +1,20 @@ +package com.sky; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@EnableCaching //开启缓存注解功能 +@SpringBootApplication +@EnableTransactionManagement //开启注解方式的事务管理 +@Slf4j +@EnableScheduling //开启任务调度 +public class SkyApplication { + public static void main(String[] args) { + SpringApplication.run(SkyApplication.class, args); + log.info("server started"); + } +}