2

CRUD 操作のためにサーバーに AJAX 要求を行うと、JSON を返す Web アプリケーションがあります。これは、jQuery を使用してページ (MVC) を更新せずにデータを処理するためです。そのため、システムで新しいエントリを作成すると、サーバーは作成されたエントリを JSON 形式で含む応答を返します。jQuery は受信したデータを管理し、(以前に作成されたエントリを使用して) リストにエントリをレンダリングします。

今はHTML Unitでテストしていますが、試してみると

WebResponse response = page.getWebResponse()

200 ステータスと「OK」というメッセージが表示されます。しかし、作成したエントリの JSON データを期待していました。

そして、私が試してみると

page.asText()

現在のページの HTML を取得します (エントリは既にリストに含まれていますが、必要なデータはありません)。

これは、応答がなかったこの問題と同様の問題です: Json ajax call return response 200 ok

PD: jQuery フォームには 2 つのフィールドがあります。1 つは名前のテキスト入力で、もう 1 つは車の設定の選択です。選択する設定のリストをこの関数に渡します。名前は、タイムスタンプと静的 int シードで自動生成されます。これは私が使用しているコードです:

public void create(List<Settings> settings) throws FailingHttpStatusCodeException, MalformedURLException, IOException
{
    page = webClient.getPage("localhost:8080/cars/list");

    int elementsCount = getEntitiesCount();
    creationSeed = elementsCount+1;

    HtmlAnchor anchor = (HtmlAnchor) page.getFirstByXPath("//a[@class='action-createCar']");
    page = (HtmlPage) anchor.click();

    HtmlForm form = page.getFirstByXPath("//form[@class='CarsForm']");
    form = page.getForms().get(0);
    HtmlTextInput nameField = form.getInputByName("CarsForm-name");
    nameField.setText("Test " + creationSeed + " - " + new Date().getTime());

    HtmlSelect columnSelectList = (HtmlSelect) form.getSelectByName("CarsForm-settings");
    if (settings != null && settings.size() > 0)
        for (Settings setting : settings)
        {
            HtmlOption htmlOption = columnSelectList.getOptionByValue(setting.name());
            htmlOption.setSelected(true);
        }

    //looking for the button to submit the form
    HtmlDivision buttonSet = page.getFirstByXPath("//div[@class='ui-dialog-buttonset']");
    HtmlButton okButton = (HtmlButton) buttonSet.getFirstElementChild();

    page = okButton.click();

    assertEquals(elementsCount + 1, getEntitiesCount());

    //Here is where I want to get the server response to check the data which is returned by the server
    //And neither page.getWebResponse() or page.asText() contains it
}

}

4

1 に答える 1

11

同様の問題があり、HtmlUnit FAQ ページを使用して解決策を見つけました。

HttpWebConnection をサブクラス化し、getResponse() を次のようにオーバーライドできます。

   new WebConnectionWrapper(webClient) {

       public WebResponse getResponse(WebRequest request) throws IOException {
           WebResponse response = super.getResponse(request);
           if (request.getUrl().toExternalForm().contains("my_url")) {
               String content = response.getContentAsString("UTF-8");

               //change content

               WebResponseData data = new WebResponseData(content.getBytes("UTF-8"),
                       response.getStatusCode(), response.getStatusMessage(), >response.getResponseHeaders());
               response = new WebResponse(data, request, response.getLoadTime());
           }
           return response;
       }
   };

これが意味することは、webClient オブジェクトをラップし、必要な要求と応答をインターセプトし、それらを抽出または変更できるということです。


WebConnectionWrapper を拡張する内部クラスを作成し、必要な JSON であるフィールドを 1 つ持っています。

private class JsonResponseWebWrapper extends WebConnectionWrapper{

    public JsonResponseWebWrapper(WebClient webClient){
        super(webClient);           
    }
    
    String jsonResponse;
    
    @Override
    public WebResponse getResponse(WebRequest request) throws IOException {;
        WebResponse response = super.getResponse(request);
        //extract JSON from response
        jsonResponse = response.getContentAsString();
        return response;
    }

    public String getJsonResponse() {
        return jsonResponse;
    }
};

このようにして、すべての応答を傍受します。しかし、最初に webClient をラップする必要があります。JSON 応答を要求する直前にこれを行ったので、ラッパーに条件を追加する必要はありませんでした。

JsonResponseWebWrapper jrww = new JsonResponseWebWrapper(webClient);
page = button.click();
String rawJSON = jrww.getJsonResponse();

その後、お気に入りの JSON パーサーを使用して解析できます。お役に立てれば!

于 2013-09-17T15:23:06.043 に答える