feat(初始化): 登录请求实现,和全局异常错误捕获
This commit is contained in:
parent
bcbc312dc3
commit
919e428e9e
|
@ -0,0 +1,7 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="RawUseOfParameterizedType" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="UNCHECKED_WARNING" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
|
@ -19,11 +19,6 @@
|
|||
|
||||
<dependencies>
|
||||
<!-- 自己的模块 -->
|
||||
<dependency>
|
||||
<groupId>com.atguigu</groupId>
|
||||
<artifactId>common-util</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atguigu</groupId>
|
||||
<artifactId>spzx-model</artifactId>
|
||||
|
|
|
@ -12,7 +12,7 @@ public class Knife4jConfig {
|
|||
@Bean
|
||||
public GroupedOpenApi adminApi() {
|
||||
return GroupedOpenApi.builder() // 分组名称
|
||||
.group("admin-api").pathsToMatch("/admin/**") // 接口请求路径规则
|
||||
.group("admin请求接口").pathsToMatch("/admin/**") // 接口请求路径规则
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,6 @@ public class Knife4jConfig {
|
|||
public OpenAPI customOpenAPI() {
|
||||
return new OpenAPI().info(new Info().title("尚品甑选API接口文档")
|
||||
.version("1.0").description("尚品甑选API接口文档")
|
||||
.contact(new Contact().name("atguigu"))); // 设定作者
|
||||
.contact(new Contact().name("bunny"))); // 设定作者
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ public class BunnyException extends RuntimeException {
|
|||
|
||||
public BunnyException(String message) {
|
||||
super(message);
|
||||
log.error("业务异常:{}", message);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public BunnyException(ResultCodeEnum codeEnum) {
|
|
@ -0,0 +1,12 @@
|
|||
package com.atguigu.exception;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EnumException {
|
||||
public static final String USER_NOT_FOUND = "用户不存在";
|
||||
public static final String USERNAME_IS_EMPTY = "用户名不能为空";
|
||||
public static final String PASSWORD_ERROR = "密码错误";
|
||||
public static final String PASSWORD_IS_EMPTY = "密码不能为空";
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.atguigu.handler;
|
||||
|
||||
|
||||
import com.atguigu.constant.MessageConstant;
|
||||
import com.atguigu.exception.BunnyException;
|
||||
import com.atguigu.spzx.model.vo.result.Result;
|
||||
import com.atguigu.spzx.model.vo.result.ResultCodeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import java.nio.file.AccessDeniedException;
|
||||
import java.sql.SQLIntegrityConstraintViolationException;
|
||||
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
// 自定义异常信息
|
||||
@ExceptionHandler(BunnyException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> exceptionHandler(BunnyException exception) {
|
||||
log.error("自定义异常信息:{}", exception.getMessage());
|
||||
return Result.error(exception.getCode(), exception.getMessage());
|
||||
}
|
||||
|
||||
// 运行时异常信息
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> exceptionHandler(RuntimeException exception) {
|
||||
log.error("运行时异常信息:{}", exception.getMessage());
|
||||
return Result.error(500, exception.getMessage());
|
||||
}
|
||||
|
||||
// 捕获系统异常
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public Result<Object> error(Exception exception) {
|
||||
log.error("系统异常信息:{}", exception.getMessage());
|
||||
return Result.error(exception.getMessage());
|
||||
}
|
||||
|
||||
// 特定异常处理
|
||||
@ExceptionHandler(ArithmeticException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> error(ArithmeticException exception) {
|
||||
log.error("特定异常信息:{}", exception.getMessage());
|
||||
return Result.error(null, exception.getMessage());
|
||||
}
|
||||
|
||||
// spring security异常
|
||||
@ExceptionHandler(AccessDeniedException.class)
|
||||
@ResponseBody
|
||||
public Result<String> error(AccessDeniedException e) throws AccessDeniedException {
|
||||
return Result.error(ResultCodeEnum.PERMISSION);
|
||||
}
|
||||
|
||||
// 处理SQL异常
|
||||
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
|
||||
@ResponseBody
|
||||
public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException exception) {
|
||||
log.error("处理SQL异常:{}", exception.getMessage());
|
||||
String message = exception.getMessage();
|
||||
if (message.contains("Duplicate entry")) {
|
||||
// 截取用户名
|
||||
String username = message.split(" ")[2];
|
||||
// 错误信息
|
||||
String errorMessage = username + MessageConstant.ALREADY_EXISTS;
|
||||
return Result.error(exception.getMessage());
|
||||
} else {
|
||||
return Result.error(MessageConstant.UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -40,5 +40,10 @@
|
|||
<artifactId>minio</artifactId>
|
||||
<version>8.5.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atguigu</groupId>
|
||||
<artifactId>common-service</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package com.atguigu.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
@Slf4j
|
||||
public class LoginFailedException extends BunnyException {
|
||||
/**
|
||||
* Constructs a new runtime exception with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public LoginFailedException() {
|
||||
}
|
||||
|
||||
public LoginFailedException(String message) {
|
||||
super(message);
|
||||
log.error("登录失败:{}", message);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.atguigu.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 密码错误异常
|
||||
*/
|
||||
@Slf4j
|
||||
public class PasswordErrorException extends BunnyException {
|
||||
/**
|
||||
* Constructs a new runtime exception with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public PasswordErrorException() {
|
||||
}
|
||||
|
||||
public PasswordErrorException(String message) {
|
||||
super(message);
|
||||
log.error("密码错误异常:{}", message);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.atguigu.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 用户未登录异常
|
||||
*/
|
||||
@Slf4j
|
||||
public class UserNotLoginException extends BunnyException {
|
||||
/**
|
||||
* Constructs a new runtime exception with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public UserNotLoginException() {
|
||||
}
|
||||
|
||||
public UserNotLoginException(String message) {
|
||||
super(message);
|
||||
log.error("用户未登录异常:{}", message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.atguigu.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public final class MD5 {
|
||||
public static String encrypt(String strSrc) {
|
||||
try {
|
||||
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
byte[] bytes = strSrc.getBytes();
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(bytes);
|
||||
bytes = md.digest();
|
||||
int j = bytes.length;
|
||||
char[] chars = new char[j * 2];
|
||||
int k = 0;
|
||||
for (byte b : bytes) {
|
||||
chars[k++] = hexChars[b >>> 4 & 0xf];
|
||||
chars[k++] = hexChars[b & 0xf];
|
||||
}
|
||||
return new String(chars);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("MD5加密出错!!+" + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(MD5.encrypt("111111"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.atguigu.utils;
|
||||
|
||||
import com.atguigu.exception.BunnyException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class StringEmptyUtil {
|
||||
/**
|
||||
* 判断内容是否为空
|
||||
*
|
||||
* @param val 值
|
||||
* @param errorMessage 如果为空的错误信息
|
||||
*/
|
||||
public void isEmpty(Object val, String errorMessage) {
|
||||
if (val == null || val.toString().isEmpty()) {
|
||||
throw new BunnyException(null, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -54,5 +54,11 @@
|
|||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atguigu</groupId>
|
||||
<artifactId>common-util</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
package com.atguigu.spzx.manger.controller;
|
||||
|
||||
import com.atguigu.spzx.manger.service.SysUserService;
|
||||
import com.atguigu.spzx.model.dto.system.LoginDto;
|
||||
import com.atguigu.spzx.model.vo.result.Result;
|
||||
import com.atguigu.spzx.model.vo.result.ResultCodeEnum;
|
||||
import com.atguigu.spzx.model.vo.system.LoginVo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
@ -8,4 +17,13 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
@RestController
|
||||
@RequestMapping("/admin/system/index")
|
||||
public class IndexController {
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Operation(summary = "登录请求", description = "登录请求实现")
|
||||
@PostMapping("login")
|
||||
public Result<LoginVo> login(@RequestBody LoginDto loginDto) {
|
||||
LoginVo vo = sysUserService.login(loginDto);
|
||||
return Result.success(vo, ResultCodeEnum.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
package com.atguigu.spzx.manger.mapper;
|
||||
|
||||
import com.atguigu.spzx.model.entity.system.SysUser;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserMapper {
|
||||
/**
|
||||
* * 根据username查询用户信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
SysUser selectByUsername(String username);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
package com.atguigu.spzx.manger.service;
|
||||
|
||||
import com.atguigu.spzx.model.dto.system.LoginDto;
|
||||
import com.atguigu.spzx.model.vo.system.LoginVo;
|
||||
|
||||
public interface SysUserService {
|
||||
/**
|
||||
* * 登录请求实现
|
||||
*
|
||||
* @param loginDto 登录请求参数
|
||||
* @return 登录后结果
|
||||
*/
|
||||
LoginVo login(LoginDto loginDto);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,57 @@
|
|||
package com.atguigu.spzx.manger.service.impl;
|
||||
|
||||
import com.atguigu.exception.BunnyException;
|
||||
import com.atguigu.exception.EnumException;
|
||||
import com.atguigu.spzx.manger.mapper.SysUserMapper;
|
||||
import com.atguigu.spzx.manger.service.SysUserService;
|
||||
import com.atguigu.spzx.model.dto.system.LoginDto;
|
||||
import com.atguigu.spzx.model.entity.system.SysUser;
|
||||
import com.atguigu.spzx.model.vo.system.LoginVo;
|
||||
import com.atguigu.utils.MD5;
|
||||
import com.atguigu.utils.StringEmptyUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class SysUserServiceImpl {
|
||||
public class SysUserServiceImpl implements SysUserService {
|
||||
@Autowired
|
||||
StringEmptyUtil stringEmptyUtil;
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* * 登录请求实现
|
||||
*
|
||||
* @param loginDto 登录请求参数
|
||||
* @return 登录后结果
|
||||
*/
|
||||
@Override
|
||||
public LoginVo login(LoginDto loginDto) {
|
||||
String password = loginDto.getPassword();
|
||||
String userName = loginDto.getUserName();
|
||||
stringEmptyUtil.isEmpty(userName, EnumException.USERNAME_IS_EMPTY);
|
||||
stringEmptyUtil.isEmpty(password, EnumException.PASSWORD_IS_EMPTY);
|
||||
|
||||
// 根据username查询用户信息
|
||||
SysUser sysUser = sysUserMapper.selectByUsername(userName);
|
||||
if (sysUser == null) {
|
||||
throw new BunnyException(EnumException.USER_NOT_FOUND);
|
||||
}
|
||||
String encryptedPassword = MD5.encrypt(password);
|
||||
// 比较密码
|
||||
if (!encryptedPassword.equals(sysUser.getPassword())) {
|
||||
throw new BunnyException(EnumException.PASSWORD_ERROR);
|
||||
}
|
||||
// 登录成功
|
||||
String token = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
redisTemplate.opsForValue().set(userName, token, 7, TimeUnit.DAYS);
|
||||
// 返回loginVo对象
|
||||
return LoginVo.builder().token(token).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.atguigu.spzx.manger.mapper.SysUserMapper">
|
||||
|
||||
<!-- 用于select查询公用抽取的列 -->
|
||||
<sql id="columns">
|
||||
id,username userName ,password,name,phone,avatar,description,status,create_time,update_time,is_deleted
|
||||
</sql>
|
||||
<!-- 根据username查询用户信息 -->
|
||||
<select id="selectByUsername" resultType="com.atguigu.spzx.model.entity.system.SysUser">
|
||||
select
|
||||
<include refid="columns"/>
|
||||
from sys_user
|
||||
where username = #{username};
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.atguigu.spzx.manger.mapper.SysUserMapper">
|
||||
|
||||
<!-- 用于select查询公用抽取的列 -->
|
||||
<sql id="columns">
|
||||
id,username userName ,password,name,phone,avatar,description,status,create_time,update_time,is_deleted
|
||||
</sql>
|
||||
<!-- 根据username查询用户信息 -->
|
||||
<select id="selectByUsername" resultType="com.atguigu.spzx.model.entity.system.SysUser">
|
||||
select
|
||||
<include refid="columns"/>
|
||||
from sys_user
|
||||
where username = #{username};
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -95,6 +95,27 @@ public class Result<T> {
|
|||
return build(data, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> success(T data, String message) {
|
||||
return build(data, 200, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param code 状态码
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> success(T data, Integer code, String message) {
|
||||
return build(data, code, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败
|
||||
*/
|
||||
|
@ -129,4 +150,25 @@ public class Result<T> {
|
|||
public static <T> Result<T> error(T data, ResultCodeEnum codeEnum) {
|
||||
return build(data, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param code 状态码
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> error(T data, Integer code, String message) {
|
||||
return build(data, code, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> error(T data, String message) {
|
||||
return build(null, 500, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package com.atguigu.spzx.model.vo.system;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "登录成功响应结果实体类")
|
||||
public class LoginVo {
|
||||
|
||||
@Schema(description = "令牌")
|
||||
private String token ;
|
||||
private String token;
|
||||
|
||||
@Schema(description = "刷新令牌,可以为空")
|
||||
private String refresh_token ;
|
||||
|
||||
private String refresh_token;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue