RPCManager.setAllowCrossDomainCalls(true);
初期化の初期段階で呼び出す必要があります (eg- onModuleLoad()
)。
getContactTypeByUserId
Access-Control-Allow-Origin
適切な値を持つ応答ヘッダーとして追加する必要がある場合があります。http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
を
確認してください。http://forums.smartclient.com/showthread.php?t=15487に
基づくと、SmartGWT はクロスドメイン リクエストを単独で処理する必要があります。
最悪のシナリオとして、これを機能させるために必要なヘッダーとともに JSONP スタイルの応答を送信する必要がある場合があります。
その場合、SmartGWT 要求を処理するために、次のような別の方法を用意するのがおそらく最善です。
私は XJSONDataSource を扱ったことがないので、以下は単なるガイドラインです。
// use a slightly different URI to distinguish from other controller method
@RequestMapping(value = "/invoiceId/sgwt", method = RequestMethod.GET, headers = "Accept=application/json")
public @ResponseBody String getContactTypeByUserIdForSgwt(@RequestBody String invoiceNumber,
HttpServletRequest request, HttpServletResponse response) {
// can reuse normal controller method
InvoiceDetailDTO invoiceDetailDto = getContactTypeByUserId(invoiceNumber);
// use jackson or other tool to convert invoiceDetailDto to a JSON string
String JSONstring = convertToJson(invoiceDetailDto);
// will have to check SmartGWT request to make sure actual parameter name that send the callback name
String callbackString = request.getParameter("callback");
response.setContentType("text/X-JSON");
return callbackString + " ( " + JSONstring + " ) " ;
}
アップデート
以前の作業の残り物のため、コードをクリーンアップする (または最初から/最小から開始する) ことをお勧めします。
これを解決するには、次の 3 つのフェーズがあります。 1. サービスを使用せず
に SmartGWT を正しく動作させる
2. サービスを CORS 要求で正しく動作させる
3. SmartGWT を切り替えてサービスを使用する
フェーズ 1 は、クライアント側の問題を解決するために使用する必要があります。
クライアントが同じホスト/ドメインにデプロイされたときにサービスを使用している場合は、フェーズ 2 にスキップします。
フェーズ 1
このために、RestDataSource JSON 応答で説明されているように、静的応答を提供するデータ URL を使用できます。
のようなファイルにサンプル応答を配置し、test.json
クライアント Web アプリケーションからアクセスできるようにします。
DataSource コードを最小限に抑え、場所とともに使用setDataURL();
しtest.json
ます。
test.json
- フィールド名と値を変更 (必要に応じて追加)
{
response:{
status:0,
startRow:0,
endRow:3,
totalRows:3,
data:[
{field1:"value", field2:"value"},
{field1:"value", field2:"value"},
{field1:"value", field2:"value"},
]
}
}
情報源
public class TestDS extends RestDataSource {
private static TestDS instance = new TestDS();
public static TestDS getInstance() {
return instance;
}
private TestDS() {
setDataURL("data/test.json"); // => http://<client-app-host:port>/<context>/data/test.json
setDataFormat(DSDataFormat.JSON);
// setClientOnly(true);
DataSourceTextField field1 = new DataSourceTextField("field1", "Field 1");
DataSourceTextField field2 = new DataSourceTextField("field2", "Field 2");
setFields(field1, field2);
}
}
フェーズ 2
詳細については、参考文献を確認してください。
でホストされているページおよび でホストされているサービスから作成された、失敗したプリフライト CORS リクエストのヘッダー。
ポートが異なるため失敗しました。異なるスキーム (https/ftp/file/etc.) または異なるホスト/ドメインでも失敗します。localhost:8118
localhost:7117
Host: localhost:7117
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.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
Origin: http://localhost:8118 <= indicates origin to which access should be granted
Access-Control-Request-Method: GET <= indicates the method that will be used in actual request
Access-Control-Request-Headers: content-type <= indicates the headers that will be used in actual request
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Content-Length: 0
成功したリクエストのリクエスト/レスポンス ヘッダーのペア。
Host: localhost:7117
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.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
Origin: http://localhost:8118
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:8118
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Content-Type
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Content-Length: 0
Host: localhost:7117
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Referer: http://localhost:8118/cors-test.html
Origin: http://localhost:8118
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: *
Content-Type: application/json
Transfer-Encoding: chunked
CORS リクエストをサポートするために、サービス バックエンドは、サービス コールだけでなく、プリフライト OPTIONS リクエストに正しく応答する必要があります。
これは、ServletFilter を使用して実行できます。
<filter>
<filter-name>corsfilter</filter-name>
<filter-class>test.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
response.addHeader("Access-Control-Allow-Origin", "http://localhost:8118");
// list of allowed methods, Access-Control-Request-Method must be a subset of this
response.addHeader("Access-Control-Allow-Methods", "GET");
// list of allowed headers, Access-Control-Request-Headers must be a subset of this
response.addHeader("Access-Control-Allow-Headers", "Content-Type, If-Modified-Since");
// pre-flight request cache timeout
// response.addHeader("Access-Control-Max-Age", "60");
}
filterChain.doFilter(request, response);
}
}
@RequestMapping(method = RequestMethod.GET, value = "/values", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map> getValues() {
List<Map<String, Object>> values = getValues(); // handle actual data processing and return a list suitable for response
SgwtResponse sgwtResponse = new SgwtResponse(); // A POJO with basic (public) attributes
sgwtResponse.status = 0L;
sgwtResponse.startRow = 0L;
sgwtResponse.endRow = Long.valueOf(values.size());
sgwtResponse.totalRows = sgwtResponse.startRow + sgwtResponse.endRow;
sgwtResponse.data = values; // java.util.List
Map<String, SgwtResponse> jsonData = new HashMap<String, SgwtResponse>();
jsonData.put("response", sgwtResponse);
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*"); // required
return new ResponseEntity<Map>(jsonData, headers, HttpStatus.OK);
}
jQuery を使用して、XHR を使用して JSON 応答を取得する単純なテスト ページ。
URL を変更してクライアント Web アプリケーションにデプロイし、SmartGWT を使用せずにサービスを直接テストします。
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#retrieve").click(function () {
$.ajax({
type: "GET",
contentType: "application/json",
url: "<URL-of-service>",
dataType: "json",
success: function (data, status, xhr) {
$("#content").text(JSON.stringify(data, null, 2));
},
error: function (xhr, status, error) {
$("#content").text("Unable to retrieve data");
}
});
});
});
</script>
</head>
<body>
<input type="button" id="retrieve" value="Retrieve"/>
<div id="content"/>
</body>
</html>
If-Modified-Since
Access-Control-Allow-Headers
SmartGWTにはヘッダーが必要でした。警告を回避するには、SmartGWT の初期化中に
使用します。RPCManager.setAllowCrossDomainCalls(true);
最近のほとんどのブラウザー (ブラウザー互換性1 ) と SmartGWT RestDataSourceは、CORS 要求をサポートしています。
XJSONDataSource は、ブラウザーが CORS 要求と互換性がないため、JSONP に依存する必要がある場合にのみ使用してください。
プリフライト リクエストを送信Access-Control-Allow-Origin: *
すると、任意のサイトがサービスに対してクロス ドメイン呼び出しを行うことができます。これにより、セキュリティ上の問題が発生する可能性があり、さらに*
特定の CORS リクエストでは使用できません。
より良いアプローチは、クロス ドメイン リクエストが許可される正確なサイトを指定することです - Access-Control-Allow-Origin: http://www.foo.com
.
この場合はおそらく必要ありませんが、Access-Control-Allow-Origin Multiple Origin Domains を確認してください。必要に応じて、複数のサイトが CORS リクエストを行えるようにする方法を見つけます。
参考文献:
[1] https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS
[2] http://java-success.blogspot.com/2012/11/cors-and-jquery-with-spring -mvc-restful.html