项目结构
pom包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wsh</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.0.3.RELEASE</spring-boot.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot Web 依赖 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
</project>
类代码
package com.wsh.common.bean.exception;
/**
* 基础接口:自定义描述枚举类需实现该接口
* @author wsh
* @create 2020-12-11 10:02
*/
public interface BaseErrorInfoInterface {
/** 状态码 */
int code();
/** 描述 */
String msg();
}
package com.wsh.common.bean.exception;
/**
* 自定义业务异常类
* @author wsh
* @create 2020-12-11 10:02
*/
public class CommonException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
protected int errorCode;
/**
* 错误信息
*/
protected String errorMsg;
public CommonException() {
super();
}
public CommonException(BaseErrorInfoInterface errorInfoInterface) {
super(errorInfoInterface.code()+"");
this.errorCode = errorInfoInterface.code();
this.errorMsg = errorInfoInterface.msg();
}
public CommonException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
super(errorInfoInterface.code()+"", cause);
this.errorCode = errorInfoInterface.code();
this.errorMsg = errorInfoInterface.msg();
}
public CommonException(String errorMsg) {
super(errorMsg);
this.errorMsg = errorMsg;
}
public CommonException(int errorCode, String errorMsg) {
super(errorCode+"");
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public CommonException(int errorCode, String errorMsg, Throwable cause) {
super(errorCode+"", cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getMessage() {
return errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
package com.wsh.common.bean.result;
import com.wsh.common.bean.exception.BaseErrorInfoInterface;
/**
* @author wsh
* @create 2020-12-11 10:06
*/
public enum CommonEnum implements BaseErrorInfoInterface {
SUCCESS(0, "success"),
SYSTEM_ERROR(100, "系统异常!"),
PARAMETER_ERROR(101, "参数错误!"),
NAME_ERROR(102, "已存在相同的名称!"),
NUMBER_ERROR(103, "已存在相同的编号!"),
SIGNATURE_NOT_MATCH(104,"用户名或密码错误!"),
NOT_FOUND(998, "未找到该资源!"),
SERVER_BUSY(999,"服务器正忙,请稍后再试!");
/** 状态码 */
private int resultCode;
/** 返回描述 */
private String resultMsg;
CommonEnum(int resultCode, String resultMsg) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
}
@Override
public int code() {
return resultCode;
}
@Override
public String msg() {
return resultMsg;
}
}
```java
package com.wsh.common.bean.result;
import com.wsh.common.bean.exception.BaseErrorInfoInterface;
/**
* @author wsh
* @create 2020-12-11 10:04
*/
public class Result {
/**
* 响应代码
*/
private int code;
/**
* 响应消息
*/
private String msg;
/**
* 响应结果
*/
private Object data;
public Result() {
}
public Result(BaseErrorInfoInterface errorInfo) {
this.code = errorInfo.code();
this.msg = errorInfo.msg();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
* 成功(不含data数据)
*
* @return
*/
public static Result success() {
return success(null);
}
/**
* 成功(包含data数据)
* @param data
* @return
*/
public static Result success(Object data) {
Result rb = new Result();
rb.setCode(CommonEnum.SUCCESS.code());
rb.setMsg(CommonEnum.SUCCESS.msg());
rb.setData(data);
return rb;
}
/**
* 失败(code、msg枚举类获取,不包含data数据)
*/
public static Result error(BaseErrorInfoInterface errorInfo) {
Result rb = new Result();
rb.setCode(errorInfo.code());
rb.setMsg(errorInfo.msg());
rb.setData(null);
return rb;
}
/**
* 失败(code、msg枚举类获取,包含data数据)
*/
public static Result error(BaseErrorInfoInterface errorInfo, Object data) {
Result rb = new Result();
rb.setCode(errorInfo.code());
rb.setMsg(errorInfo.msg());
rb.setData(data);
return rb;
}
/**
* 失败(code、msg自定义,不包含data数据)
*/
public static Result error(int code, String msg) {
Result rb = new Result();
rb.setCode(code);
rb.setMsg(msg);
rb.setData(null);
return rb;
}
}
package com.wsh.common.bean;
/**
* @author wsh
* @create 2020-12-11 10:28
*/
public class User {
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package com.wsh.common.config.exceptionhandler;
import com.wsh.common.bean.exception.CommonException;
import com.wsh.common.bean.result.CommonEnum;
import com.wsh.common.bean.result.Result;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
*
* @author wsh
* @create 2020-12-11 10:03
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 处理自定义的业务异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = CommonException.class)
@ResponseBody
public Result bizExceptionHandler(HttpServletRequest req, CommonException e){
log.error("{},业务异常!{}",req.getRequestURI(),e.getErrorMsg());
return Result.error(e.getErrorCode(),e.getErrorMsg());
}
/**
* Valid 校验参数合法性
* @param e
* @param request
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public Result bindException(Exception e, HttpServletRequest request) {
log.error("url:{},{}", request.getRequestURI(), ExceptionUtils.getStackTrace(e));
StringBuilder sb = new StringBuilder("[");
List<ObjectError> list = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
for (ObjectError item : list) {
sb.append(item.getDefaultMessage()).append(',');
}
sb.deleteCharAt(sb.length()-1);
sb.append(']');
return Result.error(CommonEnum.PARAMETER_ERROR,sb.toString());
}
/**
* 处理其他异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result exceptionHandler(HttpServletRequest req, Exception e){
log.error("url:{},系统异常!", req.getRequestURI(), e);
return Result.error(CommonEnum.SYSTEM_ERROR,e.getMessage());
}
}
```java
package com.wsh.common.config.validated;
/**
* @author wsh
* @create 2020-12-10 17:16
*/
public interface Add {
}
package com.wsh.common.config.validated;
/**
* @author wsh
* @create 2020-12-10 17:16
*/
public interface Update {
}
package com.wsh.common.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 解决跨域问题
*/
@Configuration
public class CorsConfig {
private static final Logger log = LoggerFactory.getLogger(CorsConfig.class);
@Value("${cors.allow-origins:*}")
private String allowOrigins;
public CorsConfig() {
}
@Bean
@Order
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
if (this.allowOrigins == null || this.allowOrigins.trim().equals("")) {
log.error("不合法的origin配置,allowOrigins:{}", this.allowOrigins);
System.exit(-1);
}
String[] allowOriginArr = this.allowOrigins.split(",");
for (String origin : allowOriginArr) {
corsConfiguration.addAllowedOrigin(origin);
}
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
package com.wsh.common.config;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* 打印所有的controller包下的接口请求和响应日志
* @author wsh
* @create 2020-10-10 11:20
*/
@Aspect
@Configuration
@Order
public class WebLogAspect {
private static final Logger log = LoggerFactory.getLogger(WebLogAspect.class);
private ThreadLocal<Long> startTime=new ThreadLocal<>();
// 指定所有调用controller包下类中的方法
@Pointcut("execution(public * *.*.*.controller.*.*(..))")
public void webLog(){
}
@Before(value = "webLog()")
public void doBefore(JoinPoint point){
startTime.set(System.currentTimeMillis());
log.info("WebLogAspect.doBefore............");
ServletRequestAttributes attributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request=attributes.getRequest();
log.info("请求IP:{}",request.getRemoteAddr());
log.info("请求URL:{}" , request.getRequestURL().toString());
log.info("请求方法类型 HTTP_METHOD:{}",request.getMethod());
log.info("请求方法路径 CLASS_NAME:{}" , point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName());
log.info("请求参数值:{}", Arrays.toString(point.getArgs()));
}
@AfterReturning(value = "webLog()",returning = "ret")
public void doAferReturning(Object ret){
log.info("WebLogAspect.doAfterReturning.............");
log.info("响应结果:{}", ret);
log.info("响应时间:{}ms", (System.currentTimeMillis()-startTime.get()));
}
}
package com.wsh.common.controller;
import com.wsh.common.bean.User;
import com.wsh.common.bean.result.CommonEnum;
import com.wsh.common.bean.result.Result;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
* @author wsh
* @create 2020-12-11 10:27
*/
@RestController
@RequestMapping(value = "/api")
public class TestController {
/**
* 请求参数:{"id":1,"age":18}
* @param user
* @return
*/
@RequestMapping("/insert")
public Result insert(@Valid @RequestBody User user) {
//测试 业务自定义异常
// if(user.getName()==null){
// throw new CommonException(CommonEnum.NAME_ERROR);
// }
Assert.notNull(user.getName(),CommonEnum.NAME_ERROR.msg());
return Result.success();
}
/**
* 请求参数:{"id":1,"age":18}
* @param user
* @return
*/
@RequestMapping("/update")
public Result update(@RequestBody User user) {
//测试 业务层中发生空指针异常
String str=null;
str.equals("111");
return Result.success();
}
/**
* 请求参数:{"id":1,"age":18}
* @param user
* @return
*/
@RequestMapping("/delete")
public Result delete(@RequestBody User user) {
//内部服务器异常:未知异常
Integer.parseInt("abc123");
return Result.success();
}
/**
* 不需要参数
* @param user
* @return
*/
@RequestMapping("/findByUser")
public Result findByUser(User user) {
System.out.println("正常查询用户,没有异常。");
List<User> userList =new ArrayList<>();
User user2=new User();
user2.setId(1L);
user2.setName("cc");
user2.setAge(18);
userList.add(user2);
return Result.success(userList);
}
}
package com.wsh.common.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Map;
/**
* @author wsh
* @create 2020-12-11 16:59
*/
public class TokenUtil {
public static String createToken(String accountId,String account){
// Date expiresAt = new Date(System.currentTimeMillis() + 24L * 60L * 3600L * 1000L);
String token = JWT.create()
// .withExpiresAt(expiresAt) // 设置tocken过期时间
.withClaim("iss", "lyzh_third") // jwt签发者
.withClaim("aud", "lyzh_third") // aud: 接收jwt的一方
.withClaim("accountId", accountId)
.withClaim("account", account)
.sign(Algorithm.HMAC256("lyzhSecret"));
return token;
}
/**
* 解密Token, 获取 claims 中的信息
*
* @param token
* @return
* @throws Exception
*/
public static Map<String, Claim> decryToken(String token) {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("lyzhSecret")).build();
DecodedJWT jwt = verifier.verify(token);
return jwt.getClaims();
}
}