From 7744db2b44050ac7efb464201d0ff52d02b0e739 Mon Sep 17 00:00:00 2001 From: bs32g1038 Date: Wed, 24 Apr 2024 18:00:38 +0800 Subject: [PATCH] chore: refactor --- .../main/java/com/jixialunbi/common/R.java | 42 ++--- .../jixialunbi/common/result/IResultCode.java | 12 ++ .../jixialunbi/common/result/ResultCode.java | 107 ++++++++++++ .../common/utils/ResponseUtils.java | 37 ++++ .../com/jixialunbi/config/SecurityConfig.java | 12 +- .../controllers/CategoryController.java | 6 +- .../controllers/CollectionController.java | 6 +- .../controllers/CommentController.java | 14 +- .../controllers/EmailController.java | 7 +- .../controllers/NotificationController.java | 7 +- .../controllers/PostController.java | 4 +- .../controllers/StatisticController.java | 7 +- .../jixialunbi/controllers/TagController.java | 18 +- .../controllers/UploadController.java | 3 +- .../controllers/UserController.java | 34 ++-- .../jixialunbi/dto/request/TagRequest.java | 1 - .../enums/HttpReponseResultCodeEnum.java | 80 --------- .../exception/GlobalExceptionHandler.java | 158 ++---------------- .../security/AuthEntryPointJwt.java | 16 +- ...Handler.java => CAccessDeniedHandler.java} | 14 +- .../security/MyAccessDeniedHandler.java | 21 --- .../com/jixialunbi/service/AuthService.java | 3 +- .../jixialunbi/service/FollowUserService.java | 5 +- .../com/jixialunbi/service/UserService.java | 4 +- server/src/main/resources/application.yml | 6 +- 25 files changed, 236 insertions(+), 388 deletions(-) create mode 100644 server/src/main/java/com/jixialunbi/common/result/IResultCode.java create mode 100644 server/src/main/java/com/jixialunbi/common/result/ResultCode.java create mode 100644 server/src/main/java/com/jixialunbi/common/utils/ResponseUtils.java delete mode 100644 server/src/main/java/com/jixialunbi/enums/HttpReponseResultCodeEnum.java rename server/src/main/java/com/jixialunbi/security/{CustomAccessDeniedHandler.java => CAccessDeniedHandler.java} (65%) delete mode 100644 server/src/main/java/com/jixialunbi/security/MyAccessDeniedHandler.java diff --git a/server/src/main/java/com/jixialunbi/common/R.java b/server/src/main/java/com/jixialunbi/common/R.java index 70b0c3b..d412d5b 100644 --- a/server/src/main/java/com/jixialunbi/common/R.java +++ b/server/src/main/java/com/jixialunbi/common/R.java @@ -1,54 +1,47 @@ package com.jixialunbi.common; -import com.jixialunbi.enums.HttpReponseResultCodeEnum; +import com.jixialunbi.common.result.ResultCode; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import java.util.Map; +import java.io.Serializable; /** * - 全局统一返回结果 */ @Data @Schema(name = "全局统一返回结果", description = "全局统一返回结果") -public class R { +public class R implements Serializable { @Schema(description = "是否成功") private Boolean success; @Schema(description = "返回码") - private Integer code; + private String code; @Schema(description = "返回消息") private String message; @Schema(description = "返回数据") - private Object data; + private T data; public R() { } public static R ok() { R r = new R(); - r.setSuccess(HttpReponseResultCodeEnum.SUCCESS.getSuccess()); - r.setCode(HttpReponseResultCodeEnum.SUCCESS.getCode()); - r.setMessage(HttpReponseResultCodeEnum.SUCCESS.getMessage()); + r.setSuccess(true); + r.setCode(ResultCode.SUCCESS.getCode()); + r.setMessage(ResultCode.SUCCESS.getMessage()); return r; } - public static R error() { + public static R error(ResultCode resultCode) { R r = new R(); - r.setSuccess(HttpReponseResultCodeEnum.UNKNOWN_REASON.getSuccess()); - r.setCode(HttpReponseResultCodeEnum.UNKNOWN_REASON.getCode()); - r.setMessage(HttpReponseResultCodeEnum.UNKNOWN_REASON.getMessage()); - return r; - } - - public static R setResult(HttpReponseResultCodeEnum resultCodeEnum) { - R r = new R(); - r.setSuccess(resultCodeEnum.getSuccess()); - r.setCode(resultCodeEnum.getCode()); - r.setMessage(resultCodeEnum.getMessage()); + r.setSuccess(false); + r.setCode(resultCode.getCode()); + r.setMessage(resultCode.getMessage()); + r.setData(null); return r; } @@ -62,19 +55,14 @@ public R message(String message) { return this; } - public R code(Integer code) { + public R code(String code) { this.setCode(code); return this; } - public R data(Object value) { + public R data(T value) { this.data = value; return this; } - public R data(Map map) { - this.setData(map); - return this; - } - } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/common/result/IResultCode.java b/server/src/main/java/com/jixialunbi/common/result/IResultCode.java new file mode 100644 index 0000000..31a3821 --- /dev/null +++ b/server/src/main/java/com/jixialunbi/common/result/IResultCode.java @@ -0,0 +1,12 @@ +package com.jixialunbi.common.result; + +/** + * @author haoxr + **/ +public interface IResultCode { + + String getCode(); + + String getMessage(); + +} \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/common/result/ResultCode.java b/server/src/main/java/com/jixialunbi/common/result/ResultCode.java new file mode 100644 index 0000000..d9e58a7 --- /dev/null +++ b/server/src/main/java/com/jixialunbi/common/result/ResultCode.java @@ -0,0 +1,107 @@ +package com.jixialunbi.common.result; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 前后端数据交换状态码 + * + * @author haoxr + * @since 2020-06-23 + **/ +@AllArgsConstructor +@NoArgsConstructor +public enum ResultCode implements IResultCode, Serializable { + + SUCCESS("00000", "成功"), + + USER_ERROR("A0001", "用户端错误"), + REPEAT_SUBMIT_ERROR("A0002", "您的请求已提交,请不要重复提交或等待片刻再尝试。"), + USER_LOGIN_ERROR("A0200", "用户登录异常"), + USER_NOT_EXIST("A0201", "用户不存在"), + USERNAME_OR_PASSWORD_ERROR("A0210", "用户名或密码错误"), + PASSWORD_ENTER_EXCEED_LIMIT("A0211", "用户输入密码次数超限"), + CLIENT_AUTHENTICATION_FAILED("A0212", "客户端认证失败"), + + VERIFY_CODE_TIMEOUT("A0213", "验证码已过期"), + VERIFY_CODE_ERROR("A0214", "验证码错误"), + + TOKEN_INVALID("A0230", "token无效或已过期"), + TOKEN_ACCESS_FORBIDDEN("A0231", "token已被禁止访问"), + + AUTHORIZED_ERROR("A0300", "访问权限异常"), + ACCESS_UNAUTHORIZED("A0301", "访问未授权"), + FORBIDDEN_OPERATION("A0302", "演示环境禁止新增、修改和删除数据,请本地部署后测试"), + + + PARAM_ERROR("A0400", "用户请求参数错误"), + RESOURCE_NOT_FOUND("A0401", "请求资源不存在"), + PARAM_IS_NULL("A0410", "请求必填参数为空"), + + USER_UPLOAD_FILE_ERROR("A0700", "用户上传文件异常"), + USER_UPLOAD_FILE_TYPE_NOT_MATCH("A0701", "用户上传文件类型不匹配"), + USER_UPLOAD_FILE_SIZE_EXCEEDS("A0702", "用户上传文件太大"), + USER_UPLOAD_IMAGE_SIZE_EXCEEDS("A0703", "用户上传图片太大"), + + SYSTEM_EXECUTION_ERROR("B0001", "系统执行出错"), + SYSTEM_EXECUTION_TIMEOUT("B0100", "系统执行超时"), + SYSTEM_ORDER_PROCESSING_TIMEOUT("B0100", "系统订单处理超时"), + + SYSTEM_DISASTER_RECOVERY_TRIGGER("B0200", "系统容灾功能被出发"), + FLOW_LIMITING("B0210", "系统限流"), + DEGRADATION("B0220", "系统功能降级"), + + SYSTEM_RESOURCE_ERROR("B0300", "系统资源异常"), + SYSTEM_RESOURCE_EXHAUSTION("B0310", "系统资源耗尽"), + SYSTEM_RESOURCE_ACCESS_ERROR("B0320", "系统资源访问异常"), + SYSTEM_READ_DISK_FILE_ERROR("B0321", "系统读取磁盘文件失败"), + + CALL_THIRD_PARTY_SERVICE_ERROR("C0001", "调用第三方服务出错"), + MIDDLEWARE_SERVICE_ERROR("C0100", "中间件服务出错"), + INTERFACE_NOT_EXIST("C0113", "接口不存在"), + + MESSAGE_SERVICE_ERROR("C0120", "消息服务出错"), + MESSAGE_DELIVERY_ERROR("C0121", "消息投递出错"), + MESSAGE_CONSUMPTION_ERROR("C0122", "消息消费出错"), + MESSAGE_SUBSCRIPTION_ERROR("C0123", "消息订阅出错"), + MESSAGE_GROUP_NOT_FOUND("C0124", "消息分组未查到"), + + DATABASE_ERROR("C0300", "数据库服务出错"), + DATABASE_TABLE_NOT_EXIST("C0311", "表不存在"), + DATABASE_COLUMN_NOT_EXIST("C0312", "列不存在"), + DATABASE_DUPLICATE_COLUMN_NAME("C0321", "多表关联中存在多个相同名称的列"), + DATABASE_DEADLOCK("C0331", "数据库死锁"), + DATABASE_PRIMARY_KEY_CONFLICT("C0341", "主键冲突"); + + private String code; + private String msg; + + public static ResultCode getValue(String code) { + for (ResultCode value : values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return SYSTEM_EXECUTION_ERROR; // 默认系统执行错误 + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getMessage() { + return msg; + } + + @Override + public String toString() { + return "{" + + "\"code\":\"" + code + '\"' + + ", \"msg\":\"" + msg + '\"' + + '}'; + } +} \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/common/utils/ResponseUtils.java b/server/src/main/java/com/jixialunbi/common/utils/ResponseUtils.java new file mode 100644 index 0000000..dd39863 --- /dev/null +++ b/server/src/main/java/com/jixialunbi/common/utils/ResponseUtils.java @@ -0,0 +1,37 @@ +package com.jixialunbi.common.utils; + +import cn.hutool.json.JSONUtil; +import com.jixialunbi.common.R; +import com.jixialunbi.common.result.ResultCode; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +@Slf4j +public class ResponseUtils { + + public static void writeErrMsg(HttpServletResponse response, ResultCode resultCode) { + // 根据不同的结果码设置HTTP状态 + int status = switch (resultCode) { + case ACCESS_UNAUTHORIZED, TOKEN_INVALID -> HttpStatus.UNAUTHORIZED.value(); + case TOKEN_ACCESS_FORBIDDEN -> HttpStatus.FORBIDDEN.value(); + default -> HttpStatus.BAD_REQUEST.value(); + }; + response.setStatus(status); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); + try (PrintWriter writer = response.getWriter()) { + String jsonResponse = JSONUtil.toJsonStr(R.error(resultCode)); + writer.print(jsonResponse); + writer.flush(); // 确保将响应内容写入到输出流 + } catch (IOException e) { + log.error("响应异常处理失败", e); + } + } + +} \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/config/SecurityConfig.java b/server/src/main/java/com/jixialunbi/config/SecurityConfig.java index 2d578b5..5792e35 100644 --- a/server/src/main/java/com/jixialunbi/config/SecurityConfig.java +++ b/server/src/main/java/com/jixialunbi/config/SecurityConfig.java @@ -2,7 +2,7 @@ import com.jixialunbi.security.AuthEntryPointJwt; import com.jixialunbi.security.AuthTokenFilter; -import com.jixialunbi.security.CustomAccessDeniedHandler; +import com.jixialunbi.security.CAccessDeniedHandler; import com.jixialunbi.service.UserDetailsServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @@ -40,13 +40,10 @@ public class SecurityConfig { "/swagger-ui.html" }; private final UserDetailsServiceImpl userDetailsService; - + private final CAccessDeniedHandler accessDeniedHandler; @Autowired private AuthEntryPointJwt unauthorizedHandler; - @Autowired - private CustomAccessDeniedHandler customAccessDeniedHandler; - @Bean public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); @@ -80,14 +77,15 @@ public CorsConfiguration corsConfiguration() { return corsConfiguration; } + @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity, CorsConfiguration corsConfiguration) throws Exception { httpSecurity .cors(cors -> cors.configurationSource(request -> corsConfiguration)) .csrf(e -> e.disable()) .exceptionHandling(exception -> { - exception.accessDeniedHandler(customAccessDeniedHandler); - exception.authenticationEntryPoint(unauthorizedHandler); + exception.authenticationEntryPoint(unauthorizedHandler) + .accessDeniedHandler(accessDeniedHandler); }) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeHttpRequests(auth -> diff --git a/server/src/main/java/com/jixialunbi/controllers/CategoryController.java b/server/src/main/java/com/jixialunbi/controllers/CategoryController.java index cefd32d..d93dbdf 100644 --- a/server/src/main/java/com/jixialunbi/controllers/CategoryController.java +++ b/server/src/main/java/com/jixialunbi/controllers/CategoryController.java @@ -18,11 +18,7 @@ public class CategoryController { @GetMapping("/categories") public R fetchCategories(@RequestParam(required = false, defaultValue = "1") int page, @RequestParam(required = false, defaultValue = "10") int pageSize) { - try { - return R.ok().data(categoryRepository.findAll()); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(categoryRepository.findAll()); } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/controllers/CollectionController.java b/server/src/main/java/com/jixialunbi/controllers/CollectionController.java index b3390e9..b60ef59 100644 --- a/server/src/main/java/com/jixialunbi/controllers/CollectionController.java +++ b/server/src/main/java/com/jixialunbi/controllers/CollectionController.java @@ -52,11 +52,7 @@ public R fetchCategories( post.setCollected(cn != null && cn.getDeleted() == null); } }); - try { - return R.ok().data(PageUtil.of(list)); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(PageUtil.of(list)); } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/controllers/CommentController.java b/server/src/main/java/com/jixialunbi/controllers/CommentController.java index e78b202..52f7ac7 100644 --- a/server/src/main/java/com/jixialunbi/controllers/CommentController.java +++ b/server/src/main/java/com/jixialunbi/controllers/CommentController.java @@ -36,11 +36,8 @@ public class CommentController { public R fetchComments( @RequestParam(required = false, defaultValue = "1") int page, @RequestParam(required = false, defaultValue = "10") int pageSize) { - try { - return R.ok().data(commentRepository.findAll()); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(commentRepository.findAll()); + } @GetMapping("/post-comments") @@ -52,11 +49,8 @@ public R fetchCommentsByPostId(@RequestParam(required = true) long postId) { map.put("childrens", list.stream().filter(d -> ObjectUtil.equals(d.getParentId(), v.getId()))); return map; }).toList(); - try { - return R.ok().data(result); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(result); + } @PreAuthorize("hasRole('ROLE_USER')") diff --git a/server/src/main/java/com/jixialunbi/controllers/EmailController.java b/server/src/main/java/com/jixialunbi/controllers/EmailController.java index f094829..ebb5e3f 100644 --- a/server/src/main/java/com/jixialunbi/controllers/EmailController.java +++ b/server/src/main/java/com/jixialunbi/controllers/EmailController.java @@ -22,6 +22,7 @@ @RequestMapping("/api/v1") public class EmailController { + final String EMAIL_ACTIVE_CODE_KEY = "email_active_code_key"; String html = """
"""; - @Autowired HttpSession session; - @Autowired UserService userService; - @Autowired UserRepository userRepository; - @Value("${EMAIL_PASS}") private String EMAIL_PASS; - final String EMAIL_ACTIVE_CODE_KEY = "email_active_code_key"; - @PreAuthorize("hasRole('ROLE_USER')") @PostMapping("/send-email") public R sendEmail(Principal principal) { diff --git a/server/src/main/java/com/jixialunbi/controllers/NotificationController.java b/server/src/main/java/com/jixialunbi/controllers/NotificationController.java index 0ca6da6..246f24f 100644 --- a/server/src/main/java/com/jixialunbi/controllers/NotificationController.java +++ b/server/src/main/java/com/jixialunbi/controllers/NotificationController.java @@ -28,11 +28,8 @@ public class NotificationController { @GetMapping("/notifications") public R fetchNotifications(Principal principal, @RequestParam(required = false, defaultValue = "1") int page, @RequestParam(required = false, defaultValue = "10") int pageSize) { User author = userService.getByAccount(principal.getName()); - try { - return R.ok().data(notificationRepository.findAllByReceiverId(author.getId())); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(notificationRepository.findAllByReceiverId(author.getId())); + } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/controllers/PostController.java b/server/src/main/java/com/jixialunbi/controllers/PostController.java index 9b57078..aafa591 100644 --- a/server/src/main/java/com/jixialunbi/controllers/PostController.java +++ b/server/src/main/java/com/jixialunbi/controllers/PostController.java @@ -168,7 +168,7 @@ public R getPost(@PathVariable long postId, @AuthenticationPrincipal UserDetails if (!post.get().equals(null)) { post.get().setVisitCount(post.get().getVisitCount() + 1); } - if(userDetails != null){ + if (userDetails != null) { User user = userService.getById(userDetails.getId()); // 点赞数据 var res = postLikeRepository.findOneByPostIdAndAuthorId(postId, user.getId()); @@ -184,7 +184,7 @@ public R getPost(@PathVariable long postId, @AuthenticationPrincipal UserDetails @Transactional @PreAuthorize("hasRole('ROLE_USER')") @PostMapping("/like-post/{postId}") - public R likePost(@PathVariable long postId, @AuthenticationPrincipal UserDetailsImpl userDetails) { + public R likePost(@PathVariable long postId, @AuthenticationPrincipal UserDetailsImpl userDetails) { var user = userService.getById(userDetails.getId()); var res = postLikeRepository.findOneByPostIdAndAuthorId(postId, user.getId()); if (res != null) { diff --git a/server/src/main/java/com/jixialunbi/controllers/StatisticController.java b/server/src/main/java/com/jixialunbi/controllers/StatisticController.java index 011389e..828779b 100644 --- a/server/src/main/java/com/jixialunbi/controllers/StatisticController.java +++ b/server/src/main/java/com/jixialunbi/controllers/StatisticController.java @@ -32,11 +32,8 @@ public R fetchCategories() { map.put("userCount", userRepository.count()); map.put("postCount", postRepository.countByDeleted(null)); map.put("commentCount", commentRepository.count()); - try { - return R.ok().data(map); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(map); + } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/controllers/TagController.java b/server/src/main/java/com/jixialunbi/controllers/TagController.java index 58fdbd7..06fe3b6 100644 --- a/server/src/main/java/com/jixialunbi/controllers/TagController.java +++ b/server/src/main/java/com/jixialunbi/controllers/TagController.java @@ -1,27 +1,17 @@ package com.jixialunbi.controllers; import com.jixialunbi.common.R; -import com.jixialunbi.dto.request.CommentRequest; import com.jixialunbi.dto.request.IdRequest; import com.jixialunbi.dto.request.TagRequest; -import com.jixialunbi.model.Comment; -import com.jixialunbi.model.Post; import com.jixialunbi.model.Tag; -import com.jixialunbi.model.User; import com.jixialunbi.repository.TagRepository; -import com.jixialunbi.security.UserDetailsImpl; import com.jixialunbi.service.UserService; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; -import java.security.Principal; -import java.time.LocalDateTime; -import java.util.Optional; - @RestController @RequestMapping("/api/v1") @@ -35,11 +25,7 @@ public class TagController { @GetMapping("/tags") public R fetchTags(@RequestParam(required = false, defaultValue = "1") int page, @RequestParam(required = false, defaultValue = "10") int pageSize) { - try { - return R.ok().data(tagRepository.findAll()); - } catch (Exception e) { - return R.error().message("系统异常"); - } + return R.ok().data(tagRepository.findAll()); } @PreAuthorize("hasRole('ROLE_USER')") @@ -56,7 +42,7 @@ public R createTag(@Valid @RequestBody TagRequest tagRequest) { @PostMapping("/tags/update") public R updateTag(@Valid @RequestBody TagRequest tagRequest) { Tag tag = tagRepository.findById(tagRequest.getId()).get(); - if(tag != null){ + if (tag != null) { tag.setName(tagRequest.getName().trim()); tag.setDescription(tagRequest.getDescription().trim()); } diff --git a/server/src/main/java/com/jixialunbi/controllers/UploadController.java b/server/src/main/java/com/jixialunbi/controllers/UploadController.java index b04e6b2..71138f0 100644 --- a/server/src/main/java/com/jixialunbi/controllers/UploadController.java +++ b/server/src/main/java/com/jixialunbi/controllers/UploadController.java @@ -2,6 +2,7 @@ import cn.hutool.crypto.digest.DigestUtil; import com.jixialunbi.common.R; +import com.jixialunbi.common.result.ResultCode; import com.jixialunbi.service.FileService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ public R singleFileUpload(@RequestParam("file") MultipartFile file) { fileService.saveFile(file.getBytes(), nginxPath, fileName); return R.ok().data("/static/images/" + fileName); } catch (Exception e) { - return R.error().data(e); + return R.error(ResultCode.USER_UPLOAD_FILE_ERROR).data(e); } } diff --git a/server/src/main/java/com/jixialunbi/controllers/UserController.java b/server/src/main/java/com/jixialunbi/controllers/UserController.java index 2686683..0666c66 100644 --- a/server/src/main/java/com/jixialunbi/controllers/UserController.java +++ b/server/src/main/java/com/jixialunbi/controllers/UserController.java @@ -1,9 +1,9 @@ package com.jixialunbi.controllers; import com.jixialunbi.common.R; +import com.jixialunbi.common.result.ResultCode; import com.jixialunbi.dto.request.UserRequest; import com.jixialunbi.dto.request.UserUpdateRequest; -import com.jixialunbi.enums.HttpReponseResultCodeEnum; import com.jixialunbi.model.User; import com.jixialunbi.repository.UserRepository; import com.jixialunbi.security.UserDetailsImpl; @@ -18,6 +18,8 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; +import java.util.ArrayList; + @RestController @RequestMapping("/api/v1") public class UserController { @@ -33,16 +35,12 @@ public class UserController { @GetMapping("/users") public R fetchUsers(@RequestParam int page, @RequestParam int pageSize) { - try { - Pageable pageable = PageRequest.of(page, pageSize); - Page data = userRepository.findAll(pageable); - if (data.getSize() <= 0) { - return R.ok().setResult(HttpReponseResultCodeEnum.NOT_CONTENT); - } - return R.ok().data(data); - } catch (Exception e) { - return R.error().message("系统异常"); + Pageable pageable = PageRequest.of(page, pageSize); + Page data = userRepository.findAll(pageable); + if (data.getSize() <= 0) { + return R.ok().data(new ArrayList()); } + return R.ok().data(data); } @PreAuthorize("hasRole('ROLE_USER')") @@ -54,7 +52,7 @@ public R loginUserInfo(@AuthenticationPrincipal UserDetailsImpl userDetails) { @PostMapping("/user/create") public R create(@Valid @RequestBody UserRequest request) { if (userRepository.existsByEmailIgnoreCase(request.getEmail())) { - return R.error().message("用户已存在!"); + return R.error(ResultCode.PARAM_ERROR).message("用户已存在!"); } return R.ok().data(userService.create(request)); } @@ -99,16 +97,12 @@ public R followUser(@PathVariable Long userId, @AuthenticationPrincipal UserDeta @GetMapping("/recent-users") public R fetchRecentUsers() { - try { - Pageable pageable = PageRequest.of(0, 10); - Page data = userRepository.findAll(pageable); - if (data.getSize() <= 0) { - return R.ok().setResult(HttpReponseResultCodeEnum.NOT_CONTENT); - } - return R.ok().data(data); - } catch (Exception e) { - return R.error().message("系统异常"); + Pageable pageable = PageRequest.of(0, 10); + Page data = userRepository.findAll(pageable); + if (data.getSize() <= 0) { + return R.ok().data(new ArrayList()); } + return R.ok().data(data); } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/dto/request/TagRequest.java b/server/src/main/java/com/jixialunbi/dto/request/TagRequest.java index c83e988..7d585cb 100644 --- a/server/src/main/java/com/jixialunbi/dto/request/TagRequest.java +++ b/server/src/main/java/com/jixialunbi/dto/request/TagRequest.java @@ -1,7 +1,6 @@ package com.jixialunbi.dto.request; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; diff --git a/server/src/main/java/com/jixialunbi/enums/HttpReponseResultCodeEnum.java b/server/src/main/java/com/jixialunbi/enums/HttpReponseResultCodeEnum.java deleted file mode 100644 index 55986ba..0000000 --- a/server/src/main/java/com/jixialunbi/enums/HttpReponseResultCodeEnum.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.jixialunbi.enums; - -import lombok.Getter; -import lombok.ToString; - -/** - * 前后端数据交换状态码 - */ -@Getter -@ToString -public enum HttpReponseResultCodeEnum { - - SUCCESS(true, 20000, "成功"), - UNKNOWN_REASON(false, 20001, "未知错误"), - UPDATE_ERROR(false, 20002, "更新失败"), - - BAD_SQL_GRAMMAR(false, 21001, "sql 语法错误"), - JSON_PARSE_ERROR(false, 21002, "json 解析异常"), - PARAM_ERROR(false, 21003, "参数不正确"), - - FILE_UPLOAD_ERROR(false, 21004, "文件上传错误"), - FILE_DELETE_ERROR(false, 21005, "文件刪除错误"), - EXCEL_DATA_IMPORT_ERROR(false, 21006, "Excel 数据导入错误"), - - VIDEO_UPLOAD_ALIYUN_ERROR(false, 22001, "视频上传至阿里云失败"), - VIDEO_UPLOAD_TOMCAT_ERROR(false, 22002, "视频上传至业务服务器失败"), - VIDEO_DELETE_ALIYUN_ERROR(false, 22003, "阿里云视频文件删除失败"), - FETCH_VIDEO_UPLOADAUTH_ERROR(false, 22004, "获取上传地址和凭证失败"), - REFRESH_VIDEO_UPLOADAUTH_ERROR(false, 22005, "刷新上传地址和凭证失败"), - FETCH_PLAYAUTH_ERROR(false, 22006, "获取播放凭证失败"), - - URL_ENCODE_ERROR(false, 23001, "URL编码失败"), - ILLEGAL_CALLBACK_REQUEST_ERROR(false, 23002, "非法回调请求"), - FETCH_ACCESSTOKEN_FAILD(false, 23003, "获取 accessToken 失败"), - FETCH_USERINFO_ERROR(false, 23004, "获取用户信息失败"), - LOGIN_ERROR(false, 23005, "登录失败"), - - COMMENT_EMPTY(false, 24006, "评论内容必须填写"), - - PAY_RUN(false, 25000, "支付中"), - PAY_UNIFIEDORDER_ERROR(false, 25001, "统一下单错误"), - PAY_ORDERQUERY_ERROR(false, 25002, "查询支付结果错误"), - - ORDER_EXIST_ERROR(false, 25003, "课程已购买"), - - GATEWAY_ERROR(false, 26000, "服务不能访问"), - - CODE_ERROR(false, 28000, "验证码错误"), - - LOGIN_PHONE_ERROR(false, 28009, "手机号码不正确"), - LOGIN_MOBILE_ERROR(false, 28001, "账号不正确"), - LOGIN_PASSWORD_ERROR(false, 28008, "密码不正确"), - LOGIN_DISABLED_ERROR(false, 28002, "该用户已被禁用"), - REGISTER_MOBLE_ERROR(false, 28003, "手机号已被注册"), - LOGIN_AUTH(false, 28004, "需要登录"), - LOGIN_ACL(false, 28005, "没有权限"), - SMS_SEND_ERROR(false, 28006, "短信发送失败"), - SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL(false, 28007, "短信发送过于频繁"), - - DIVIDE_ZERO(false, 29001, "除零错误"), - - DATA_NULL(false, 30001, "数据不存在!"), - DATA_EXITS(false, 30002, "数据已存在!"), - DATA_NODE_EXITS(false, 30003, "该章节下存在视频课程,请先删除视频课程!"), - - NOT_CONTENT(true, 40001, "暂无数据!"); - - private final Boolean success; - - private final Integer code; - - private final String message; - - HttpReponseResultCodeEnum(Boolean success, Integer code, String message) { - this.success = success; - this.code = code; - this.message = message; - } - -} \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/exception/GlobalExceptionHandler.java b/server/src/main/java/com/jixialunbi/exception/GlobalExceptionHandler.java index f41a481..de17935 100644 --- a/server/src/main/java/com/jixialunbi/exception/GlobalExceptionHandler.java +++ b/server/src/main/java/com/jixialunbi/exception/GlobalExceptionHandler.java @@ -1,24 +1,16 @@ package com.jixialunbi.exception; +import com.jixialunbi.common.R; +import com.jixialunbi.common.result.ResultCode; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.core.AuthenticationException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import java.util.Objects; - -import static com.jixialunbi.common.Constants.*; - /** * Global exception handler class for handling all the exceptions */ @@ -26,141 +18,15 @@ @RestControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { - /** - * This parameter is used to print StackTrace while debugging. Its value is false by default. - */ - @Value("${exception.trace:false}") - private boolean printStackTrace; - - /** - * Handles MethodArgumentNotValidException - * - * @param ex - * @param headers - * @param statusCode - * @param request - * @return ResponseEntity with detailed information related to the error - */ - @Override - @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) - protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, - HttpHeaders headers, - HttpStatusCode statusCode, - WebRequest request) { - log.error(METHOD_ARGUMENT_NOT_VALID, ex); - final ErrorResponse errorResponse = new ErrorResponse(HttpStatus.UNPROCESSABLE_ENTITY.value(), VALIDATION_ERROR); - for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) { - errorResponse.addValidationError(fieldError.getField(), fieldError.getDefaultMessage()); - } - return ResponseEntity.unprocessableEntity().body(errorResponse); - } - - /** - * Handles NoSuchElementFoundException - * - * @param ex - * @param request - * @return ResponseEntity with detailed information related to the error - */ - @ExceptionHandler(NoSuchElementFoundException.class) - @ResponseStatus(HttpStatus.NOT_FOUND) - public ResponseEntity handleNoSuchElementFoundException(NoSuchElementFoundException ex, WebRequest request) { - log.error(NOT_FOUND, ex); - return buildErrorResponse(ex, HttpStatus.NOT_FOUND, request); - } - - /** - * Handles ElementAlreadyExistsException - * - * @param ex - * @param request - * @return ResponseEntity with detailed information related to the error - */ - @ExceptionHandler(ElementAlreadyExistsException.class) - @ResponseStatus(HttpStatus.CONFLICT) - public ResponseEntity handleElementAlreadyExistsException(ElementAlreadyExistsException ex, WebRequest request) { - log.error(ALREADY_EXISTS, ex); - return buildErrorResponse(ex, HttpStatus.CONFLICT, request); - } - - /** - * Handles all the uncaught exceptions that cannot be caught by the previous methods - * - * @param ex - * @param request - * @return ResponseEntity with detailed information related to the error - */ @ExceptionHandler(Exception.class) - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public ResponseEntity handleAllUncaughtException(Exception ex, WebRequest request) { - log.error(ex.getMessage(), ex); - return buildErrorResponse(ex, HttpStatus.INTERNAL_SERVER_ERROR, request); - } - - /** - * Build error message by the given exception, status and request - * - * @param ex - * @param statusCode - * @param request - * @return ResponseEntity with detailed information related to the error - */ - private ResponseEntity buildErrorResponse(Exception ex, - HttpStatusCode statusCode, - WebRequest request) { - return buildErrorResponse(ex, ex.getMessage(), statusCode, request); - } - - /** - * Build error message by the given exception, message, status and request - * - * @param ex - * @param message - * @param statusCode - * @param request - * @return ResponseEntity with detailed information related to the error - */ - private ResponseEntity buildErrorResponse(Exception ex, - String message, - HttpStatusCode statusCode, - WebRequest request) { - final ErrorResponse errorResponse = new ErrorResponse(statusCode.value(), message); - if (printStackTrace && isTraceOn(request)) { - errorResponse.setStackTrace(ExceptionUtils.getStackTrace(ex)); + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R handleException(Exception e) throws Exception { + // 将 Spring Security 异常继续抛出,以便交给自定义处理器处理 + if (e instanceof AccessDeniedException + || e instanceof AuthenticationException) { + throw e; } - return ResponseEntity.status(statusCode).body(errorResponse); - } - - /** - * Checks the tracing parameter sent by request - * - * @param request - * @return the tracing status based on the request - */ - private boolean isTraceOn(WebRequest request) { - String[] value = request.getParameterValues(TRACE); - return Objects.nonNull(value) - && value.length > 0 - && value[0].contentEquals("true"); - } - - /** - * Handles internal exceptions - * - * @param ex - * @param body - * @param headers - * @param statusCode - * @param request - * @return ResponseEntity with detailed information related to the error - */ - @Override - public ResponseEntity handleExceptionInternal( - Exception ex, - Object body, - HttpHeaders headers, - HttpStatusCode statusCode, - WebRequest request) { - return buildErrorResponse(ex, statusCode, request); + log.error("unknown exception: {}", e.getMessage()); + return R.error(ResultCode.SYSTEM_EXECUTION_ERROR); } } diff --git a/server/src/main/java/com/jixialunbi/security/AuthEntryPointJwt.java b/server/src/main/java/com/jixialunbi/security/AuthEntryPointJwt.java index 0d6ff51..a97bef5 100644 --- a/server/src/main/java/com/jixialunbi/security/AuthEntryPointJwt.java +++ b/server/src/main/java/com/jixialunbi/security/AuthEntryPointJwt.java @@ -1,6 +1,8 @@ package com.jixialunbi.security; import com.fasterxml.jackson.databind.ObjectMapper; +import com.jixialunbi.common.R; +import com.jixialunbi.common.result.ResultCode; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -12,8 +14,6 @@ import org.springframework.stereotype.Component; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; @Component public class AuthEntryPointJwt implements AuthenticationEntryPoint { @@ -23,19 +23,11 @@ public class AuthEntryPointJwt implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - logger.error("Unauthorized error: {}", authException.getMessage()); - + logger.error("未登录: {}", authException.getMessage()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - - final Map body = new HashMap<>(); - body.put("status", HttpServletResponse.SC_UNAUTHORIZED); - body.put("error", "Unauthorized"); - body.put("message", authException.getMessage()); - body.put("path", request.getServletPath()); - final ObjectMapper mapper = new ObjectMapper(); - mapper.writeValue(response.getOutputStream(), body); + mapper.writeValue(response.getOutputStream(), R.error(ResultCode.ACCESS_UNAUTHORIZED)); } } \ No newline at end of file diff --git a/server/src/main/java/com/jixialunbi/security/CustomAccessDeniedHandler.java b/server/src/main/java/com/jixialunbi/security/CAccessDeniedHandler.java similarity index 65% rename from server/src/main/java/com/jixialunbi/security/CustomAccessDeniedHandler.java rename to server/src/main/java/com/jixialunbi/security/CAccessDeniedHandler.java index 91f3e29..2bc8b50 100644 --- a/server/src/main/java/com/jixialunbi/security/CustomAccessDeniedHandler.java +++ b/server/src/main/java/com/jixialunbi/security/CAccessDeniedHandler.java @@ -1,6 +1,7 @@ package com.jixialunbi.security; -import jakarta.servlet.ServletException; +import com.jixialunbi.common.result.ResultCode; +import com.jixialunbi.common.utils.ResponseUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.AccessDeniedException; @@ -10,12 +11,9 @@ import java.io.IOException; @Component -public class CustomAccessDeniedHandler implements AccessDeniedHandler { - +public class CAccessDeniedHandler implements AccessDeniedHandler { @Override - public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - response.getWriter().write("Forbidden"); + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { + ResponseUtils.writeErrMsg(response, ResultCode.ACCESS_UNAUTHORIZED); } - -} \ No newline at end of file +} diff --git a/server/src/main/java/com/jixialunbi/security/MyAccessDeniedHandler.java b/server/src/main/java/com/jixialunbi/security/MyAccessDeniedHandler.java deleted file mode 100644 index 05867f5..0000000 --- a/server/src/main/java/com/jixialunbi/security/MyAccessDeniedHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.jixialunbi.security; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.stereotype.Component; - -import java.io.IOException; - -@Component -public class MyAccessDeniedHandler implements AuthenticationFailureHandler { - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - response.setCharacterEncoding("UTF-8"); - response.setContentType("application/json"); - response.getWriter().println("禁止访问"); - response.getWriter().flush(); - } -} diff --git a/server/src/main/java/com/jixialunbi/service/AuthService.java b/server/src/main/java/com/jixialunbi/service/AuthService.java index a38f730..780c963 100644 --- a/server/src/main/java/com/jixialunbi/service/AuthService.java +++ b/server/src/main/java/com/jixialunbi/service/AuthService.java @@ -21,7 +21,6 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -80,7 +79,7 @@ public CommandResponse signup(@Valid UserRequest request) { user.setEmail(request.getEmail()); user.setPassword(encoder.encode(request.getPassword().trim())); // add default role to the user - user.setRoles(new HashSet<>(Arrays.asList(new Role(1L, RoleType.ROLE_USER)))); + user.setRoles(new HashSet<>(List.of(new Role(1L, RoleType.ROLE_USER)))); userRepository.save(user); log.info(CREATED_USER); return CommandResponse.builder().id(user.getId()).build(); diff --git a/server/src/main/java/com/jixialunbi/service/FollowUserService.java b/server/src/main/java/com/jixialunbi/service/FollowUserService.java index 88aae1a..57e118b 100644 --- a/server/src/main/java/com/jixialunbi/service/FollowUserService.java +++ b/server/src/main/java/com/jixialunbi/service/FollowUserService.java @@ -25,10 +25,7 @@ public class FollowUserService { public Boolean isFollow(long userId, long followUserId) { var frs = followUserRepository.findOneByUserIdAndFollowUserId(userId, followUserId); - if (frs == null || frs.getDeleted() != null) { - return false; - } - return true; + return frs != null && frs.getDeleted() == null; } @Transactional diff --git a/server/src/main/java/com/jixialunbi/service/UserService.java b/server/src/main/java/com/jixialunbi/service/UserService.java index 1e8e844..436d895 100644 --- a/server/src/main/java/com/jixialunbi/service/UserService.java +++ b/server/src/main/java/com/jixialunbi/service/UserService.java @@ -11,8 +11,8 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import static com.jixialunbi.common.Constants.CREATED_USER; @@ -32,7 +32,7 @@ public class UserService { public User create(UserRequest request) { // add default role (ROLE_USER) to the user - final Set roles = new HashSet<>(Arrays.asList(new Role(1L, RoleType.ROLE_USER))); + final Set roles = new HashSet<>(List.of(new Role(1L, RoleType.ROLE_USER))); // add ROLE_ADMIN role if requested by admin if (request.getRoles() != null && request.getRoles().contains(RoleType.ROLE_ADMIN.name())) diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 21306c9..55cc58d 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -16,9 +16,9 @@ spring: username: ${DB_USERNAME} password: ${DB_PASSWORD} jpa: - hibernate: - ddl-auto: update - show-sql: true +# hibernate: +# ddl-auto: update +# show-sql: true properties: hibernate.format_sql: true hibernate: