入站集成场景下能否重置StreamWriter已写入的数据
问题解答
首先明确:你无法直接擦除已经通过writeString()写入StreamWriter的内容。因为ServiceNow的StreamWriter是面向流式输出的实现,数据写入后会直接进入输出缓冲区,官方没有提供清空已有流内容的接口,你原来的写法会导致正常写入的半截内容和错误信息拼接在一起,返回非法JSON。
推荐解决方法
方案1:内存预构建响应(适配绝大多数场景)
先把所有响应数据在内存中组装完成,确认没有异常后再一次性写入流,从根源上避免半截内容写入流的问题。
修改后的代码示例:
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) { var body = request.body.data; /* 处理请求数据 */ try { // 先在内存里组装响应数据 var resultArr = []; var inc = new GlideRecord('incident'); inc.query(); while(inc.next()){ var obj = {}; obj.id = inc.getValue('number'); obj.sys_id = inc.getUniqueValue(); resultArr.push(obj); } // 组装完成后再写入流 var writer = response.getStreamWriter(); response.setContentType('application/json'); response.setStatus(200); writer.writeString(JSON.stringify({results: resultArr})); } catch (ex) { // 异常时直接写入错误内容,没有之前的半截数据干扰 var writer = response.getStreamWriter(); response.setContentType('application/json'); response.setStatus(500); writer.writeString(JSON.stringify({error: "Something went wrong"})); } })(request, response);
方案2:大结果集场景处理
如果你需要返回超大规模的结果集,全量放内存会导致性能损耗,可以在捕获异常时调用response.reset()方法清空整个响应的所有配置和已写入缓冲区内容,再重新输出错误响应:
catch (ex) { // 清空所有已设置的响应头、状态码、已写入的流内容 response.reset(); // 重新配置响应并写入错误信息 response.setContentType('application/json'); response.setStatus(500); var writer = response.getStreamWriter(); writer.writeString(JSON.stringify({error: "Something went wrong"})); }
注意:response.reset()会清空所有之前对响应做的配置,调用后需要重新设置所有响应参数。
内容的提问来源于stack exchange,提问作者asprin
相关产品推荐
相关产品推荐

