spring ext 跨域
read方法中调用的response对象是父类BaseController的一个成员变量.
spring默认bean的生命周期Score为singleton单例模式.
当多线程并发使用同一bean, 并使用bean中的同一成员变量时会有问题. 比如下例中的成员变量response
以下是服务端跨域代码.
@Controller @Scope("request") @RequestMapping("/CrossDomain") public class CrossDomainController extends BaseController { @RequestMapping("/read") @ControllerLog(description = "跨域请求") public void read(@RequestParam Map<String, Object> params) throws IOException { String url = (String) params.get("url"); if(BlankUtil.isNotEmpty(url)) { HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost(url); // 设置请求的header httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); // 设置请求的参数 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); for (String key : params.keySet()) { nvps.add(new BasicNameValuePair(key, String.valueOf(params.get(key)))); } httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8")); // 执行请求 HttpResponse httpResponse = httpClient.execute(httpPost); String result = EntityUtils.toString(httpResponse.getEntity(), "utf-8"); if("xml".equalsIgnoreCase(String.valueOf(params.get("type")))) { response.setContentType("text/xml; charset=UTF-8"); } try { System.err.println("---------->" + String.valueOf(params.get("type")) + result.length()); PrintWriter out = response.getWriter(); out.write(result); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } } }
修改Bean的生命周期scope配置为request或prototype即可.
JS代码(请求Java后台得到远程服务器xml文本内容, 然后在js端转换成xmldoc对象)
function crossDomainloadXmlFile(config) { var doc = null; Ext.Ajax.request({ url : config.url, // 请求地址 params : config.params, // 请求参数 timeout: config.timeout || 30000, async : false,//同步请求 method : 'post', // 方法 callback : function(options, success, response) { if(!success) { if(top.checkTimeoutAndRelogin(response.status)) { top.Ext.MessageBox.alert('错误提示', response.message); } return; } console.log('crossDomainloadXmlFile:' + response.responseText) doc = parseXmlString(response.responseText); } }); return doc; } function parseXmlString(xmlString) { var doc; if (window.ActiveXObject) { doc = new ActiveXObject("Microsoft.XMLDOM"); doc.setProperty("SelectionLanguage", "XPath"); doc.async = false; doc.loadXML(xmlString); } // load XML string code for Mozilla, Firefox, Opera, etc. else { var parser = new DOMParser(); doc = parser.parseFromString(xmlString, "text/xml"); } return doc.documentElement; }
EXT组件:
/** * Created by huangbaidong on 2016/6/30. * 简单数据字典通用Store, * 外部调用传入参数dictionaryId作为过滤条件. * 使用案例: store: Ext.create('app.component.sys.dictionary.SimpleDictionaryXmlStore', { dictionaryId : 1 }) */ Ext.define('app.component.sys.dictionary.SimpleDictionaryXmlStore', { extend: 'Ext.data.XmlStore', storeId :'simpleDictionaryStore', dictionaryId : 0, constructor : function(config) { var me = this; Ext.apply(config, { fields: [{ name: 'id', mapping: '@id' }, { name: 'name', mapping: '@name' }, { name: 'dictionaryId', mapping: '@dictionaryId' }], data:(function(){ var array = []; Ext.each(top.simpleDictionaryStore.getData().items, function(item) { if(item.data.dictionaryId == config.dictionaryId) { array.push(item); } }) return array; })() }); app.component.sys.dictionary.SimpleDictionaryXmlStore.superclass.constructor.call(this, config); } });
/** * 跨域获取数据字典, 并缓存为全局单例Store * @type {Ext.data.Store} */ top.simpleDictionaryStore = Ext.create('Ext.data.Store', { autoLoad : true, fields: [{ name: 'id', mapping: '@id' }, { name: 'name', mapping: '@name' }, { name: 'dictionaryId', mapping: '@dictionaryId' }], proxy: { type: 'ajax', url: '../CrossDomain/read', reader: { type: 'xml', record: 'simpleDictionary', idProperty: '@id', totalRecords: '@total' }, extraParams:{//服务端跨域处理 url: DICTIONARY_URL, type : 'xml' } } });