Smartgwt RestDataSource与SpringMVC和跨客户端

Smartgwt RestDataSource与SpringMVC和跨客户端,第1张

Smartgwt RestDataSource与SpringMVC和跨客户端

RPCManager.setAllowCrossDomainCalls(true);
应该在初始化的早期阶段调用(例如-
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 + " ) " ; }

更新资料

清理代码(或从头开始/最少)可能是个好主意,原因是先前的工作遗留了余下的时间。

解决此问题的过程分为三个阶段:
1. 在 使用服务的 情况下 使SmartGWT正常工作
2.在CORS请求下使服务正常工作
3.切换SmartGWT以使用服务

应该使用阶段1来解决所有客户端问题。
如果客户端在同一主机/域中部署时正在使用服务,请跳至阶段2。

阶段1
为此,可以使用提供静态响应的数据URL,如RestDataSource
JSON响应中所述。
将样本响应放置在类似于的文件中,

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:7117User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,**;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateOrigin: http://localhost:8118Access-Control-Request-Method: GETAccess-Control-Request-Headers: content-typeServer: Apache-Coyote/1.1Access-Control-Allow-Origin: http://localhost:8118Access-Control-Allow-Methods: GETAccess-Control-Allow-Headers: Content-TypeAllow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONSContent-Length: 0Host: localhost:7117User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateContent-Type: application/jsonReferer: http://localhost:8118/cors-test.htmlOrigin: http://localhost:8118Server: Apache-Coyote/1.1Access-Control-Allow-Origin: *Content-Type: application/jsonTransfer-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请求。
由于浏览器与CORS请求不兼容,仅在必须依赖JSONP时才使用XJSONDataSource。

发送

Access-Control-Allow-Origin:*
飞行前请求将允许任何站点对服务进行跨域调用,这可能造成安全问题,
*
并且不能在某些CORS请求中使用。
更好的方法是指定允许跨域请求的确切站点-
Access-Control-Allow-Origin: http://www.foo.com

在这种情况下可能不需要,但是请检查“访问控制允许起源多源域”吗?如果需要,可以找到允许多个站点发出CORS请求的方法。

参考文献:
[1] https://developer.mozilla.org/zh-
CN/docs/HTTP/Access_control_CORS
[2] http://java-success.blogspot.com/2012/11/cors-and-jquery-with-spring
-mvc-restful.html



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5441852.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存