この問題は 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