1、增加api异常捕获

2、修改调试模式
3、允许增加多个api列表
4、修改保存key逻辑
5、修改前端为Angular,与当前前端不兼容,等待程序中......
This commit is contained in:
Luoye 2020-12-10 17:34:00 +08:00
parent 07395a2e97
commit b680a6da95
18 changed files with 389 additions and 72 deletions

View File

@ -100,13 +100,13 @@
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
<version>3.4.1</version>
</dependency>
<!--Mybatis plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
<version>3.4.1</version>
</dependency>
<!--添加redis缓存依赖-->
<dependency>

View File

@ -1,10 +1,10 @@
package io.qyi.e5.bean.core;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.qyi.e5.util.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@ -25,8 +25,8 @@ import java.io.PrintWriter;
* @author: 落叶随风
* @create: 2020-02-16 01:11
**/
@Aspect
@Component
//@Aspect
//@Component
@Slf4j
public class WebExceptionAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

View File

@ -0,0 +1,29 @@
package io.qyi.e5.config;
import lombok.Getter;
/**
* @program: push
* @description:
* @author: 落叶随风
* @create: 2020-09-30 10:48
**/
@Getter
public enum APiCode {
TOKEN_LENGTH_IS_INCORRECT(10000, "token长度不正确"),
TOKEN_DOES_NOT_EXIST(10000, "token不存在"),
OUTLOOK_QUANTITATIVE(10001, "此账号数量已超过5个"),
GITHUBID_NOT_NULL(10002, "github id 不能为空"),
OUTLOOK_NAME_NOT_NULL(10002, "outlook名称不能为空!"),
OUTLOOK_INSERT_ERROR(10004, "新增失败!");
private int code;
private String msg;
APiCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@ -0,0 +1,27 @@
package io.qyi.e5.config;
import lombok.Getter;
/**
* @program: push
* @description:
* @author: 落叶随风
* @create: 2020-09-15 16:47
**/
@Getter
public enum ResultCode {
SUCCESS(0, "Success"),
FAILED(1001, "响应失败"),
API_FAILED(1001, "API 响应失败"),
VALIDATE_FAILED(1002, "参数校验失败"),
ERROR(5000, "未知错误"),
NO_PARAMETERS(1003, "缺少参数");
private int code;
private String msg;
ResultCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@ -0,0 +1,49 @@
package io.qyi.e5.config;
import lombok.Getter;
/**
* @program: push
* @description:
* @author: 落叶随风
* @create: 2020-09-15 16:43
**/
@Getter
public class ResultVO<T> {
/**
* 状态码比如1000代表响应成功
*/
private int code;
/**
* 响应信息用来说明响应情况
*/
private String msg;
/**
* 响应的具体数据
*/
private T data;
public ResultVO(T data) {
this(ResultCode.SUCCESS, data);
}
public ResultVO() {
this(ResultCode.SUCCESS);
}
public ResultVO(ResultCode resultCode) {
this.code = resultCode.getCode();
this.msg = resultCode.getMsg();
}
public ResultVO(int code, String msg) {
this.code = code;
this.msg = msg;
}
public ResultVO(ResultCode resultCode, T data) {
this.code = resultCode.getCode();
this.msg = resultCode.getMsg();
this.data = data;
}
}

View File

@ -0,0 +1,34 @@
package io.qyi.e5.config.exception;
import io.qyi.e5.config.APiCode;
import lombok.Getter;
/**
* @program: push
* @description:
* @author: 落叶随风
* @create: 2020-09-15 16:42
**/
@Getter
public class APIException extends RuntimeException {
private int code;
private String msg;
public APIException() {
this(1001, "接口错误");
}
public APIException(String msg) {
this(1002, msg);
}
public APIException(APiCode code) {
this(code.getCode(), code.getMsg());
}
public APIException(int code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
}

View File

@ -0,0 +1,88 @@
package io.qyi.e5.config.exception;
import io.qyi.e5.config.ResultCode;
import io.qyi.e5.config.ResultVO;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @program: push
* @description:
* @author: 落叶随风
* @create: 2020-09-15 16:41
**/
@RestControllerAdvice
public class ExceptionControllerAdvice {
/**
*
* @param e: 用来捕获404400这种无法到达controller的错误
* @Author: 落叶随风
* @Date: 2020/9/17 15:17
* @Return: * @return: io.qyi.push.config.bean.ResultVO<java.lang.String>
*/
@ExceptionHandler(APIException.class)
public ResultVO<String> APIExceptionHandler(APIException e) {
return new ResultVO<>(e.getCode(), e.getMsg());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO<String> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
return new ResultVO<>(ResultCode.VALIDATE_FAILED, objectError.getDefaultMessage());
}
/**
* 参数校验
* @param e:
* @Author: 落叶随风
* @Date: 2020/9/21 11:28
* @Return: * @return: io.qyi.push.config.bean.ResultVO<java.lang.String>
*/
@ExceptionHandler(BindException.class)
public ResultVO<String> BindException(BindException e) {
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
return new ResultVO<>(ResultCode.VALIDATE_FAILED, objectError.getDefaultMessage());
}
/**
* 无参数
* @param e:
* @Author: 落叶随风
* @Date: 2020/9/17 17:00
* @Return: * @return: io.qyi.push.config.bean.ResultVO<java.lang.String>
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResultVO<String> HttpMessageNotReadableException(HttpMessageNotReadableException e) {
return new ResultVO<>(ResultCode.NO_PARAMETERS);
}
/*@RestControllerAdvice(basePackages = {"io.qyi.push.api.v1"}) // 注意哦这里要加上需要扫描的包
public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> aClass) {
// 如果接口返回的类型本身就是ResultVO那就没有必要进行额外的操作返回false
return !returnType.getGenericParameterType().equals(ResultVO.class);
}
@Override
public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse response) {
// String类型不能直接包装所以要进行些特别的处理
if (returnType.getGenericParameterType().equals(String.class)) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将数据包装在ResultVO里后再转换为json字符串响应给前端
return objectMapper.writeValueAsString(new ResultVO<>(data));
} catch (JsonProcessingException e) {
throw new APIException("返回String类型错误");
}
}
// 将原本的数据包装在ResultVO里
return new ResultVO<>(data);
}
}*/
}

View File

@ -62,23 +62,6 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro
logger.info("Github 认证: code{} state{} Token", code, state);
Map<String, Object> userInfo_redis = new HashMap<>();
/*是否调试模式*/
if (isDebug) {
List<String> list = new ArrayList<>();
list.add("admin");
list.add("user");
String[] l = list.toArray(new String[list.size()]);
String token = EncryptUtil.getInstance().SHA1Hex(UUID.randomUUID().toString());
UsernamePasswordAuthenticationToken authenticationToken1 = new UsernamePasswordAuthenticationToken("debugName",
"DebugAvatar", adminGithubId, token, "admin", AuthorityUtils.createAuthorityList(l));
authenticationToken1.setDetails(authenticationToken);
userInfo_redis.put("github_name", "debug");
userInfo_redis.put("github_id", adminGithubId);
userInfo_redis.put("avatar_url", "https://www.baidu.com");
userInfo_redis.put("authority", list);
redisUtil.hmset(token_ + token, userInfo_redis, tokenExpire);
return authenticationToken1;
}
if (!redisUtil.hasKey(states + state)) {
throw new UsernameNotFoundException("status不存在");
// return ResultUtil.error(ResultEnum.STATE_HAS_EXPIRED);

View File

@ -88,11 +88,6 @@ public class AdminController {
return "ok";
}
@GetMapping("/test")
public String test() {
return "ok";
}
@RequestMapping("setAnnouncement")
public String setAnnouncement(String text) throws IOException {
File file = ResourceUtils.getFile("classpath:announcement.txt");
@ -114,12 +109,10 @@ public class AdminController {
/*写token信息到redis*/
Map<String, Object> userInfo_redis = new HashMap<>();
userInfo_redis.put("github_name", "admin");
userInfo_redis.put("github_id", 0000);
userInfo_redis.put("github_id", 10000);
userInfo_redis.put("avatar_url", "https://www.baidu.com");
userInfo_redis.put("authority", list_Authority);
redisUtil.hmset(token_ + token, userInfo_redis, tokenExpire);
// 创建一个已认证的token
// UsernamePasswordAuthenticationToken authenticationToken1 = new UsernamePasswordAuthenticationToken(userInfo_redis.get("github_name").toString(),
// userInfo_redis.get("github_name").toString(), (int)userInfo_redis.get("github_name"), token, "user", AuthorityUtils.createAuthorityList(Authority));

View File

@ -0,0 +1,26 @@
package io.qyi.e5.outlook.bean;
import lombok.Data;
/**
* @program: e5
* @description:
* @author: 落叶随风
* @create: 2020-12-10 16:54
**/
@Data
public class OutlookListVo {
private int id;
private String clientId;
private String clientSecret;
private Integer cronTimeRandomStart;
private Integer cronTimeRandomEnd;
/*名称*/
private String name;
/*描述*/
private String describes;
/*下次调用时间*/
private long nextTime;
/*运行状态*/
private int status;
}

View File

@ -10,8 +10,9 @@ import lombok.Data;
**/
@Data
public class OutlookVo {
private int id;
private String clientId;
private String clientSecret;
private int cronTimeRandomStart;
private int cronTimeRandomEnd;
private Integer cronTimeRandomStart;
private Integer cronTimeRandomEnd;
}

View File

@ -0,0 +1,15 @@
package io.qyi.e5.outlook.bean.bo;
import lombok.Data;
/**
* @program: e5
* @description:
* @author: 落叶随风
* @create: 2020-12-10 15:47
**/
@Data
public class insertOneBO {
private String name;
private String describe;
}

View File

@ -4,8 +4,11 @@ package io.qyi.e5.outlook.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.qyi.e5.bean.result.Result;
import io.qyi.e5.bean.result.ResultEnum;
import io.qyi.e5.config.ResultVO;
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
import io.qyi.e5.outlook.bean.OutlookListVo;
import io.qyi.e5.outlook.bean.OutlookVo;
import io.qyi.e5.outlook.bean.bo.insertOneBO;
import io.qyi.e5.outlook.entity.Outlook;
import io.qyi.e5.outlook.service.IOutlookService;
import io.qyi.e5.util.ResultUtil;
@ -15,6 +18,10 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 前端控制器
@ -30,15 +37,25 @@ public class OutlookController {
@Autowired
IOutlookService outlookService;
@PostMapping("/save")
public Result save(@RequestParam String client_id, @RequestParam String client_secret) {
@PostMapping("/insertOne")
public ResultVO insertOne(@RequestBody insertOneBO bo) {
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (outlookService.save(client_id, client_secret, authentication.getGithub_id())) {
return ResultUtil.success();
}
return ResultUtil.error(ResultEnum.UNKNOWN_ERROR);
Outlook outlook = outlookService.insertOne(bo.getName(), bo.getDescribe(), authentication.getGithub_id());
OutlookVo vo = new OutlookVo();
BeanUtils.copyProperties(outlook, vo);
return new ResultVO<>(vo);
}
@PostMapping("/save")
public ResultVO save(@RequestParam String client_id, @RequestParam String client_secret,@RequestParam int outlook_id) {
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (outlookService.save(client_id, client_secret, outlook_id, authentication.getGithub_id())) {
return new ResultVO<>();
}
return new ResultVO<>();
}
@PostMapping("/saveRandomTime")
public Result saveRandomTime(@RequestParam int cronTime, @RequestParam String crondomTime) {
String[] split = crondomTime.split("-");
@ -86,4 +103,21 @@ public class OutlookController {
}
return ResultUtil.success(vo);
}
@GetMapping("/getOutlookList")
public Result getOutlookList() {
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
int github_id = authentication.getGithub_id();
List<Outlook> outlooklist = outlookService.getOutlooklist(github_id);
List<OutlookListVo> vo = new ArrayList<>();
outlooklist.forEach(outlook -> {
OutlookListVo v = new OutlookListVo();
BeanUtils.copyProperties(outlook, v);
vo.add(v);
});
return ResultUtil.success(vo);
}
}

View File

@ -2,7 +2,9 @@ package io.qyi.e5.outlook.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@ -58,6 +60,11 @@ public class Outlook implements Serializable {
*/
private Integer cronTimeRandomEnd;
/*名称*/
private String name;
/*描述*/
private String describes;
}

View File

@ -12,5 +12,5 @@ import io.qyi.e5.outlook.entity.Outlook;
* @since 2020-02-24
*/
public interface OutlookMapper extends BaseMapper<Outlook> {
Outlook selectOutlookOne(int id, int github_id);
}

View File

@ -17,13 +17,17 @@ public interface IOutlookService extends IService<Outlook> {
boolean getTokenAndSave(String code,String client_id,String client_secret,String redirect_uri,String grant_type) throws Exception;
boolean save(String client_id,String client_secret,int github_id);
Outlook insertOne(String name, String describe, int github_id);
boolean saveRandomTime(int github_id,int cron_time,int cron_time_random_start,int cron_time_random_end);
boolean save(String client_id, String client_secret, int outlook_id, int github_id);
boolean saveRandomTime(int github_id, int cron_time, int cron_time_random_start, int cron_time_random_end);
int getMailList(Outlook outlook) throws Exception;
List<Outlook> findAll();
int deleteInfo(int github_id);
List<Outlook> getOutlooklist(int github_id);
}

View File

@ -8,16 +8,19 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.qyi.e5.config.APiCode;
import io.qyi.e5.config.exception.APIException;
import io.qyi.e5.outlook.entity.Outlook;
import io.qyi.e5.outlook.mapper.OutlookMapper;
import io.qyi.e5.outlook.service.IOutlookService;
import io.qyi.e5.util.netRequest.OkHttpClientUtil;
import io.qyi.e5.util.netRequest.OkHttpRequestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@ -75,35 +78,48 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
@Override
public boolean save(String client_id, String client_secret, int github_id) {
public Outlook insertOne(String name, String describe, int github_id) {
if (StringUtils.isBlank(name)) {
throw new APIException(APiCode.OUTLOOK_NAME_NOT_NULL);
}
Outlook outlook = new Outlook();
outlook.setName(name);
outlook.setDescribes(describe);
outlook.setGithubId(github_id);
logger.info(outlook.toString());
if (baseMapper.insert(outlook) != 1) {
throw new APIException(APiCode.OUTLOOK_INSERT_ERROR);
}
return outlook;
}
@Override
public boolean save(String client_id, String client_secret, int outlook_id, int github_id) {
if (github_id == 0) {
return false;
throw new APIException(APiCode.OUTLOOK_NAME_NOT_NULL);
}
if (outlook_id == 0) {
throw new APIException("缺少参数!");
}
QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("github_id", github_id)
.or().eq("client_id", client_id);
Outlook outlook1 = baseMapper.selectOne(queryWrapper);
// 有数据
if (outlook1 != null) {
outlook1.setClientId(client_id)
.setClientSecret(client_secret);
// HashMap<String, Object> sc = new HashMap<>();
// sc.put("github_id", github_id);
// sc.put("id", outlook_id);
// queryWrapper.allEq(sc);
queryWrapper.eq("github_id", github_id).eq("id", outlook_id);
/*2020-12-10 mybatis plus问题导致会被截断*/
// Outlook outlook1 = baseMapper.selectOne(queryWrapper);
int i = baseMapper.update(outlook1, queryWrapper);
if (i == 1) {
return true;
}
} else {
Outlook outlook = new Outlook();
outlook.setClientId(client_id)
.setClientSecret(client_secret)
.setGithubId(github_id);
int i = baseMapper.insert(outlook);
if (i == 1) {
return true;
}
Outlook outlook1 = baseMapper.selectOutlookOne(outlook_id,github_id );
if (outlook1 == null) {
throw new APIException("未查询到此条记录!");
}
return false;
outlook1.setClientId(client_id);
outlook1.setClientSecret(client_secret);
if (baseMapper.update(outlook1, queryWrapper) != 1) {
throw new APIException("更新记录失败!");
}
return true;
}
@Override
@ -154,7 +170,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
String message = json.getJSONObject("error").getString("message");
/*如果出现的错误是没有message中收集的那么就认为是无法刷新的情况。比如 用户取消了授权、删除了key*/
if (!errorCheck(message)) {
throw new Exception("无法刷新令牌!code:3" + message);
throw new Exception("无法刷新令牌!code:3" + message);
}
logger.info("令牌过期!");
/*刷新令牌*/
@ -166,7 +182,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
s = MailList(token);
json = JSON.parseObject(s);
if (json.containsKey("error")) {
throw new Exception("无法刷新令牌!code:2,错误消息: "+ json.getJSONObject("error").getString("message"));
throw new Exception("无法刷新令牌!code:2,错误消息: " + json.getJSONObject("error").getString("message"));
}
}
logger.info("邮件列表请求成功!" + s);
@ -207,7 +223,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
head.put("Content-Type", "application/json");
head.put("Authorization", access_token);
/*不用管邮件内容*/
OkHttpClientUtil.doGet("https://graph.microsoft.com/v1.0/me/messages/" + id, null,head, null);
OkHttpClientUtil.doGet("https://graph.microsoft.com/v1.0/me/messages/" + id, null, head, null);
}
return count;
}
@ -216,7 +232,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
Map<String, String> head = new HashMap<>();
head.put("Content-Type", "application/json");
head.put("Authorization", access_token);
String s = OkHttpClientUtil.doGet("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject",null, head, null);
String s = OkHttpClientUtil.doGet("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject", null, head, null);
logger.debug("请求邮件列表返回数据:" + s);
return s;
}
@ -238,7 +254,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
JSONObject jsonObject = JSON.parseObject(s);
if (!jsonObject.containsKey("access_token")) {
logger.info("返回的access_token字段不存在");
throw new Exception("返回的access_token字段不存在,无法刷新令牌! 需要重新授权!" );
throw new Exception("返回的access_token字段不存在,无法刷新令牌! 需要重新授权!");
}
outlook.setRefreshToken(jsonObject.getString("refresh_token"));
outlook.setAccessToken(jsonObject.getString("access_token"));
@ -271,4 +287,12 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
return false;
}
@Override
public List<Outlook> getOutlooklist(int github_id) {
QueryWrapper<Outlook> qw = new QueryWrapper<Outlook>().eq("github_id", github_id);
List<Outlook> outlooks = baseMapper.selectList(qw);
return outlooks;
}
}

View File

@ -1,5 +1,8 @@
<?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="io.qyi.e5.outlook.mapper.OutlookMapper">
<select id="selectOutlookOne" resultType="io.qyi.e5.outlook.entity.Outlook">
select * from outlook where id = #{id} and github_id = #{github_id}
</select>
</mapper>