对于http协议和tcp协议分别在两个不同的端口进行监听。
在rpc调用的方法中,包装一层发送到mock的地址,其boolean值可以配置在application.yml中方便切换,在代码中使用${}占位符进行注入。
//@RestController 层
@PostMapping(path="/mock/**")
public String mockHttp(@RequestBody String body,@RequestHeader Map<String, String> header) {
return getRes(body, header, "", "");
}
String info = header.get("ZZZ"); //从报文头中获得一些信息
Map<String, String> valMap = JSONObject.parseObject(body, HashMap.class);//对于json报文可以转换成map处理,如果有结构的map注意泛型的后一个参数为Object
String transCode = valMap.get(valMapKey);//获得某个报文值
在外部配置文件.propertoes中 可以配置K=V,可以配置多个配置文件进行细分
这里的K,可以是报文中的K或V,目的是为了辨别出 正是这一种报文或者这一种报文的一种交易行为(增删改查等)
这里的V,是报文中的一个key,这个key可以是UID等,用来辨别每一条不同的报文
这里挡板文件名字格式为 targetTransCode_condValue.txt,里面放着用来模拟的返回报文
String transCode = valMap.get(valMapKey);//这里获得key
String cond = pro.getProperty(transCode);//查询属性文件
String targetTransCode = "/json/"+transCode;
if(!StringUtils.isEmpty(cond)) {
condValue = valMap.get(cond);
}
//最后去指定目录获取挡板文件即可,可以额外放targetTransCode.txt 这样对于这一种的报文,当找不到具体对应的condValue报文时,使用通用报文。
对于xml格式的解析可以参考另一篇名为saxReader的gist,原理一样。
在启动类中开启端口监听:
TcpMockService a=new TcpMockService(9999);
a.start();
Server类:
public TcpMockService(int port) throws Exception { server = new ServerSocket(port); }
public void start() {
while (true) {
Socket s = server.accept();//开启端口的监听,会一直阻塞直到收到信息
pool.execute(new Worker(s));
}
}
具体实现Runnable的类:
class Worker implements Runnable{
private Socket s;
private Properties bp;
Worker(Socket s){
this.s = s;
public void run() {
try {
InputStream is = s.getInputStream();
byte[] len = new byte[9];//假设前9位约定代表报文长度
is.read(len);
String l = new String(len, StandardCharsets.UTF_8);
int length = Integer.parseInt(l);//报文长度
byte[] cl = new byte[length];
is.read(cl);
Document d = saxReader.read(new ByteArrayInputStream(cl));
//...解析报文
String res = FileUtils.readFileToString(targetFile, "UTF-8");
int length2 = res.getBytes(StandardCharsets.UTF_8).length;
byte[] out = new byte[9 + length2];
byte[] templen = String.valueOf(length2).getBytes(StandardCharsets.UTF_8);
if (templen.length > 9) {
throw new RuntimeException("too big xml");
}
for (int i = 0; i < 9 - templen.length; i++) {
out[i] = 0x30;//按字节填写长度
}
System.arraycopy(templen, 0, out, 9 - templen.length, templen.length);
System.arraycopy(res.getBytes(StandardCharsets.UTF_8), 0, out, 9, length2);
s.getOutputStream().write(out);
s.getOutputStream().flush();
}
catch (Exception e){
e.printStackTrace();
}
}
}