kotlin使用spring mvc(三)

Filter中读取输入流

在很多场景中,我们需要读取接口调用方的原始报文,以方便出现问题的时候进行对质、修复,但是在spring mvc中的输入流只允许读取一次,在Filter中读取之后action中就无法就行绑定了,如下面的代码

if(request != null){
            //读取原始报文
            val originText = request.inputStream.bufferedReader().readText()
            println(originText)
            chain?.doFilter(request,response)
        }

这样在模型绑定的时候直接抛出

Required request body is missing

按照常理上思维,输入流读取到最后,我重置不就行了吗,事实上尝试之后发现不可行,spring mvc根本没有实现,那我们只能自己造轮子了

class ResettableStreamHttpServletRequest(val request: HttpServletRequest) : HttpServletRequestWrapper(request) {
   //把输入流缓存到字节数组
    private val rawData: ByteArray = IOUtils.toByteArray(this.request.inputStream)
	//可重置的输入流对象
    private val servletStream: ResettableServletInputStream

    init {
	     //初始化的时候就把缓存的字节数组读到流中
        servletStream = ResettableServletInputStream(ByteArrayInputStream(rawData))
    }

    internal fun resetInputStream() {
	    //重置的时候,重新构造一个输入流对象
        servletStream.stream = ByteArrayInputStream(rawData)
    }

    override fun getInputStream(): ServletInputStream {
        return servletStream
    }

    override fun getReader(): BufferedReader {
        val encoding = characterEncoding
        return if (encoding != null) {
            BufferedReader(InputStreamReader(servletStream, encoding))
        } else {
            BufferedReader(InputStreamReader(servletStream))
        }
    }


}
//必须定义一个ServletInputStream,它没有提供公开的构造方法
 class ResettableServletInputStream(var stream: InputStream) : ServletInputStream() {
    override fun isReady(): Boolean {
        return true
    }

    override fun isFinished(): Boolean {
        return false
    }

    override fun setReadListener(listener: ReadListener?) {

    }
    override fun read(): Int {
        return stream.read()
    }
}

在Filter中使用ResettableStreamHttpServletRequest

        val resettableStreamHttpServletRequest = ResettableStreamHttpServletRequest(request = request as HttpServletRequest)
        //读取原始报文
        val orginText = resettableStreamHttpServletRequest.inputStream.bufferedReader().readText()
        println(orginText)
        resettableStreamHttpServletRequest.resetInputStream()

        chain?.doFilter(resettableStreamHttpServletRequest,response)

转载于:https://my.oschina.net/weidedong/blog/2249400

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值