电商生鲜网站开发(二)——后台开发:用户模块
接口设计
https://blog.csdn.net/a2272062968/article/details/123385857
开发任务与知识点
登录
注册
重名校验
@Override
public void register(String userName, String password) throws MallException, NoSuchAlgorithmException {
User result = userMapper.selectByName(userName);
if (result != null) {
throw new MallException(MallExceptionEnum.NAME_EXISTED);
}
User user = new User();
user.setUsername(userName);
user.setPassword(MD5Utils.getMD5Str(password));
int count = userMapper.insertSelective(user);
if (count == 0) {
throw new MallException(MallExceptionEnum.INSERT_FAILED);
}
}
密码加密存储
MD5加密类
package com.learn2333.freshmall.util;
import com.learn2333.freshmall.common.Constant;
import org.apache.tomcat.util.codec.binary.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
public static String getMD5Str(String strValue) throws NoSuchAlgorithmException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
return Base64.encodeBase64String(md5.digest((strValue+ Constant.SALT).getBytes()));
}
}
Session的使用(保存登录信息)用户控制层,登录时增加用户对象(抹除密码信息),退出时清空用户对象
越权交验(没有登录不能修改、只能修改自己用户的)
统一响应对象
package com.learn2333.freshmall.common;
import com.learn2333.freshmall.exception.MallExceptionEnum;
public class ApiRestResponse<T> {
private Integer status;
private String msg;
private T data;
private static final int OK_CODE = 10000;
private static final String OK_MSG = "SUCCESS";
public ApiRestResponse(Integer status, String msg, T data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public ApiRestResponse(Integer status, String msg) {
this.status = status;
this.msg = msg;
}
public ApiRestResponse() {
this(OK_CODE, OK_MSG);
}
public static <T> ApiRestResponse<T> success() {
return new ApiRestResponse<>();
}
public static <T> ApiRestResponse<T> success(T result) {
ApiRestResponse<T> response = new ApiRestResponse<>();
response.setData(result);
return response;
}
public static <T> ApiRestResponse<T> error(Integer code, String msg) {
return new ApiRestResponse<>(code, msg);
}
public static <T> ApiRestResponse<T> error(MallExceptionEnum ex) {
return new ApiRestResponse<>(ex.getCode(), ex.getMsg());
}
@Override
public String toString() ...
get,set方法
}
异常枚举
Java异常体系
Postman实操
统一异常处理(使用过滤器)
更新个人信息
另外系统中的常量可定义常量类存储
package com.learn2333.freshmall.common;
public class Constant {
public static final String SALT = "https://learn2333.com/666";
public static final String MALL_USER = "mall_user";
}
案例:注册接口
@PostMapping("/register")
@ResponseBody
public ApiRestResponse register(@RequestParam("userName") String userName,@RequestParam("password") String password)
完成注册接口交验,用户名,密码
如果交验失败返回创建的通用返回对象
通用返回对象类中包含状态码,信息,范型的data,构造方法返回成功状态码,如果失败则可以传入定义的异常枚举
异常枚举中存放着所有异常的状态码和信息
交验通过调用userService中的register注册接口
注册接口实现内容要先查询交验用户名是否为存在,如果存在直接抛出自定义的通用异常即可
自定义的通用异常接收异常枚举,每次要抛出不同的异常信息定义异常枚举传入再抛出即可
如果用户名不存在正常注册
UserMapper中定义selectByName查询用户名,返回user对象
转到mapper.xml书写sql语句
userMapper.insertSelective(user) 方法是插入user中不为空的数据,该方法会返回一个数字代表修改了几条数据
判断如果返回的书==0,则插入失败,抛出自定义的数据插入失败自定义异常类并传入异常枚举
回到控制类,返回自定义的通用返回对象成功ApiRestResponse.success() (如果此前失败了则不会执行到此,直接被抛出异常了)
使用Postman测试post接口
统一处理异常
目的是对前端结构统一保证安全,因为post请求一个接口如果出现异常可能返回许多不同的参数
抛出异常,直接转化为Json的APIResponse
抛出重名异常
之前的请求返回
统一异常后的返回
GlobalExceptionHandler.java 开发过滤器处理异常
package com.learn2333.freshmall.exception;
import com.learn2333.freshmall.common.ApiRestResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseBody
public Object handleException(Exception e) {
log.error("Default Exception: ", e);
return ApiRestResponse.error(MallExceptionEnum.SYSTEM_ERROR);
}
@ExceptionHandler(MallException.class)
@ResponseBody
public Object handleMallException(MallException e) {
log.error("MallException: ", e);
return ApiRestResponse.error(e.getCode(), e.getMessage());
}
}
自定义异常类
package com.learn2333.freshmall.exception;
public class MallException extends Exception {
private final Integer code;
private final String message;
public MallException(Integer code, String msg) {
this.code = code;
this.message = msg;
}
public MallException(MallExceptionEnum exceptionEnum) {
this(exceptionEnum.getCode(), exceptionEnum.getMsg());
}
get方法
}
根据程序开发过程需要增加自定义的异常枚举信息来配合异常类抛出
package com.learn2333.freshmall.exception;
public enum MallExceptionEnum {
NEED_USER_NAME(10001, "用户名不能为空"),
NEED_PASSWORD(10002, "密码不能为空"),
PASSWORD_TOO_SHORT(10003, "密码长度不能小于8位"),
NAME_EXISTED(10004, "注册失败,不允许重名"),
INSERT_FAILED(10005, "数据插失败入"),
WRONG_PASSWORD(10006, "密码错误"),
NEED_LOGIN(10007, "用户未登录"),
UPDATE_FAILED(10008, "更新失败"),
NEED_ADMIN(10009, "无管理员权限"),
SYSTEM_ERROR(20000, "系统异常");
Integer code;
String msg;
MallExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
get,set方法
}
Java异常体系
案例:登录接口
功能分析
登录状态要保持
session保存用户信息的实现方案
之后的访问,会先从session中获取用户信息,然后在执行业务逻辑
总结:
定义返回统一响应对象ApiRestResponse
登录状态使用session保持
统一异常处理,自定义异常枚举从底层不断向上抛出,使用ApiRestResponse返回异常信息
常见错误:
响应对象不规范(返回参数不一致等)
异常不统一处理,存在安全隐患
|