SoapUI Mock Service中reader.readLine()首次请求后返回null问题
SoapUI Mock Service 请求体重复读取返回null的解决方法
问题根源
你遇到的问题是因为Servlet 请求输入流是一次性消费的:首次调用request.getReader()或request.getInputStream()读取流后,流的指针会移动到末尾,后续再读取就会返回null。哪怕更换LineNumberReader为BufferedReader,或者改用read(char[])方法,只要流已经被消费,就无法再读取到内容。另外,SoapUI 的MockRequest内部可能已经提前读取过请求流,导致自定义的setData方法无法再次获取内容。
解决方案
方案1:直接使用SoapUI内置API获取请求体
SoapUI 提供了MockRequest.getRequestContent()方法,已经封装了请求体的读取和缓存,无需手动操作输入流。直接替换你的setData方法即可:
修改后的完整代码:
def requestMethod = mockRequest.getMethod() log.info "mockRequest.method: " + requestMethod if (requestMethod.toString() != "GET") { log.info "dispatch:Status 405" return "405 - Method Not Allowed" } def acceptEncodingHeaderList = mockRequest.getRequestHeaders().get("Accept-Encoding") log.info "AcceptEncoding Header List: " + acceptEncodingHeaderList if (!acceptEncodingHeaderList.contains("gzip, deflate, br")) { log.info "dispatch:Status 406" return "406 - Not Acceptable" } // 直接使用内置API获取请求体 def data = mockRequest.getRequestContent() log.info "data:" + data if (!data.contains("bscs")) { log.info "dispatch:Status 400" return "400 - Bad Request" } log.info "dispatch:ok " return "200 - OK"
方案2:手动缓存请求体(如果需要自定义读取逻辑)
如果必须保留自定义的读取逻辑,可在首次读取后将请求体缓存到MockRequest的属性中,后续直接取用缓存内容:
def requestMethod = mockRequest.getMethod() log.info "mockRequest.method: " + requestMethod if (requestMethod.toString() != "GET") { log.info "dispatch:Status 405" return "405 - Method Not Allowed" } def acceptEncodingHeaderList = mockRequest.getRequestHeaders().get("Accept-Encoding") log.info "AcceptEncoding Header List: " + acceptEncodingHeaderList if (!acceptEncodingHeaderList.contains("gzip, deflate, br")) { log.info "dispatch:Status 406" return "406 - Not Acceptable" } def data = setData() log.info "data:" + data if (!data.contains("bscs")) { log.info "dispatch:Status 400" return "400 - Bad Request" } log.info "dispatch:ok " return "200 - OK" def setData() { // 检查是否已有缓存的请求体 def cachedBody = mockRequest.getProperty("REQUEST_BODY") if (cachedBody) { return cachedBody } def request = mockRequest.getHttpRequest() def buffer = new StringWriter() def inputStream = request.getInputStream() def byteBuffer = new byte[1024] int bytesRead // 读取输入流内容 while ((bytesRead = inputStream.read(byteBuffer)) != -1) { buffer.write(byteBuffer, 0, bytesRead) } def data = buffer.toString() // 缓存到MockRequest属性中 mockRequest.setProperty("REQUEST_BODY", data) return data }
注意事项
- 避免重复调用
request.getReader()或request.getInputStream(),这两个方法会返回同一个流对象,读取后无法重置。 - 优先使用SoapUI提供的内置API,这类方法已经处理了流的复用和缓存问题,更稳定可靠。
内容的提问来源于stack exchange,提问作者Luiz Henrique Oliveira
相关产品推荐
相关产品推荐

