1

この問題は 1 日中悩まされていました。私はここで多くの時間を費やし、Google で正しい答えを見つけようとしてさまざまな修正を試みました。

ここで定義されているSpring MVCコントローラーがあります:

@RequestMapping(value = "/searchAndCount", method = RequestMethod.GET, produces = "application/json", headers =
{ "Accept=application/json", "Content-Type=application/json" }, consumes = "application/json")
public @ResponseBody
RequestResults<?> searchAndCount(@RequestBody SearchInvoiceDTO searchInvoiceDto)
{
      RequestResults<?> requestResults = invoiceApprovalService.searchAndCount(searchInvoiceDto);
    return requestResults;
}

ほとんどの get では単純なパラメーターが返されることはわかっていますが、この場合は、すべての検索条件を 1 つのオブジェクトに入れて送信する方がよいことがわかりました。これが、@RequestBody を実行している理由です。

以前の修正に従って、JSON 出力を受け入れるために必要な可能性がある両方のヘッダーが含まれていることを確認しました。

JSON 文字列は次のようになります。 String s1 = "{\"userId\":3, \"ddUserId\":301010651, \"customerCode\":\"QA\", \"customerId\":8}"; はい、Jackson ObjectMapper ツールを使用して、このコードがこの文字列からオブジェクトに、またはその逆に正しくマップされることを確認しました。POJO を見ると、Serializable が実装されており、デフォルトのコンストラクターがあります。

Junit テストは素晴らしく機能し、データを返します。

MockHttpServletRequestBuilder requestBuilder =
        MockMvcRequestBuilders.get("/invoices/searchAndCount").contentType(MediaType.APPLICATION_JSON)
        .content(test);

    this.mockMvc.perform(requestBuilder).andDo(print());

これにより、コントローラーが呼び出されます。出力からヘッダーが何であるかを確認でき、実際に実際のデータが返されることがわかります。これは素晴らしいことです。そのため、コントローラー側からできることはあまりないと感じています。

コントローラーへの実際の呼び出しは、SmartGWT RestDataSource から行われます。

RequestMethod はデータソースで定義されています。ここに init メソッドがあります。

private InvoiceDataSource(String id)
{
    setID(id);
    setClientOnly(false);

    // set up FETCH to use GET requests
    OperationBinding fetch = new OperationBinding();
    fetch.setOperationType(DSOperationType.FETCH);
    fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
    fetch.setDataFormat(DSDataFormat.JSON);
    DSRequest fetchProps = new DSRequest();
    fetchProps.setHttpMethod("GET");
    fetch.setRequestProperties(fetchProps);

    // set up ADD to use POST requests
    OperationBinding add = new OperationBinding();
    add.setOperationType(DSOperationType.ADD);
    add.setDataProtocol(DSProtocol.POSTMESSAGE);
    // ===========================================
    DSRequest addProps = new DSRequest();
    addProps.setHttpMethod("POST");
    add.setRequestProperties(addProps);

    // set up UPDATE to use PUT
    OperationBinding update = new OperationBinding();
    update.setOperationType(DSOperationType.UPDATE);
    update.setDataProtocol(DSProtocol.POSTMESSAGE);
    // ===========================================
    DSRequest updateProps = new DSRequest();
    updateProps.setHttpMethod("PUT");
    // updateProps.setContentType("application/json");
    update.setRequestProperties(updateProps);

    // set up REMOVE to use DELETE
    OperationBinding remove = new OperationBinding();
    remove.setOperationType(DSOperationType.REMOVE);
    DSRequest removeProps = new DSRequest();
    removeProps.setHttpMethod("DELETE");
    remove.setRequestProperties(removeProps);

    // apply all the operational bindings
    setOperationBindings(fetch, add, update, remove);

    init();
}

Fetch は、transformReponse を使用してデータを渡す最良の方法と思われる POSTMESSAGE に設定されています。

@Override
protected Object transformRequest(DSRequest dsRequest)
{
    // gets the correct URL - (web-app-root)/rest/invoices/searchAndCount
    postProcessTransform(dsRequest);

    System.out.println("InvoiceDataSource: transformRequest: START");
    dsRequest.setContentType("application/json");
    JavaScriptObject jso = dsRequest.getData();

    // setting more headers, but this doesn't seem to change anything
    dsRequest.setAttribute("Access-Control-Allow-Origin", "*");
    dsRequest.setAttribute("Content-Type", "application/json");
    dsRequest.setAttribute("Accept", "application/json");

    String s1 = JSON.encode(jso);
    System.out.println("InvoiceDataSource: transformRequest: FINISH: s1=" + s1);
    return s1;
}

私は彼が正しい URL を持っていることを知っているので、変数 "s1" にも正しい JSON データがあることを吐き出していることも知っています。もう一度その JSON をテストして、コントローラーに正しくヒットすることを確認しました。

また、pom.xml ファイルで定義されているように、Jackson の依存関係もあります。また、springmvc-servlet.xml ファイルにメッセージ コンバーターを設定しています。これらが正しくない場合、単体テストは機能しません。ただし、pom.xml ファイルまたは springmvc-servlet.xml ファイルを参照する必要がある場合は、お知らせください。

私は今、一日中多くのことを研究し、試してきましたが、これまでのところ... 運がありません. 十分な情報を提供できたと思いますが、さらに必要な場合はお知らせください。最終的には、SmartGWT RestDataSource を微調整して、正しいデータをこのコントローラーに渡して、実際にコントローラーからデータを取得できることを願っています。

更新: Eclipse で Jetty を使用してこれを実行すると、Firefox 23.0.1 を使用して Web アプリを開きます。Eclipse のコンソール内では、次のように表示されます。

[WARN] 415 - GET /rest/invoices/searchAndCount (127.0.0.1) 1440 bytes
Request headers
  Host: 127.0.0.1:8888
  User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language: en-US,en;q=0.5
  Accept-Encoding: gzip, deflate
  Cookie: GLog=%7B%0D%20%20%20%20left%3A22%2C%20%0D%20%20%20%20top%3A11%2C%20%0D%20%20%20%20width%3A705%2C%20%0D%20%20%20%20height%3A855%2C%20%0D%20%20%20%20priorityDefaults%3A%7B%0D%20%20%20%20%20%20%20%20Log%3A4%0D%20%20%20%20%7D%2C%20%0D%20%20%20%20defaultPriority%3A3%2C%20%0D%20%20%20%20trackRPC%3Atrue%0D%7D
   Connection: keep-alive
   If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
 Response headers
  Content-Type: text/html; charset=iso-8859-1
  Content-Length: 1440
  Accept: application/json

Request ヘッダー: Accept: text/html,application/xhtml+xml,application/xml;q=0.9, / ;q=0.8 は application/json を表示しないことに注意してください。 また、Request header: "Content-Type" は表示されません。現在

Chrome を使用すると、結果は次のようになります。

[WARN] 415 - GET /rest/invoices/searchAndCount (127.0.0.1) 1440 bytes
Request headers
   Host: 127.0.0.1:8888
   Connection: keep-alive
   Accept: */*
   User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
   DNT: 1
   Accept-Encoding: gzip,deflate,sdch
   Accept-Language: en-US,en;q=0.8
   If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
   Cache-Control: max-age=0
Response headers
   Content-Type: text/html; charset=iso-8859-1
   Content-Length: 1440
   Accept: application/json

JUnit テストから実行すると、常に「Content-Type:application/json」が存在します。そのため、いくつかの場所で JSON を使用していることを SmartGWT RestDataSource に伝えていますが、Web サービス呼び出しが正しいヘッダーを作成していないようです。

更新: 次のコードを SmartGWT RestDataSource transformRequest メソッドに追加しました。

    Map<String, String> httpHeaders = new HashMap<String, String>();
    httpHeaders.put("Accept", "*/*");
    httpHeaders.put("Content-Type", "application/json");
    dsRequest.setHttpHeaders(httpHeaders);

"Accept" Request-Header を追加できますが、415 Unsupported Media エラー メッセージが引き続き表示されます。「Content-Type」Request-Header を追加すると、400 BAD REQUEST エラー メッセージが表示されます。

私は今コンソールでこれを取得します:

[WARN] 400 - GET /rest/invoices/searchAndCount (127.0.0.1) 1418 bytes
Request headers
   Host: 127.0.0.1:8888
   User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
   Accept: */*
   Accept-Language: en-US,en;q=0.5
   Accept-Encoding: gzip, deflate
   Connection: keep-alive
   If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
   Content-Type: application/json
Response headers
   Content-Type: text/html; charset=iso-8859-1
   Content-Length: 1418
4

1 に答える 1