Skip to content

Instantly share code, notes, and snippets.

@wutingjia
Last active February 22, 2019 11:58
Show Gist options
  • Save wutingjia/c2bb4af712241b5e96f9d4a40e0d5445 to your computer and use it in GitHub Desktop.
Save wutingjia/c2bb4af712241b5e96f9d4a40e0d5445 to your computer and use it in GitHub Desktop.
mockServer

对于http协议和tcp协议分别在两个不同的端口进行监听。
在rpc调用的方法中,包装一层发送到mock的地址,其boolean值可以配置在application.yml中方便切换,在代码中使用${}占位符进行注入。

HTTP

//@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,原理一样。

TCP

在启动类中开启端口监听:

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();
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment