paopao/docs/tasks/任务8-Sprint-1-获取当前用户信息接口.md
2024-05-14 09:54:01 +08:00

6.2 KiB
Raw Blame History

任务名称: 获取当前用户信息

目标:

  • 了解DTO的使用
  • 掌握mapstruct的使用
  • 掌握如何获取当前用户

预备知识:

  • [列出完成该任务前学生应具备的基础知识或先修技能,如特定编程语言基础、框架了解等。]

操作步骤:

  1. 引入mapstruct依赖

MapStruct是一个开源的Java库它通过注解处理器自动创建对象之间的映射代码。这个库的主要目的是减少在处理对象转换时的手动编写样板代码尤其是当需要在不同领域模型、数据传输对象DTOs或数据库实体之间进行映射时。

使用MapStruct你只需要定义一个映射接口该接口声明了源对象和目标对象之间的转换方法。MapStruct会自动生成接口的实现这个实现包含了实际的属性映射逻辑。这种方法使得映射代码保持清晰、简洁且类型安全。

  1. 创建UserDto类
package com.lk.paopao.dto;

import lombok.Value;
import java.io.Serializable;

@Value
public class UserDto implements Serializable {
    Long id;
    String nickname;
    String username;
    String phone;
    Byte status;
    String avatar;
    Long balance;
    Boolean isAdmin;
}

@Value 是 Lombok 库提供的一个注解,用于简化 Java 类的编写。当这个注解应用在一个类上时Lombok 会自动为类的所有字段生成以下内容:

  • 私有字段Private fields所有字段默认变为私有并且没有公共访问器getter 和 setter
  • 构造器:生成一个全参数的构造器,用于初始化所有字段。
  • final 字段如果字段没有初始化Lombok 会将其声明为 final并要求在构造器中提供初始值。
  • equals() 和 hashCode():生成 equals() 和 hashCode() 方法,基于所有字段进行比较。
  • toString():生成 toString() 方法,显示类实例的字段值。
  • 不可变性Immutability默认情况下类是不可变的这意味着一旦创建对象的状态就不能改变。字段默认都是 final 的,除非显式声明它们不是。
  1. 创建UserMapper接口
package com.lk.paopao.mapper;

import com.lk.paopao.entity.User;
import com.lk.paopao.dto.UserDto;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;

@Mapper(componentModel = "spring")
public interface UserMapper {
    User toEntity(UserDto userDto);

    UserDto toDto(User user);

    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    User partialUpdate(UserDto userDto, @MappingTarget User user);
}

代码中用到的注解解释:

  • @Mapper: 这是一个 MapStruct 注解,用于创建一个映射接口。
  • componentModel = "spring": 这个参数指定了生成的映射器类应该使用 Spring 的组件模型,这样可以在 Spring 应用程序中自动注册。
  • @BeanMapping: 这个注解用于配置映射方法。
  • nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE: 这个参数指定了当目标对象中的某个属性为 null 时,是否忽略该属性的映射。
  • @MappingTarget: 这个注解用于指定目标对象,用于更新目标对象。
  1. 在AuthService中添加获取当前用户方法
/**
     * 获取当前登录的用户详情。
     * @return 当前登录的UserDetails对象
     * @throws AuthFailedException 如果无法获取当前用户详情,则抛出异常
     */
    public UserDetails getCurrentUserDetails() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication.getPrincipal() instanceof UserDetails) {
            return (UserDetails) authentication.getPrincipal();
        }
        throw new AuthFailedException("找不到用户在线信息");
    }

    /**
     * 获取当前登录的用户信息。
     * @return 当前登录的用户信息
     * @throws AuthFailedException 如果无法获取当前用户信息,则抛出异常
     */
    public User getCurrentUser() {
        // 通过当前用户详情获取用户信息
        return userRepository.findByUsername(getCurrentUserDetails().getUsername()).orElseThrow(()->new AuthFailedException("找不到用户在线信息"));
    }
  1. 创建UserService类
package com.lk.paopao.service;

import com.lk.paopao.dto.UserDto;
import com.lk.paopao.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuthService authService;

    /**
     * 获取当前用户的基本信息
     * @return UserDto 当前用户的数据传输对象
     */
    public UserDto info(){
        return userMapper.toDto(authService.getCurrentUser());
    }
}
  1. 创建UserController类
package com.lk.paopao.controller;

import com.lk.paopao.dto.UserDto;
import com.lk.paopao.dto.rest.response.DataResult;
import com.lk.paopao.dto.rest.response.ResultUtil;
import com.lk.paopao.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("${app.version}/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/info")
    public DataResult<UserDto> info() {
        return ResultUtil.ok(userService.info());
    }
}
  1. 测试

技术/工具需求:

  • [列出完成任务所需的技术栈、工具、软件版本等。]

成功标准:

  • [明确完成任务的评判标准,如代码功能实现、性能指标、测试通过条件等。]

扩展学习(可选):

  • [提供一些额外学习资源或挑战性任务,鼓励学有余力的学生进一步探索。]

评估与反馈:

  • [说明如何提交作业、代码审查的标准、或任何反馈收集机制。]

时间估算:

  • [给出预计完成该任务所需的时间,帮助学生合理安排学习计划。]