/** * @class ServerScript.app * * ServerScript app是HttpServletRequest和HttpServletResponse关联的服务器端的JavaScript方法库。 */ app = { /** * 向当前用户的浏览器控制台中输出指定对象的日志信息。 * @param {Object} object 打印的对象。 */ log: function(object) { Console.print(request, Wb.encode(object), 'log', true); }, /** * 向当前用户的浏览器控制台中输出指定对象的提示信息。 * @param {Object} object 打印的对象。 */ info: function(object) { Console.print(request, Wb.encode(object), 'info', true); }, /** * 向当前用户的浏览器控制台中输出指定对象的警告信息。 * @param {HttpServletRequest} request 请求对象。该请求对象用于关联到对应用户。 * @param {Object} object 打印的对象。 */ warn: function(object) { Console.print(request, Wb.encode(object), 'warn', true); }, /** * 向当前用户的浏览器控制台中输出指定对象的错误信息。 * @param {Object} object 打印的对象。 */ error: function(object) { Console.print(request, Wb.encode(object), 'error', true); }, /** * 向当前用户的客户端发送指定对象。 * @param {Object} object 发送的对象。 * @param {Boolean} [successful] 是否成功标识。如果指定该参数将采用JSON格式封装,该模式仅适用于文件上传模式的数据发送。 */ send: function(object, successful) { if (Wb.isObject(object) || Wb.isArray(object)) object = Wb.encode(object); if (successful === undefined && WebUtil.jsonResponse(request)) { if (object === null) object = ''; //兼容java else if (object === undefined) object = 'undefined'; else object = object.toString(); successful = true; //upload模式的json格式响应 } if (successful === undefined) WebUtil.send(response, object); else WebUtil.send(response, object, successful); }, /** * 获取文件控件上传的单个或多个文件。 * @param {String} fieldName 文件控件名称。 * @return {Object[]} 获取的文件数据[{stream:输入流,name:文件名称,size:文件长度},...],如果未找到返回空数组。 */ getFiles: function(fieldName) { var files = [], index = '', prefix = '', data; function getData(name) { var file = request.getAttribute(name); if (file instanceof java.io.InputStream) return { stream: file, name: request.getAttribute(name + '__name'), size: request.getAttribute(name + '__size') }; else return null; } while ((data = getData(fieldName + prefix + index))) { files.push(data); if (index === '') { index = 0; prefix = '@'; } index++; } return files; }, /** * 获取HttpServletRequest和HttpSession对象中指定名称的属性或参数。 * 如果相同名称的属性或参数都存在则返回优先顺序最高的值。优先顺序依次为 * HttpSession的attribute,HttpServletRequest的attribute和 * HttpServletRequest的parameter。如果都不存在则返回null。 * 如果name参数缺省,将返回所有值组成的对象。 * @param {String} [name] 参数或属性或称。 * @param {Boolean} [returnString] 如果获取单个参数,false返回原始对象值,true返回原始对象转换为字符串后的值。默认为false。 * @return {Object} 请求对象的parameter和attribute中的值组成的对象。 */ get: function(name, returnString) { if (name === undefined) { //获取全部值 var jo = WebUtil.fetch(request), result = {}; jo.entrySet().forEach(function(e) { result[e.key] = e.value; }); return result; } else { //获取单个值 return returnString ? WebUtil.fetch(request, name) : WebUtil.fetchObject(request, name); } }, /** * 获取指定名称的参数,并转换为布尔类型。 * @param {String} name 参数名称。 * @return {Boolean} 参数转换后的布尔值。 */ getBool: function(name) { return Wb.parseBool(app.get(name)); }, /** * 获取指定名称的参数,并转换为整数类型。 * @param {String} name 参数名称。 * @return {Integer} 参数转换后的整数值。 */ getInt: function(name) { return parseInt(app.get(name), 10); }, /** * 获取指定名称的参数,并转换为浮点数类型。 * @param {String} name 参数名称。 * @return {Double} 参数转换后的浮点值。 */ getFloat: function(name) { return parseFloat(app.get(name)); }, /** * 获取指定名称的参数,并转换为日期类型。参数必须为有效日期格式的字符串。 * @param {String} name 参数名称。 * @return {Date} 参数转换后的日期值。 */ getDate: function(name) { return Wb.strToDate(app.get(name, true)); }, /** * 获取指定名称的参数,并转换为Java日期类型。参数必须为有效日期格式的字符串。 * @param {String} name 参数名称。 * @return {Date} 参数转换后的日期值。 */ getJavaDate: function(name) { return DateUtil.strToDate(app.get(name, true)); }, /** * 获取指定名称的参数,并转换为对象/数组。 * @param {String} name 参数名称。 * @return {Object/Array} 参数转换后的对象。 */ getObject: function(name) { var str = app.get(name, true); if (!str) throw 'Param "' + name + '" is null or blank'; return Wb.decode(str); }, /** * 获取指定名称的参数,并转换为Java字符串数组。 * @param {String} name 参数名称。 * @return {JavaString[]} 参数转换后的对象。 */ getJavaArray: function(name) { return Java.to(app.getObject(name), Java.type('java.lang.String[]')); }, /** * 判断指定参数是否不为空。参数是指存储在session的attribute,request的attribute或parameter中的值。 * @param {String} name 参数名称。 * @return {Boolean} 如果参数存在且其值不为空则返回true,否则返回false。 */ has: function(name) { return !Wb.isEmpty(app.get(name, true)); }, /** * 遍历对象,并把对象中每个条目的值设置到request的attribute对象,attribute名称为对象中条目的名称。 * 如果首个参数不是对象,将以第1个参数为名称,第2个参数为值,设置到attribute。 * @param {Object/String/Map/JSONObject} object 设置的对象。 * @param {Object} [val] 如果object为字符串,该项为设置的值。 */ set: function(object, val) { if (Wb.isObject(object) || ((SysUtil.isMap(object) || object instanceof JSONObject) && object.entrySet)) { Wb.each(object, function(k, v) { request.setAttribute(k, v); }); } else if (object) request.setAttribute(object, val); }, /** * 启动jndi指定的数据库连接的事务,如果指定的连接已经启动事务则该方法没有任何效果。 * @param {String} [jndi] 数据库jndi变量名称。为空表示使用默认使用库。 * @param {Integer} [isolation] 事务的孤立程度,值对应Connection.TRANSACTION_XXX值。 */ startTrans: function(jndi, isolation) { var conn = DbUtil.getConnection(request, (jndi || null)); if (conn.getAutoCommit()) { conn.setAutoCommit(false); if (isolation) conn.setTransactionIsolation(isolation); } }, /** * 提交jndi指定的数据库连接的事务,如果指定的连接事务已经提交或回滚则该方法没有任何效果。 * @param {String} [jndi] 数据库jndi变量名称。为空表示使用默认使用库。 */ commit: function(jndi, isolation) { var conn = DbUtil.getConnection(request, (jndi || null)); if (!conn.getAutoCommit()) { conn.commit(); } }, /** * 回滚jndi指定的数据库连接的事务,如果指定的连接事务已经提交或回滚则该方法没有任何效果。 * @param {String} [jndi] 数据库jndi变量名称。为空表示使用默认使用库。 */ rollback: function(jndi, isolation) { var conn = DbUtil.getConnection(request, (jndi || null)); if (!conn.getAutoCommit()) { conn.rollback(); } }, /** * 判断当前请求对指定模块是否可以访问。 * @param {String} path 模块路径或其捷径。 * @return {Boolean} true可以访问,false不可以访问。 */ perm: function(path) { return WbUtil.canAccess(request, path); }, /** * 删除树型结构表中的指定键值的记录。当记录被删除时,其树型结构的所有子节点记录均将被删除。 * 该方法将使用指定jndi的共享数据库连接,并默认启用事务。 * @param {String} tableName 数据库表名。 * @param {String} keyName 主键ID字段名称。 * @param {String} parentKeyName 上级ID字段名称。 * @param {Array} delKeys 删除的主键值列表。 * @param {String} [extraFields] 返回的附加字段名称列表,多个字段以逗号分割。 * @param {String} [jndi] 数据库jndi名称。 * @return {JSONArray} 包括子节点在内的所有被删除节点记录值组成的数据列表。 */ delTree: function(tableName, keyName, parentKeyName, delKeys, extraFields, jndi) { var rs, delRecs, config; if (extraFields) extraFields = ',' + extraFields; else extraFields = ''; if (jndi) config = { jndi: jndi }; else config = null; rs = app.run('select ' + keyName + ',' + parentKeyName + extraFields + ' from ' + tableName, config); delRecs = Wb.reverse(Wb.travelTree(rs, keyName, parentKeyName, delKeys)); app.run('delete from ' + tableName + ' where ' + keyName + '={?' + keyName + '?}', { arrayData: delRecs }); return delRecs; }, /** * 根据当前语言种类格式化字符串。 * @param {String} format 模板字符串。 * @param {String...} values 格式化填充的字符串内容列表。 * @return {String} 格式化后的字符串。 */ format: function() { return Str.format(request, arguments[0], [].slice.call(arguments, 1)); }, /** * 根据客户端当前语言代码,获取langs中对应值组成的对象。 * @param {Object} langs 按不同语言定义的值对象。 * @return {Object} 根据客户端语言提取值后组成的对象。 */ getLang: function(langs) { var list = {}, lang = Str.getLanguage(request); Wb.each(langs, function(k, v) { list[k] = v[lang]; }); return list; }, /** * 运行SQL语句,并获取返回结果对象。 * @param {String} sql 运行的SQL语句。 * @param {Object} [config] 配置对象。 * @param {String} config.jndi 数据库连接jndi。 * @param {String} config.arrayName 执行批处理时,指定数据源来自request中存储的该变量。 * @param {JSONArray/Array/String} config.arrayData 执行批处理时,指定数据源来自该值。 * @param {Boolean} config.batchUpdate 是否允许批处理操作。 * @param {String} config.errorText 当该值不为空且查询结果集不为空,系统将抛出该信息的异常。 * @param {String} config.type 执行何种SQL操作,可为"query","update","execute","call",默认为自动。 * @param {String} config.transaction 执行何种数据库事务操作,可为"start","commit","none"。 * @param {String} config.isolation 数据库事务隔离级别,可为"readCommitted","readUncommitted","repeatableRead","serializable"。 * @param {Boolean} config.uniqueUpdate 指定插入、更改或删除记录操作是否有且只有1条。 * @return {Object} 运行SQL语句获得的结果,可能值为结果集,影响记录数或输出参数结果Map。 */ run: function(sql, config) { var arrayData, query = new com.wb.tool.Query(); if (config && config.arrayData) { arrayData = config.arrayData; if (!(arrayData instanceof JSONArray)) { if (Wb.isArray(arrayData)) arrayData = Wb.reverse(arrayData); else arrayData = new JSONArray(arrayData); config.arrayData = arrayData; } } Wb.apply(query, { request: request, sql: sql }, config); return query.run(); }, /** * 在共享的request和response或独立虚拟的response上下文中运行指定文件的xwl模块并返回生成的脚本。 * 使用该方法运行模块不验证权限,不释放模块运行过程中生成的资源,所有资源待主模块运行完成之后释放。 * @param {String} url 运行的模块url地址。 * @param {Object} [params] 请求的参数对象。 * @param {Boolean} [isInvoke] 是否为invoke模式的调用。true只返回闭包部分的脚本, * false返回全部模块脚本。如果指定该参数,将在独立虚拟的response内运行。 * @return {String} 返回的脚本。只有当指定isInvoke参数时才返回运行的脚本。 */ execute: function(url, params, isInvoke) { if (isInvoke === undefined) { if (params) WebUtil.applyAttributes(request, Wb.reverse(params)); WbUtil.run(url, request, response); } else { return WbUtil.run(url, Wb.reverse(params), request, !!isInvoke); } }, /** * 使用com.wb.tool.DataProvider直接输出数据到客户端,详见该控件说明。 * @param {ResultSet} rs 结果集。 * @param {Object} [config] 配置参数对象,见com.wb.tool.DataProvider控件的使用。 * @param {Boolean} [directOutput] 是否立即输出内容到客户端,true立即输出,false从该方法返回内容。默认为false。 * @return {String/undefined} 输出脚本或undefined。 */ dp: function(rs, config, directOutput) { var dp = new com.wb.tool.DataProvider(); Wb.apply(dp, { request: request, response: response, resultSet: rs }, config); if (directOutput) dp.output(); else return dp.getScript(); }, /** * 从数据库获取数据,并输出指定格式的脚本、图片或流数据至客户端。 * @param {String} sql sql语句。 * @param {Object} [config] 配置参数对象,见DataProvider控件的使用。 * @param {Boolean} [returnScript] 是否返回脚本,true返回生成的脚本,false直接输出,默认为false。 * @return {String/undefined} 输出脚本或undefined。 */ output: function(sql, config, returnScript) { var configText, newConfig, dp = new com.wb.controls.DpControl(); dp.request = request; dp.response = response; if (config) { newConfig = {}; Wb.each(config, function(key, value) { if (Wb.isObject(value)) value = Wb.encode(value); else value = String(value); newConfig[key] = value; }); configText = Wb.encode(newConfig); } else configText = '{}'; dp.configs = new JSONObject(configText); dp.configs.put('sql', sql); if (returnScript) return dp.getContent(false); else dp.create(); }, /** * 获取由SQL生成的数据对象。详见app.output方法的说明。 * @param {String} sql sql语句。 * @param {Object} [config] 配置参数对象,见DataProvider控件的使用。 * @return {Object} 数据对象。 */ getData: function(sql, config) { return Wb.decode(app.output(sql, config, true)); }, /** * 获取SQL生成的数据集首行所有字段名称和值组成的对象。如果首行不存在返回null。 * @param {String} sql sql语句。 * @param {Object} [config] 配置对象。详见app.run方法的config参数。 * @return {Object} 记录数据组成的对象或null。 */ getRecord: function(sql, config) { return app.getRecords(sql, config, true); }, /** * 获取SQL生成的数据集所有行所有字段值组成的数组。数组内每一项为记录数据对象。 * @param {String} sql sql语句。 * @param {Object} [config] 配置对象。详见app.run方法的config参数。config.count属性指定返回最大记录数。 * @param {Boolean} [firstRow] 是否仅获取首行记录组成的对象。默认为false。 * @return {Array} 所有记录数据组成的数组。 */ getRecords: function(sql, config, firstRow) { var rs, st; try { rs = app.run(sql, config); st = rs.getStatement(); if (firstRow) { if (rs.next()) return Wb.getRecord(rs); else return null; } else return Wb.getRecords(rs, config ? config.count : -1); } finally { DbUtil.close(rs); DbUtil.close(st); } }, /** * 执行上下文绑定的insert, update, delete数据库更新操作。 * @param {Object} config 配置参数对象,见Updater控件的使用。 */ update: function(configs) { var updater = new com.wb.tool.Updater(); if (Wb.isObject(configs.fieldsMap)) configs.fieldsMap = Wb.toJSONObject(configs.fieldsMap); Wb.apply(updater, { request: request }, configs); updater.run(); } };