添加拦截器

1. 添加拦截器
2. 修复swagger
3. 添加全局异常处理
4. reader和writer添日志
This commit is contained in:
曾伟 2021-09-07 15:15:46 +08:00
parent 73c16974be
commit 927cae5ace
20 changed files with 453 additions and 7 deletions

View File

@ -57,6 +57,24 @@
<artifactId>spring-kafka</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.9.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.38</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.38</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,12 @@
package cn.org.gitlink.notification.common.exceptions;
/**
* 网关拦截非白名单用户异常类
* @author zengwei
* @date 2021/09/07
* */
public class ForbiddenException extends Exception{
public ForbiddenException(String message) {
super(message);
}
}

View File

@ -0,0 +1,42 @@
package cn.org.gitlink.notification.common.interceptor;
import cn.org.gitlink.notification.common.exceptions.ForbiddenException;
import cn.org.gitlink.notification.common.response.DataPacketUtil;
import cn.org.gitlink.notification.common.response.ResponseData;
import cn.org.gitlink.notification.common.utils.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
/**
* web请求异常全局处理类在使用的模块内继承此类然后加上ControllerAdvice注解example:
* @ControllerAdvice
* public class ReaderExceptionInterceptor extends ExceptionInterceptor {}
* @author zengwei
* @date 2021/09/07
* */
public class ExceptionInterceptor {
private static final Logger logger = LoggerFactory.getLogger(ExceptionInterceptor.class);
private static String logTemplate = "request page url{}, error:{}";
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({ForbiddenException.class})
public ResponseData handle(HttpServletRequest request, ForbiddenException e) {
logger.warn("非法求请, ip:{}", CommonUtils.getIPAddress(request));
return DataPacketUtil.jsonFailResult(e.getMessage());
}
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({Exception.class})
public ResponseData handle(HttpServletRequest request, Exception e) {
logger.error(logTemplate, request.getRequestURI(), e);
return DataPacketUtil.jsonFailResult("服务器异常,请联系管理员处理!", e);
}
}

View File

@ -0,0 +1,42 @@
package cn.org.gitlink.notification.common.interceptor;
import cn.org.gitlink.notification.common.exceptions.ForbiddenException;
import cn.org.gitlink.notification.common.utils.CommonUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* GitLink统一拦截类example:
* @Configuration
* public class ReaderWebConfig implements WebMvcConfigurer {
* @Autowired
* private GitLinkInterceptor gitLinkInterceptor;
* @Override
* public void addInterceptors(InterceptorRegistry registry) {
* registry.addInterceptor(gitLinkInterceptor).addPathPatterns("/**");
* }
* }
*
* @author zengwei
* @date 2021/09/07
* */
@Component
public class GitLinkInterceptor implements HandlerInterceptor {
@Value(value = "${white-list:''}")
private String whiteList;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
if (null == httpServletRequest || whiteList.contains("*")) {
return true;
}
if (!whiteList.contains(CommonUtils.getIPAddress(httpServletRequest))) {
throw new ForbiddenException("没有权限访问,请向管理员申请访问权限!");
}
return true;
}
}

View File

@ -0,0 +1,53 @@
package cn.org.gitlink.notification.common.response;
import java.util.HashMap;
import java.util.List;
public class DataPacketUtil
{
public static final String RESULT_KEY_SUCCESS = "请求成功";
public static final String RESULT_KEY_FAIL = "请求失败";
public static final Integer SUCCESS_CODE = 1;
public static final Integer FAIL_CODE = 0;
public static final String NOT_FOUND_MESSAGE = "资源不存在";
public static final String FORBIDDEN_MESSAGE = "您无权限进行此操作!";
public static ResponseData jsonResult(String msg, Integer code, Object data)
{
return new ResponseData(msg, code, data);
}
public static ResponseData jsonSuccessResult() {
return jsonResult(RESULT_KEY_SUCCESS, SUCCESS_CODE, new HashMap<>());
}
public static ResponseData jsonSuccessResult(Object data) {
return jsonResult(RESULT_KEY_SUCCESS, SUCCESS_CODE, data);
}
public static ResponseData jsonSuccessResult(String msg) {
return jsonResult(msg, SUCCESS_CODE, new HashMap<>());
}
public static ResponseData jsonSuccessResult(String msg, Object data) {
return jsonResult(msg, SUCCESS_CODE, data);
}
public static ResponseData jsonFailResult() {
return jsonResult( RESULT_KEY_FAIL, FAIL_CODE, new HashMap<>());
}
public static ResponseData jsonFailResult(String msg) {
return jsonResult( msg, FAIL_CODE, new HashMap<>());
}
public static ResponseData jsonFailResult(Object data) {
return jsonResult( RESULT_KEY_FAIL, FAIL_CODE, data);
}
public static ResponseData jsonFailResult(String msg, Object data) {
return jsonResult( msg, FAIL_CODE, data);
}
}

View File

@ -0,0 +1,34 @@
package cn.org.gitlink.notification.common.response;
import java.io.Serializable;
public class PageData<T> implements Serializable {
private long total;
private java.util.List<T> rows;
public PageData(long total, java.util.List<T> rows) {
this.total = total;
this.rows = rows;
}
public long getTotal() {
return this.total;
}
public void setTotal(long total) {
this.total = total;
}
public java.util.List<T> getRows() {
return this.rows;
}
public void setRows(java.util.List<T> rows) {
this.rows = rows;
}
public PageData() {
}
}

View File

@ -0,0 +1,65 @@
package cn.org.gitlink.notification.common.response;
import org.apache.kafka.common.protocol.types.Field;
import java.io.Serializable;
public class ResponseData<T> implements Serializable {
/**
* 响应状态
*/
protected Integer code;
/**
* 响应消息
*/
protected String message;
/**
* 响应数据
*/
private T data;
public void setMessage(String message) {
this.message = message;
}
public void setCode(Integer code) { this.code = code; }
public String toString() {
return "ResponseData(message=" + getMessage() + ", data=" + getData() + ")";
}
public String getMessage() {
return this.message;
}
public Integer getCode() { return this.code; }
public ResponseData(T data) {
this.data = data;
}
public ResponseData(String message) {
this.message = message;
}
public ResponseData(String message, Integer code, T data) {
this.message = message;
this.code = code;
this.data = data;
}
public T getData() {
return this.data;
}
public void setData(T data) {
this.data = data;
}
public ResponseData() {
}
}

View File

@ -0,0 +1,52 @@
package cn.org.gitlink.notification.common.utils;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
/**
* 公共工具类
* @author zengwei
* @date 2021/09/07
* */
public class CommonUtils {
/**
* 根据request获取ip
* @author zengwei
* @data 2021/07/09
* */
public static String getIPAddress(HttpServletRequest request) {
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
//多次反向代理后会有多个ip值第一个ip才是真实ip
int index = XFor.indexOf(",");
if (index != -1) {
return XFor.substring(0,index);
} else {
return XFor;
}
}
XFor = Xip;
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
return XFor;
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getRemoteAddr();
}
return XFor;
}
}

10
pom.xml
View File

@ -51,6 +51,16 @@
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package cn.org.gitlink.notification.reader.config;
import cn.org.gitlink.notification.common.interceptor.ExceptionInterceptor;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class ReaderExceptionInterceptor extends ExceptionInterceptor {}

View File

@ -0,0 +1,17 @@
package cn.org.gitlink.notification.reader.config;
import cn.org.gitlink.notification.common.interceptor.GitLinkInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class ReaderWebConfig implements WebMvcConfigurer {
@Autowired
private GitLinkInterceptor gitLinkInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(gitLinkInterceptor).addPathPatterns("/**");
}
}

View File

@ -16,14 +16,13 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import({BeanValidatorPluginsConfiguration.class})
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.gitlink.notification")).paths(PathSelectors.any()).build();
.apis(RequestHandlerSelectors.basePackage("cn.org.gitlink.notification.reader")).paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {

View File

@ -1,5 +1,7 @@
package cn.org.gitlink.notification.reader.controller;
import cn.org.gitlink.notification.common.response.DataPacketUtil;
import cn.org.gitlink.notification.common.response.ResponseData;
import cn.org.gitlink.notification.common.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -10,8 +12,8 @@ public class IndexController {
@Autowired
private RedisUtil redisUtil;
@GetMapping(value = "")
public String index() {
public ResponseData index() {
redisUtil.set("hello", "Hello reader!");
return redisUtil.get("hello").toString();
return DataPacketUtil.jsonSuccessResult(redisUtil.get("hello").toString());
}
}

View File

@ -1,6 +1,9 @@
server:
port: 8080
logging:
config: classpath:logback.xml
spring:
redis:
# Redis数据库索引默认为0
@ -22,3 +25,6 @@ spring:
min-idle: 0
# 连接超时时间(毫秒)
timeout: 1000
#ip白名单列表多个ip用逗号隔开允许所有用*号
white-list: '*'

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="./logs/reader.log"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>

View File

@ -16,14 +16,13 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import({BeanValidatorPluginsConfiguration.class})
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.gitlink.notification")).paths(PathSelectors.any()).build();
.apis(RequestHandlerSelectors.basePackage("cn.org.gitlink.notification.writer")).paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {

View File

@ -0,0 +1,7 @@
package cn.org.gitlink.notification.writer.config;
import cn.org.gitlink.notification.common.interceptor.ExceptionInterceptor;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class WriterExceptionInterceptor extends ExceptionInterceptor {}

View File

@ -0,0 +1,17 @@
package cn.org.gitlink.notification.writer.config;
import cn.org.gitlink.notification.common.interceptor.GitLinkInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WriterWebConfig implements WebMvcConfigurer {
@Autowired
private GitLinkInterceptor gitLinkInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(gitLinkInterceptor).addPathPatterns("/**");
}
}

View File

@ -1,6 +1,9 @@
server:
port: 8082
logging:
config: classpath:logback.xml
spring:
#kafka配置
kafka:
@ -32,4 +35,7 @@ spring:
#密钥的反序列化器类实现类实现了接口org.apache.kafka.common.serialization.Deserializer
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
#值的反序列化器类实现类实现了接口org.apache.kafka.common.serialization.Deserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
#ip白名单列表多个ip用逗号隔开允许所有用*号
white-list: '*'

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="./logs/writer.log"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>