gpt4 book ai didi

web-services - 如何从服务器端模拟复杂的 REST 调用?

转载 作者:行者123 更新时间:2023-12-04 04:37:35 26 4
gpt4 key购买 nike

在使用广泛使用 REST 服务的 javascript 时——包括使用 GET、PUT、POST、DELETES 等词汇;我发现很难模拟服务器端,因此前端开发可以独立(后端)进行。

有时捕获多步数据也很有用,因此我们甚至可以帮助重现整个 REST 链(或从这些链触发的与前端相关的错误)

我可以使用哪些工具来模拟 REST 调用,尤其是有状态的调用? (即,如果我对某个资源执行 PUT,我希望它的下一个 GET 会以某种方式改变)

我尝试了 SOAPUI 4.0.1,它的 REST 模拟令人失望。另外,我需要的不仅仅是单状态模拟(任何人都可以使用静态 .json 文件来完成)。我需要做状态转换类型的模拟;最好使用 Content-Range header 。

任何人?

最佳答案

实际上,我最终创建了自己的 Java REST Mock Engine,它基本上可以模拟任何响应。只要您可以手工制作或剪切粘贴模拟整个 http 响应的文本文件,您就可以使用我的解决方案来模拟该服务。

这是servlet:

package com.mockrest.debug;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
* Servlet implementation class MockGridData
*/
public class MockRest extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public MockRest() {
super();
// TODO Auto-generated constructor stub
}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
sub:{
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
String setdata = request.getParameter("__setdata");
if (setdata!=null && setdata.length()>0){
System.err.println("Setting Data...");
HttpSession sess = request.getSession(true);
String data = "/"+request.getParameter("__setdata");
sess.setAttribute("data", data);
try{
InputStream is = getServletContext().getResourceAsStream(data);
if (is!=null){
is.close();
response.getWriter().write("Successfully pointed next REST call to:"+data);
}
else{
response.sendError(500, "Cannot find resource:"+data);
}
}
catch (IOException ioe){
response.sendError(500, Arrays.deepToString(ioe.getStackTrace()));
}

}
else{
System.err.println("Fetching Data...");
HttpSession sess = request.getSession(false);
if (sess==null || sess.getAttribute("data")==null){
response.sendError(500,"Session invalid or no Previous Data Set!");
}
String rsrc = (String)sess.getAttribute("data");
System.err.println("Resource Being used:"+rsrc);
InputStream is = getServletContext().getResourceAsStream(rsrc);
if (is!=null){
String statusline = readLine(is);
Pattern statusPat = Pattern.compile("^HTTP/1.1 ([0-9]+) (.*)$");
Matcher m = statusPat.matcher(statusline);
if (m!=null && m.matches()){
int status = Integer.valueOf(m.group(1));
response.setStatus(status, m.group(2));
}
else{
throw new ServletException("Bad input file: status line parsing failed, got this as status line:"+statusline);
}
String line;
Pattern httpHeaderPat = Pattern.compile("^([^:]+): (.*)$");
while ((line=readLine(is))!=null){
if (line.length()==0){
// end of headers
break;
}
Matcher m2 = httpHeaderPat.matcher(line);
if (m2!=null && m2.matches()){
response.setHeader(m2.group(1), m2.group(2));
}
}
OutputStream os = response.getOutputStream();
byte[] buf = new byte[1024];
int size;
while ((size=is.read(buf))>0){
os.write(buf, 0, size);
}
os.flush();
}
}
}
}

private String readLine(InputStream is) throws IOException {
StringBuffer sb = new StringBuffer();
char c;
while ((c=(char)is.read())!='\n'){
sb.append(c);
}
if (sb.charAt(sb.length()-1) == '\r'){
sb.deleteCharAt(sb.length()-1);
}
return sb.toString();
}

}

要配置它,请将预先构建的响应文件放入您的 WebContent 中。文件夹。我通常以 .http 结束这些文件。扩展名。

一个例子 init.http文件在下面。假设我们将此文件放在名为 data 的文件夹中内网页内容:
HTTP/1.1 200 OK
Date: Wed, 26 Oct 2011 18:31:45 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Content-Range: items 0-1/2
Content-Length: 385
Cache-Control: private
Content-Type: application/json

[
{
"id": "249F0",
"field1": " Global",
"displaystartdate": "2007-10-20",
"displayenddate": "2012-10-20",
"status": "Major Delay",
"children": true
},
{
"id": "962581",
"field2": "Europe",
"displaystartdate": "2007-10-20",
"displayenddate": "2012-10-20",
"status": "Major Delay",
"children": true
}
]

标题 必须用空行与正文分开(无空格,nada)。熟悉 http 的人会注意到它是一个纯粹的 http 响应。这是故意的。

您可以使用此工具模拟您希望响应具有的任何 http header ;甚至到目前为止响应不同的服务器 header (在我的示例中,我模拟了假装是 IIS 6.0 的响应);或不同的 HTTP 状态码等。

从您的浏览器/javascript 调用它;首先用:
http://yourserver/yourweb/MockGridData?__setdata=data/init.http

然后在您的 javascript 或 REST AJAX 调用中,如果它转到
http://yourserver/yourweb/MockGridData

使用任何方法或参数;它将获得您之前制作的 http 响应;甚至到内容范围;缓存头;等等,如果您需要随后的 AJAX 调用来返回其他内容,只需调用 __setdata再次。我建议您设置一些按钮来在您的网络应用程序中进行显式状态转换。

假设一切都已设置好,对于模拟的 REST 链,开发人员可以执行以下操作:
  • 调用
    http://yourserver/yourweb/MockGridData?__setdata=data/init.http
  • 运行将导致调用的 javascript 模块(例如,使用 GET)
    http://yourserver/yourweb/MockGridData
  • 单击一个按钮,然后执行:
    http://yourserver/yourweb/MockGridData?__setdata=data/step1.http
  • 运行另一个将导致调用的 javascript 步骤(例如,使用 PUT)
    http://yourserver/yourweb/MockGridData
  • 单击另一个按钮,然后执行:
    http://yourserver/yourweb/MockGridData?__setdata=data/step2.http
  • 运行另一个将导致调用的 javascript 步骤(例如,使用 GET)
    http://yourserver/yourweb/MockGridData

    但这次期待与#4 不同的结果。

  • 这甚至应该适用于二进制和压缩响应,但我还没有测试过。

    关于web-services - 如何从服务器端模拟复杂的 REST 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7921074/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com