【探花交友】day02—完善个人信息(四)

简介: 【探花交友】day02—完善个人信息(四)

3.3、代码实现

3.3.1、ThreadLocal工具类

定义ThreadLocal工具类,仅需要调用set方法即可将数据存入ThreadLocal中

1. /**
2.  * 工具类:实现向threadlocal存储数据的方法
3.  */
4. public class UserHolder {
5. 
6.     private static ThreadLocal<User> tl = new ThreadLocal<>();
7. 
8. 
9.     //将用户对象,存入Threadlocal
10.     public static void set(User user) {
11.         tl.set(user);
12.     }
13. 
14.     //从当前线程,获取用户对象
15.     public static User get() {
16.         return tl.get();
17.     }
18. 
19.     //从当前线程,获取用户对象的id
20.     public static Long getUserId() {
21.         return tl.get().getId();
22.     }
23. 
24.     //从当前线程,获取用户对象的手机号码
25.     public static String getMobile() {
26.         return tl.get().getMobile();
27.     }
28. }

3.3.2、定义拦截器

定义拦截器,在前置拦截方法preHandle中解析token并验证有效性,如果失效返回状态码401。如果有效,解析User对象,存入ThreadLocal中

1. public class TokenInterceptor implements HandlerInterceptor {
2. 
3.     @Override
4.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
5. 
6.         //1、获取请求头
7.         String token = request.getHeader("Authorization");
8. 
9.         //2、使用工具类,判断token是否有效
10.         boolean verifyToken = JwtUtils.verifyToken(token);
11.         //3、如果token失效,返回状态码401,拦截 
12.         if(!verifyToken) {
13.             response.setStatus(401);
14.             return false;
15.         }
16.         //4、如果token正常可用,放行
17. 
18.         //解析token,获取id和手机号码,构造User对象,存入Threadlocal
19.         Claims claims = JwtUtils.getClaims(token);
20.         String mobile = (String) claims.get("mobile");
21.         Integer id = (Integer) claims.get("id");
22. 
23.         User user = new User();
24.         user.setId(Long.valueOf(id));
25.         user.setMobile(mobile);
26. 
27.         UserHolder.set(user);
28. 
29.         return true;
30.     }
31. }

3.3.3、注册拦截器

拦截器需要注册到MVC容器中

1. @Configuration
2. public class WebConfig  implements WebMvcConfigurer {
3. 
4.     @Override
5.     public void addInterceptors(InterceptorRegistry registry) {
6.         registry.addInterceptor(new TokenInterceptor())
7.                 .addPathPatterns("/**")
8.                 .excludePathPatterns(new String[]{"/user/login","/user/loginVerification"});
9.     }
10. }

3.3.4、测试

修改UsersController方法,从ThreadLoca中获取用户数据

1. /**
2.  * 查询用户资料
3.  */
4. @GetMapping
5. public ResponseEntity users(Long userID) {
6.     if(userID == null) {
7.         userID = UserHolder.getUserId();
8.     }
9.     UserInfoVo userInfo = userInfoService.findById(userID);
10.     return ResponseEntity.ok(userInfo);
11. }

4、统一异常处理

软件开发过程中,不可避免的是需要处理各种异常,常见的形式就是逐层向上抛出,web层进行处理。使用try {...} catch {...}很方便就能对异常做到业务处理

  1. 冗余代码多,影响代码可读性
  2. 异常处理和业务代码耦合

4.1、解决方案

SpringMVC提供了一套解决全局异常的处理方案,可以在代码无侵入的前提下完成异常处理。遵循逐层抛出,异常处理器统一处理的思路

 

4.2、代码实现

项目中可能存在不可预知的各种异常,如:空指针,数组越界等。针对这类异常,可以直接在异常处理器中统一处理;

还有一类是可预知的错误,如图片不合法,验证码错误等等。这类错误也可以理解为业务异常,可以通过自定义异常类来处理;

4.2.1、业务异常对象

为了方便操作,将一些常见的业务错误封装到ErrorResult对象中

1. @Data
2. @NoArgsConstructor
3. @AllArgsConstructor
4. @Builder
5. public class ErrorResult {
6. 
7.     private String errCode = "999999";
8.     private String errMessage;
9. 
10.     public static ErrorResult error() {
11.         return ErrorResult.builder().errCode("999999").errMessage("系统异常稍后再试").build();
12.     }
13. 
14.     public static ErrorResult fail() {
15.         return ErrorResult.builder().errCode("000001").errMessage("发送验证码失败").build();
16.     }
17. 
18.     public static ErrorResult loginError() {
19.         return ErrorResult.builder().errCode("000002").errMessage("验证码失效").build();
20.     }
21. 
22.     public static ErrorResult faceError() {
23.         return ErrorResult.builder().errCode("000003").errMessage("图片非人像,请重新上传!").build();
24.     }
25. 
26.     public static ErrorResult mobileError() {
27.         return ErrorResult.builder().errCode("000004").errMessage("手机号码已注册").build();
28.     }
29. 
30.     public static ErrorResult contentError() {
31.         return ErrorResult.builder().errCode("000005").errMessage("动态内容为空").build();
32.     }
33. 
34.     public static ErrorResult likeError() {
35.         return ErrorResult.builder().errCode("000006").errMessage("用户已点赞").build();
36.     }
37. 
38.     public static ErrorResult disLikeError() {
39.         return ErrorResult.builder().errCode("000007").errMessage("用户未点赞").build();
40.     }
41. 
42.     public static ErrorResult loveError() {
43.         return ErrorResult.builder().errCode("000008").errMessage("用户已喜欢").build();
44.     }
45. 
46.     public static ErrorResult disloveError() {
47.         return ErrorResult.builder().errCode("000009").errMessage("用户未喜欢").build();
48.     }
49. }

4.2.2 业务异常类

自定义业务异常类,针对业务错误之间抛出业务异常即可

1. /**
2.  * 自定义异常类
3.  */
4. @Data
5. public class BusinessException extends RuntimeException {
6. 
7.     private ErrorResult errorResult;
8. 
9.     public BusinessException(ErrorResult errorResult) {
10.         super(errorResult.getErrMessage());
11.         this.errorResult = errorResult;
12.     }
13. }

4.2.3、异常处理器

1. /**
2.  * 自定义统一异常处理
3.  *  1、通过注解,声明异常处理类
4.  *  2、编写方法,在方法内部处理异常,构造响应数据
5.  *  3、方法上编写注解,指定此方法可以处理的异常类型
6.  */
7. @ControllerAdvice
8. public class ExceptionAdvice {
9. 
10.     //处理业务异常
11.     @ExceptionHandler(BusinessException.class)
12.     public ResponseEntity handlerException(BusinessException be) {
13.         be.printStackTrace();
14.         ErrorResult errorResult = be.getErrorResult();
15.         return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResult);
16.     }
17. 
18.     //处理不可预知的异常
19.     @ExceptionHandler(Exception.class)
20.     public ResponseEntity handlerException1(Exception be) {
21.         be.printStackTrace();
22.         return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResult.error());
23.     }
24. }
相关文章
|
人工智能 测试技术 API
【探花交友】day02—完善个人信息(二)
【探花交友】day02—完善个人信息(二)
229 0
|
3天前
|
前端开发 JavaScript 开发者
惊!这些前端技术竟然能让你的网站在社交媒体上疯传!
【10月更文挑战第30天】在这个信息爆炸的时代,社交媒体成为内容传播的重要渠道。本文介绍了前端开发者如何利用技术让网站内容在社交媒体上疯传,包括优化分享链接、创建引人注目的标题和描述、利用Open Graph和Twitter Cards、实现一键分享功能以及创造交互式内容。通过这些方法,提升用户分享意愿,使网站成为社交媒体上的热门话题。
11 2
|
5月前
|
前端开发 Java 关系型数据库
杨校老师项目之基于SSM社区疫情防控人员访客登记报备平台
杨校老师项目之基于SSM社区疫情防控人员访客登记报备平台
34 0
|
存储 前端开发 API
【探花交友】day02—完善个人信息(三)
【探花交友】day02—完善个人信息(三)
116 0
|
存储 云安全 安全
【探花交友】day02—完善个人信息(一)
【探花交友】day02—完善个人信息
142 0
|
消息中间件 NoSQL 前端开发
【探花交友】day06—即时通信(一)
【探花交友】day06—即时通信
178 0
|
Dubbo NoSQL 应用服务中间件
【探花交友】day06—即时通信(四)
【探花交友】day06—即时通信(四)
180 0
|
JSON 测试技术 API
【探花交友】day06—即时通信(二)
【探花交友】day06—即时通信(二)
117 0
|
NoSQL 程序员 API
【探花交友】day06—即时通信(三)
【探花交友】day06—即时通信(三)
117 0
|
API
【探花交友】day04—圈子功能实现(三)
【探花交友】day04—圈子功能实现(三)
82 0