正文
导入SpringbootWEb依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-start-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制
定义一个Controller,指定RESTFUL接口映射
@RestController
@SwaggerScanClass
public class TestController {
@Autowired
private RedisTemplate redisTemplate;
@Value("${mp.event.aeskey:4b57e89bac82a797}")
private String aesKey;
private Map<String, Long> mockUrlTimeOut = new ConcurrentHashMap<>();
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@PostMapping("/addMockInfo")
@ApiOperation("添加Mock信息")
public Resp addMockInfo(@RequestParam("url") String url, @RequestBody Object body) {
String redisSaveKey = AES.encrypt(url, aesKey);
Object returnBody = redisTemplate.opsForValue().get(redisSaveKey);
if (returnBody != null) {
redisTemplate.opsForValue().setIfAbsent(redisSaveKey, body, 48, TimeUnit.HOURS);
return Resp.Ok("url 响应报文更新成功" + url);
}
applicationEventPublisher.publishEvent(new AddMockInfoEvent(this, Clock.systemDefaultZone(), url, body));
return Resp.Ok("url添加Mock成功" + url);
}
@PostMapping("/addMockInfoTimeOut")
@ApiOperation("添加Mock信息Url的阻塞时间")
public Resp addMockInfoTimeOut(@RequestParam("url") String url, @RequestParam("timeOut") Long timeOut) {
Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(url, timeOut, 48, TimeUnit.HOURS);
mockUrlTimeOut.put(url, timeOut);
return aBoolean ? Resp.Ok("url添加Mock成功" + timeOut) : Resp.error("添加Mock信息Url的阻塞时间失败");
}
@ApiOperation("Mock动态回调Request")
public Resp addMockInfoByRequest() {
ServletRequestAttributes httpRequest = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = httpRequest.getRequest();
String requestURI = request.getRequestURI();
String redisSaveKey = AES.encrypt(requestURI, aesKey);
Object returnBody = redisTemplate.opsForValue().get(redisSaveKey);
if (returnBody == null) {
return Resp.error("Mock动态回调Request 没找到报文");
}
Long timeOut = mockUrlTimeOut.get(requestURI);
if (timeOut == null || timeOut == 0) {
Object redisSaveTimeOut = redisTemplate.opsForValue().get(requestURI);
if (redisSaveTimeOut != null) {
timeOut = (Long) redisSaveTimeOut;
mockUrlTimeOut.put(requestURI, timeOut);
}
}
try {
if (timeOut == null || timeOut == 0) {
return Resp.Ok(returnBody);
}
Thread.sleep(timeOut);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Resp.Ok(returnBody);
}
}
复制
定义一个事件 AddMockInfoEvent
public class AddMockInfoEvent extends ApplicationEvent {
private String url;
private Object context;
public AddMockInfoEvent(Object source) {
super(source);
}
public AddMockInfoEvent(Object source, Clock clock) {
super(source, clock);
}
public AddMockInfoEvent(Object source, String url, Object context) {
super(source);
this.url = url;
this.context = context;
}
public AddMockInfoEvent(Object source, Clock clock, String url, Object context) {
super(source, clock);
this.url = url;
this.context = context;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Object getContext() {
return context;
}
public void setContext(Object context) {
this.context = context;
}
}
复制
监听事件的发生:调用了添加动态URL的Mock接口时发生
import com.baomidou.mybatisplus.core.toolkit.AES;
import com.gton.controller.TestController;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.UrlPathHelper;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
@SuppressWarnings("unchecked")
public class SystemDIYEventPushListener {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
@Lazy
private TestController testController;
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
@Value("${mp.event.aeskey:4b57e89bac82a797}")
private String aesKey;
private String mockUrls = "MockUrls";
@EventListener
public void handleUserRemovedEvent(AddMockInfoEvent event) {
String url = event.getUrl();
String redisSaveKeyUrl = AES.encrypt(url, aesKey);
Object context = event.getContext();
redisTemplate.opsForValue().setIfAbsent(redisSaveKeyUrl, context, 48, TimeUnit.HOURS);
Set<String> mockUrlsVar = redisTemplate.opsForSet().members(mockUrls);
if (CollectionUtils.isEmpty(mockUrlsVar)) {
mockUrlsVar = new HashSet<>();
} else {
RequestMappingInfo build = RequestMappingInfo.paths(mockUrlsVar.stream().toArray(String[]::new)).build();
requestMappingHandlerMapping.unregisterMapping(build);
}
try {
mockUrlsVar.add(url);
redisTemplate.opsForSet().add(mockUrls, url);
redisTemplate.expire(mockUrls, 48, TimeUnit.HOURS);
RequestMappingInfo requestMappingInfo =
RequestMappingInfo.
paths(mockUrlsVar.stream().toArray(String[]::new))
.build();
Method addMockInfoByGetMethod = TestController.class.getDeclaredMethod("addMockInfoByRequest");
requestMappingHandlerMapping.
registerMapping(requestMappingInfo,
testController,
addMockInfoByGetMethod);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
复制
测试

响应

试验新的Mock挡板是否动态添加成功

添加延时响应

查看效果