私は実際に、基本的にあらゆるレスポンスをモックできる独自の Java REST Mock Engine を作成することになりました。http 応答全体をシミュレートするテキスト ファイルを手作りまたはカット アンド ペーストできる限り、このソリューションを使用してサービスをモックすることができます。
サーブレットは次のとおりです。
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
内部 WebContentというフォルダー内にこのファイルを配置したとします。
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 ヘッダーをシミュレートできます。これまでのところ、別のサーバー ヘッダーで応答することさえできます (私の例では、IIS 6.0 のふりをして応答をシミュレートしました)。または別の HTTP ステータス コードなど。
ブラウザ/javascriptから呼び出すには; 最初に次のようにプライミングします。
http://yourserver/yourweb/MockGridData?__setdata=data/init.http
次に、JavaScript または REST AJAX 呼び出しで、
http://yourserver/yourweb/MockGridData
任意のメソッドまたはパラメーターを使用。以前に作成した http 応答を取得します。Content-Range に至るまで。ヘッダーをキャッシュします。その後の AJAX 呼び出しで何か他のものを返す必要がある場合は、単純に__setdata
もう一度呼び出します。Web アプリで明示的な状態遷移を行うためのボタンをいくつか設定することをお勧めします。
すべてがセットアップされていると仮定すると、シミュレートされた 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 とは異なる結果が予想されます。
これは、バイナリおよび gzip された応答でも機能するはずですが、私はそれをテストしていません。