1.3.3、代码实现
UserInfo实体类
1. @Data 2. @NoArgsConstructor 3. @AllArgsConstructor 4. public class UserInfo implements Serializable { 5. 6. /** 7. * 由于userinfo表和user表之间是一对一关系 8. * userInfo的id来源于user表的id 9. */ 10. @TableId(type= IdType.INPUT) 11. private Long id; //用户id 12. private String nickname; //昵称 13. private String avatar; //用户头像 14. private String birthday; //生日 15. private String gender; //性别 16. private Integer age; //年龄 17. private String city; //城市 18. private String income; //收入 19. private String education; //学历 20. private String profession; //行业 21. private Integer marriage; //婚姻状态 22. private String tags; //用户标签:多个用逗号分隔 23. private String coverPic; // 封面图片 24. private Date created; 25. private Date updated; 26. 27. //用户状态,1为正常,2为冻结 28. @TableField(exist = false) 29. private String userStatus = "1"; 30. }
UserController
1. @RestController 2. @RequestMapping("/user") 3. public class UserController { 4. 5. @Autowired 6. private UserInfoService userInfoService; 7. 8. /** 9. * 保存用户信息 10. * UserInfo 11. * 请求头中携带token 12. */ 13. @PostMapping("/loginReginfo") 14. public ResponseEntity loginReginfo(@RequestBody UserInfo userInfo, 15. @RequestHeader("Authorization") String token) { 16. //1、解析token 17. Claims claims = JwtUtils.getClaims(token); 18. Integer id = (Integer) claims.get("id"); 19. //2、向userinfo中设置用户id 20. userInfo.setId(Long.valueOf(id)); 21. //3、调用service 22. userInfoService.save(userInfo); 23. return ResponseEntity.ok(null); 24. } 25. }
UserInfoService
1. @Service 2. public class UserInfoService { 3. 4. @DubboReference 5. private UserInfoApi userInfoApi; 6. 7. public void save(UserInfo userInfo) { 8. userInfoApi.save(userInfo); 9. } 10. }
UserInfoApi
1. public interface UserInfoApi { 2. public void save(UserInfo userInfo); 3. }
UserInfoApiImpl
1. @DubboService 2. public class UserInfoApiImpl implements UserInfoApi { 3. 4. @Autowired 5. private UserInfoMapper userInfoMapper; 6. 7. @Override 8. public void save(UserInfo userInfo) { 9. userInfoMapper.insert(userInfo); 10. } 11. }
UserInfoMapper
1. public interface UserInfoMapper extends BaseMapper<UserInfo> { 2. 3. }
1.4、上传用户头像
1.4.1、需求分析
接口文档
YAPI地址:http://192.168.136.160:3000/project/19/interface/api/91
文件上传采用POST传递,mvc中经过文件解析器转化为MultipartFile对象处理
后续请求中,请求headr中都有Authorization参数。
执行流程
1.4.2、代码实现
UserControler
1. /** 2. * 上传用户头像 3. * @return 4. */ 5. @PostMapping("/loginReginfo/head") 6. public ResponseEntity head(MultipartFile headPhoto,@RequestHeader("Authorization") String token) throws IOException { 7. //1、判断token是合法 8. boolean verifyToken = JwtUtils.verifyToken(token); 9. if(!verifyToken){ 10. return ResponseEntity.status(401).body(null); 11. } 12. //2、向userinfo中设置用户id 13. Claims claims = JwtUtils.getClaims(token); 14. Integer id = (Integer) claims.get("id"); 15. //3、调用service 16. userInfoService.updateHead(headPhoto,id); 17. return ResponseEntity.ok(null); 18. }
UserInfoService
1. //更新用户头像 2. public void updateHead(MultipartFile headPhoto, Long id) throws IOException { 3. //1、将图片上传到阿里云oss 4. String imageUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream()); 5. //2、调用百度云判断是否包含人脸 6. boolean detect = aipFaceTemplate.detect(imageUrl); 7. //2.1 如果不包含人脸,抛出异常 8. if(!detect) { 9. throw new RuntimeException(); 10. }else{ 11. //2.2 包含人脸,调用API更新 12. UserInfo userInfo = new UserInfo(); 13. userInfo.setId(id); 14. userInfo.setAvatar(imageUrl); 15. userInfoApi.update(userInfo); 16. } 17. }
UserInfoApi
public void update(UserInfo userInfo);
UserInfoApiImpl
1. @Override 2. public void update(UserInfo userInfo) { 3. userInfoMapper.updateById(userInfo); 4. }
2、用户信息管理
2.1、查询用户资料
2.1.1、接口文档
YAPI地址:http://192.168.136.160:3000/project/19/interface/api/265
参数userID: 用户id,当不传递时,查询当前用户的资料信息
2.1.2、代码实现
UserInfoVo
1. @Data 2. @NoArgsConstructor 3. @AllArgsConstructor 4. public class UserInfoVo implements Serializable { 5. 6. private Long id; //用户id 7. private String nickname; //昵称 8. private String avatar; //用户头像 9. private String birthday; //生日 10. private String gender; //性别 11. private String age; //年龄 12. private String city; //城市 13. private String income; //收入 14. private String education; //学历 15. private String profession; //行业 16. private Integer marriage; //婚姻状态 17. }
UsersController
1. @RestController 2. @RequestMapping("/users") 3. public class UsersControler { 4. 5. @Autowired 6. private UserInfoService userInfoService; 7. 8. /** 9. * 查询用户资料 10. */ 11. @GetMapping 12. public ResponseEntity users(Long userID,@RequestHeader("Authorization") String token) { 13. if(userID == null) { 14. Claims claims = JwtUtils.getClaims(token); 15. Integer id = (Integer) claims.get("id"); 16. userID = Long.valueOf(id); 17. } 18. UserInfoVo userInfo = userInfoService.findById(userID); 19. return ResponseEntity.ok(userInfo); 20. } 21. }
UserInfoService
1. //根据id查寻 2. public UserInfoVo findById(Long id) { 3. UserInfo userInfo = userInfoApi.findById(id); 4. 5. UserInfoVo vo = new UserInfoVo(); 6. 7. BeanUtils.copyProperties(userInfo,vo); //copy同名同类型的属性 8. 9. if(userInfo.getAge() != null) { 10. vo.setAge(userInfo.getAge().toString()); 11. } 12. 13. return vo; 14. }
UserInfoApiImpl
1. @Override 2. public UserInfo findById(Long id) { 3. return userInfoMapper.selectById(id); 4. }
2.2、更新用户资料
2.2.1、接口文档
YAPI地址:http://192.168.136.160:3000/project/19/interface/api/259
2.2.2、代码实现
UsersController
1. /** 2. * 更新用户资料 3. * @return 4. */ 5. @PutMapping 6. public ResponseEntity updateUserInfo(@RequestBody UserInfo userInfo,@RequestHeader("Authorization") String token){ 7. //1、判断token是否合法 8. boolean verifyToken = JwtUtils.verifyToken(token); 9. if(!verifyToken){ 10. return ResponseEntity.status(401).body(null); 11. } 12. //2、获取用户id 13. Claims claims = JwtUtils.getClaims(token); 14. Integer id = (Integer) claims.get("id"); 15. //3、设置用户id 16. userInfo.setId(Long.valueOf(id)); 17. userInfoService.update(userInfo); 18. return ResponseEntity.ok(null); 19. }
UserInfoService
1. //更新 2. public void update(UserInfo userInfo) { 3. userInfoApi.update(userInfo); 4. }
UserInfoApiImpl
1. @Override 2. public void update(UserInfo userInfo) { 3. userInfoMapper.updateById(userInfo); 4. }
3、统一token处理
3.1、代码存在的问题
3.2、解决方案
基于ThreadLocal + 拦截器的形式统一处理
拦截器(Interceptor)
- 是一种动态拦截方法调用的机制;
- 类似于Servlet 开发中的过滤器Filter,用于对处理器进行前置处理和后置处理。
ThreadLocal
- 线程内部的存储类,赋予了线程存储数据的能力。
- 线程内调用的方法都可以从ThreadLocal中获取同一个对象。
- 多个线程中ThreadLocal数据相互隔离
Threadlocal使用方法很简单
1. ThreadLocal<T> threadLocal = new ThreadLocal<T>(); 2. threadLocal.set() //将数据绑定到当前线程 3. threadLocal.get() //从当前线程中获取数据