电商生鲜网站开发(二)——后台开发:用户模块
文章目录
电商生鲜网站开发(二)——后台开发:用户模块接口设计开发任务与知识点案例:注册接口统一处理异常Java异常体系案例:登录接口接口设计
/a2272062968/article/details/123385857
开发任务与知识点
登录
注册
重名校验
@Overridepublic 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(password);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.mon.Constant;import org.apache.tomcat.util.codec.binary.Base64;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/*** MD5工具*/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.mon;import com.learn2333.freshmall.exception.MallExceptionEnum;/*** 通用返回对象*/public class ApiRestResponse<T> {//状态码private Integer status;//信息private String msg;//范型的dataprivate 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);}//成功 返回默认状态码(无参构造函数的2个常量)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());}@Overridepublic String toString() ...get,set方法}
异常枚举
Java异常体系
Postman实操
统一异常处理(使用过滤器)
更新个人信息
另外系统中的常量可定义常量类存储
package com.mon;/*** 常量值*/public class Constant {//用于加密MD5的盐值public static final String SALT = "/666";//session中用户对象的keypublic static final String MALL_USER = "mall_user";}
案例:注册接口
@PostMapping("/register")@ResponseBodypublic 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.mon.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;/*** 处理统一异常的handler*/@ControllerAdvicepublic class GlobalExceptionHandler {private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(Exception.class)@ResponseBodypublic Object handleException(Exception e) {log.error("Default Exception: ", e);return ApiRestResponse.error(MallExceptionEnum.SYSTEM_ERROR);}@ExceptionHandler(MallException.class)@ResponseBodypublic Object handleMallException(MallException e) {log.error("MallException: ", e);return ApiRestResponse.error(e.getCode(), e.getMessage());}}
自定义异常类
package com.learn2333.freshmall.exception;/*** 统一异常*///了解完下面java异常体系后,可知道这里继承可将Exception改为RuntimeException运行时异常,因为这里要抛出的都是我们自定义的异常枚举,这样我们抛出异常的时候就不用再每次都增加方法签名了,而作用上一样的public class MallException extends RuntimeException {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方法}
通过统一返回对象类处理抛出的异常枚举信息并返回失败数据
package com.mon;import com.learn2333.freshmall.exception.MallExceptionEnum;/*** 通用返回对象*/public class ApiRestResponse<T> {//状态码private Integer status;//信息private String msg;//范型的dataprivate 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);}//成功 返回默认状态码(无参构造函数的2个常量)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());}@Overridepublic String toString() {get,set;
Java异常体系
案例:登录接口
功能分析
登录状态要保持
session保存用户信息的实现方案
之后的访问,会先从session中获取用户信息,然后在执行业务逻辑
总结:
定义返回统一响应对象ApiRestResponse
登录状态使用session保持
统一异常处理,自定义异常枚举从底层不断向上抛出,使用ApiRestResponse返回异常信息
常见错误:
响应对象不规范(返回参数不一致等)
异常不统一处理,存在安全隐患