springboot实战学习笔记(3)(Lombok插件、postman测试工具、MD5加密算法、post请求、接口文档、注解、如何在IDEA中设置层级显示包结构、显示接口中的方法)

接着上篇博客学习。上篇博客是已经搭建好了后台的开发环境。现在逐一去开发和完善各个层的接口。首先就是从用户这个模块开始。

springboot实战学习笔记(2)-CSDN博客

目录

1、用户模块需要开发的接口

2、数据库字段采用下划线命名,而实体类里面对应的采用驼峰命名。​编辑

3、Lombok?在编译阶段,为实体类自动生成setter()、getter()、toString()方法。

4、基本的开发流程。

5、分析与实现注册接口。

6、向AI文心一言提问:为什么注册时采用post请求?

7、创建三层中的类

8、每个类依次开始编写代码。

UserController类。

UserService接口。

UserServiceImpl实现类。

UserMapper接口。

9、接口测试(因为还没有写好前端,就要借助一个测试接口工具postman)

10、IDEA中如何让包的层次结构(树),一层一层显示。

11、在IDEA中如何显示包中的接口的方法。

12、Md5Util密文工具类代码。


1、用户模块需要开发的接口
  • 注册
  • 登录
  • 获取用户详细信息
  • 更新用户基本信息
  • 更新用户头像
  • 更新用户密码
2、数据库字段采用下划线命名,而实体类里面对应的采用驼峰命名。
3、Lombok?在编译阶段,为实体类自动生成setter()、getter()、toString()方法。

使用条件:在pom文件中引入依赖,在实体类上添加注解

  • 要安装并启用这个插件(辣椒)。

  • 在pom.xml文件中引入lombok依赖。

  • 然后在需要的实体类上添加注解@Data

  • 测试查看效果。

4、基本的开发流程。

  • 明确需求。清楚的了解用户是如何使用。
  • 阅读接口文档。明确接口的输入和输出。
  • 思路分析。分析将来如何写代码、逻辑是啥?
  • 开发。
  • 测试。测试接口的正确性。
5、分析与实现注册接口。
  • 注册就是用户在表单里面填写用户名、密码,再点击注册按钮。接着会在后台添加新用户。
  • 查看接口开发文档(注册)



  • data。返回给浏览器的主体数据。在案例中,它的格式是JSON格式的(以后基本上都是这个格式的)。
  • 因为所有的响应数据,它的格式都是一样的。所以就去定义一个result类。类里面有三个成员变量,对应着"code"、"message"、"data"。当给浏览器响应一个result对象时,springboot对把这个对象自动的转换为JSON格式的字符串,这样格式就处理好了。
  • result实体类
package com.feisi.pojo;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//统一响应结果
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> {
    private Integer code;//业务状态码  0-成功  1-失败
    private String message;//提示信息
    private T data;//响应数据

    //快速返回操作成功响应结果(带响应数据)
    public static <E> Result<E> success(E data) {
        return new Result<>(0, "操作成功", data);
    }

    //快速返回操作成功响应结果
    public static Result success() {
        return new Result(0, "操作成功", null);
    }

    public static Result error(String message) {
        return new Result(1, message, null);
    }
}
  • 其中注解@NoArgsConstructor与注解@AllArgsConstructor是用lombok提供的自动生成无参构造方法与有参构造方法。
  • 三个静态方法。其中业务状态码"code"为"0"代表成功、"code"为"1"代表失败。然后success()方法如果调用时传入数据data,就new一个Result的对象原封不动装起来。
  • 如果时添加用户或者是添加文章,然后没有什么响应的主体数据,就不需要"data",重写构造方法,"data"里面传一个"null"就行了。
  • 最后一个error()方法,调用时把提示的错误信息传进来,内部new一个Result,响应状态码为"1",然后"data"为"null"就行了。
  • 请求路径:"/user"在UserController外层声明。

  • 如何快速关闭所有打开的标签页

6、向AI文心一言提问:为什么注册时采用post请求?

在Web开发中,注册用户时采用POST请求而不是GET请求,主要是基于以下几个原因:

  • 数据安全性:POST请求用于提交表单数据到服务器,这些数据包括用户名、密码等敏感信息。与GET请求不同,POST请求的数据不会附加在URL之后,因此不会在浏览器的历史记录、服务器日志或代理服务器日志中留下痕迹,从而提高了数据的安全性。
  • 数据长度限制:GET请求通过URL传递数据,而URL的长度是有限制的(浏览器和服务器都可能对URL长度有限制)。这限制了可以通过GET请求发送的数据量。相反,POST请求通过HTTP请求体发送数据,可以发送大量数据,适合用于注册表单等需要传输大量信息的场景。
  • 数据可见性:GET请求的数据会直接显示在URL中,这可能不是所有信息都希望被用户或第三方看到的(例如密码)。而POST请求的数据是包含在HTTP请求体中,对用户不可见,更符合注册等需要保护用户隐私的场景。
  • 可缓存性:GET请求是可以被缓存的,这意味着浏览器或中间代理服务器可能会存储GET请求的响应,并在后续请求中直接使用缓存的数据。然而,对于注册等提交表单的POST请求,由于每次提交的数据都可能不同,因此不应该被缓存。
  • 语义明确性:HTTP协议中定义了GET和POST的不同语义。GET请求通常用于请求服务器发送资源,而POST请求则用于向服务器提交数据以进行处理(如提交表单数据)。因此,在注册用户时,使用POST请求更符合HTTP协议的设计初衷。

综上所述,注册时采用POST请求是为了保护用户数据的安全性、传输大量数据、避免敏感信息泄露、避免不必要的缓存,以及符合HTTP协议的语义。

7、创建三层中的类
  • 在controller包下new一个类"UserController"。

  • new一个"UserService"(接口)。然后在impl包下提供一个实现类"UserServiceImpl"去实现接口"UserService"就行了。

  • mapper包下new一个"UserMapper"(接口)。

8、每个类依次开始编写代码。
  • UserController类。

(1)首先在类上面添加注解@ResultController与注解@RequestMapping,并且需求指定请求的映射路径"/user"。

@RestController
@RequestMapping("/user")
  • 将来要用到UserService。就要去类里面注入service对象。
@Autowired
    private UserService userService;

(2)其次在register()方法上添加注解@PostMapping(因为注册接口的请求方式是post)并且添加映射地址"/register"。

@PostMapping("/register")
  • 查询用户(根据用户名查询,查看是否被占用已注册)
  • 注册用户
import com.feisi.pojo.Result;
import com.feisi.pojo.User;
import com.feisi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Title: UserController
 * @Author HeYouLong
 * @Package com.feisi.controller
 * @Date 2024/9/17 下午1:51
 * @description:
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/register")
    public Result register(String username, String password) {
        //查询用户
        User user = userService.findByName(username);
        if(user==null){
            //没有占用
            //注册
            userService.register(username,password);
            return Result.success();
        }else {
            //被占用
            return Result.error("用户名已被占用");
        }
    }
}

  • UserService接口。

(1)在"UserController"类里面注入service对象报错原因。解决:去实现类"UserControllerImpl"添加注解@Service

package com.feisi.service;

import com.feisi.pojo.User;

/**
 * @Title: UserService
 * @Author HeYouLong
 * @Package com.feisi.service
 * @Date 2024/9/17 下午2:00
 * @description:
 */
public interface UserService {

    //根据用户名查询用户
    User findByName(String username);

    //注册
    void register(String username, String password);
}
  • UserServiceImpl实现类。

(1)在这个类上面添加注解@Service,将当前这个类的对象注入到容器里面。

@Service

(2)在实现类"UserServiceImpl"里面调用mapper层里的方法,进行数据的处理(sql语句)那么就要在实现类"UserServiceImpl"里面注入"UserMapper"对象。

@Autowired
    private UserMapper userMapper;

(3)在处理注册时,要进行数据库加密,因为不能直接看到数据表里数据。加密完成之后,就可以调用mapper层的方法去注册添加用户。

  • 加密一般使用MD5加密算法完成。使用一个工具类"Md5Util"。这个类里面提供了一个方法getMD5String():它能够传进一个明文的密码,返回一个密文的密码
package com.feisi.service.impl;

import com.feisi.mapper.UserMapper;
import com.feisi.pojo.User;
import com.feisi.service.UserService;
import com.feisi.utils.Md5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Title: UserServiceImpl
 * @Author HeYouLong
 * @Package com.feisi.service.impl
 * @Date 2024/9/17 下午2:03
 * @description:
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User findByName(String username) {
       User user = userMapper.findByUserName(username);
        return user;
    }

    @Override
    public void register(String username, String password) {
        //加密处理
        //传入明文密码,返回一个密文密码
        String md5String = Md5Util.getMD5String(password);
        //添加,注意传入的密码是加密后的字符串
        userMapper.add(username,md5String);
    }
}

  • UserMapper接口。

(1)在里面添加两个抽象方法(findByUserName()、add())

(2)在每个方法上添加注解@Select("")、@Insert(""),书写sql语句。

(3)记得在接口上添加注解@Mapper。

@Mapper

package com.feisi.mapper;

import com.feisi.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

/**
 * @Title: UserMapper
 * @Author HeYouLong
 * @Package com.feisi.mapper
 * @Date 2024/9/17 下午2:10
 * @description:
 */
@Mapper
public interface UserMapper {

    //根据用户名查询用户
    @Select("select * from user where username = #{username}")
    User findByUserName(String username);


    //添加
    //注意换行后,values前面有一个空格
    //now函数,获取当前数据库的时间
    @Insert("insert into user(username,password,create_time,update_time)" +
            " values(#{username},#{password},now(),now())")
    void add(String username, String password);
}
9、接口测试(因为还没有写好前端,就要借助一个测试接口工具postman
  • 中文翻译版的postman官网。

PostMan中文文档icon-default.png?t=O83Ahttps://postman.org.cn/

  • 官网中注册一个免费的账号(用户)。
  • 安装并打开该软件工具。

  • 打开后第一件事情就是创建工作空间。点击左上角的workspaces —>createWorkspace——>点击next——>起一个名字Name——>点击create。



  • 第二件事情就是创建一个工作集(Collections)。这里直接导入已经创建好的file。


  • 可以看到所有后面要测试目录的用例

  • 这里只写了注册的相关接口操作。所以只看注册的先。

  • 出现报错("500"可能是sql语句写错了的原因)

出现"406"。解决:因为在前面的Result类里面没有添加注解@Data,然后编译的时候,就不能自动的提供getter()、setter()等等方法,不然框架就没法把Result对象转换JSON字符串。

  • 修改好之后,重新启动springboot工程。再次在postman中测试接口。操作成功后,检查数据库是否有数据!


  • 再添加进去一次试试,看看返回的结果。

10、IDEA中如何让包的层次结构(树),一层一层显示。
  • 不勾选压缩空的中间软件包(英文:"Compact Middle Packages")

  • 若勾选了它,就会如下显示,本人觉得不方便。

11、在IDEA中如何显示包中的接口的方法。
  • 勾选显示成员(英文:"Show Members")

12、Md5Util密文工具类代码。
package com.feisi.utils;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {
    /**
     * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
     */
    protected static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    protected static MessageDigest messagedigest = null;

    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsaex) {
            System.err.println(Md5Util.class.getName() + "初始化失败,MessageDigest不支持MD5Util。");
            nsaex.printStackTrace();
        }
    }

    /**
     * 生成字符串的md5校验值
     *
     * @param s
     * @return
     */
    public static String getMD5String(String s) {
        return getMD5String(s.getBytes());
    }

    /**
     * 判断字符串的md5校验码是否与一个已知的md5码相匹配
     *
     * @param password  要校验的字符串
     * @param md5PwdStr 已知的md5校验码
     * @return
     */
    public static boolean checkPassword(String password, String md5PwdStr) {
        String s = getMD5String(password);
        return s.equals(md5PwdStr);
    }


    public static String getMD5String(byte[] bytes) {
        messagedigest.update(bytes);
        return bufferToHex(messagedigest.digest());
    }

    private static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }

    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>>
        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值