Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring MVC-获取HttpServletResponse主体_Java_Spring Mvc_Servlets - Fatal编程技术网

Java Spring MVC-获取HttpServletResponse主体

Java Spring MVC-获取HttpServletResponse主体,java,spring-mvc,servlets,Java,Spring Mvc,Servlets,由于两天后我仍然无法确定如何在HandlerInterceptorAdapter中打印HttpServletResponse正文,因此我将另问一次:) 使用HttpServletRequest我可以轻松地执行类似request.getReader().lines().collect(Collectors.joining(System.lineSeparator())和我有完整的正文,但是如何使用HttpServletResponse实现相同的内容呢 我在StackOverflow上发现了很多关于

由于两天后我仍然无法确定如何在
HandlerInterceptorAdapter
中打印
HttpServletResponse
正文,因此我将另问一次:)

使用
HttpServletRequest
我可以轻松地执行类似
request.getReader().lines().collect(Collectors.joining(System.lineSeparator())
和我有完整的正文,但是如何使用
HttpServletResponse
实现相同的内容呢

我在StackOverflow上发现了很多关于这方面的问题,但它们似乎都不起作用

这是处理程序:

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    //how to print here the "response" by using the "response" parameter
    super.afterCompletion(request, response, handler, ex);
}
答案和链接完全相同,但它们使用
ServletResponse
而不是
HttpServletResponse
以及
FilterChain
的内容,而我的
afterCompletion
处理程序中没有这些内容。即使是看起来最完整的一个也不适合(我认为)我的情况

有人能给我提供一个带有
HttpServletResponse
的简单序列化示例吗?

简单的答案是“在处理程序拦截器中不能这样做”。 :

HandlerInterceptor基本上类似于Servlet过滤器,但与后者不同的是,它只允许自定义预处理,并可以选择禁止执行处理程序本身,以及自定义后处理过滤器功能更强大,例如,它们允许交换传递给链的请求和响应对象。注意,过滤器是在web.xml中配置的,web.xml是应用程序上下文中的HandlerInterceptor

作为一项基本指导原则,与细粒度处理程序相关的预处理任务是HandlerInterceptor实现的候选任务,特别是考虑了常见处理程序代码和授权检查。另一方面,筛选器非常适合于请求内容和视图内容处理,如多部分表单和GZIP压缩。这通常显示何时需要将筛选器映射到某些内容类型(例如图像)或所有请求


因此,我建议您查看基于过滤器的解决方案,正如您所指出的。您可能会感兴趣:它似乎可以用最少的编码实现您想要的。但是,一旦你开始使用过滤器,你在问题中链接到的任何公认答案都可能会起到作用。

深入搜索它很困难,但发现
ResponseBodyAdvice
可能适合我的目的。因此,在StackOverflow上寻找一些例子,发现guy也有同样的问题,必须操作
对象体

这是我最后的工作解决方案,以实现我写的

@ControllerAdvice
公共类CSRFHandler实现ResponseBodyAdvice{
@值(${security.csrf.enabled}”)
私有字符串csrfEnabled;
@值(${security.csrf.headerName}”)
私有字符串csrfHeaderName;
@值(${security.csrf.salt}”)
私盐;
@凌驾
公共布尔支持(MethodParameter returnType,Class>converterType){
返回true;
}
@凌驾
BodyWrite之前的公共对象(对象主体、方法参数returnType、MediaType selectedContentType、,
Class>selectedConverterType,ServerHttpRequest请求,
服务器HttpResponse(响应){
if(新布尔值(csrfEnabled).booleanValue()){
String csrfValue=SecureUtil.buildCsrfValue(salt,StringUtil.toJson(body));
response.getHeaders().add(csrfHeaderName,csrfValue);
}
返回体;
}
}

在科特林,我的结局如下:

@Bean
open fun logFilter(): CommonsRequestLoggingFilter {
    val filter = InfoRequestLoggingFilter()
    filter.setIncludeQueryString(true)
    filter.setIncludePayload(true)
    filter.setMaxPayloadLength(10000)
    filter.isIncludeHeaders = false
    return filter
}

嗨Faraz Durrani谢谢你的回复。我正在寻找如何打印身体的反应,而不是要求。你好GPI谢谢你的有用的答案。很明显,为什么这不是一个好方法,但是尝试一下eperrequestfilter或Filter,似乎在控制器执行后没有调用dofilternental或doFilter。我应该用什么来代替呢?我猜如果你的过滤器的方法没有被调用,那可能是因为Spring没有把它们取出来并部署它们。因此,您可能应该阅读手册,了解“如何注册过滤器”。如果您使用纯SpringBoot应用程序,而不是嵌入Spring上下文的Servlet Web应用程序,那么这样做的方式就不同了。。。因此,请阅读相关文档。
@Bean
open fun logFilter(): CommonsRequestLoggingFilter {
    val filter = InfoRequestLoggingFilter()
    filter.setIncludeQueryString(true)
    filter.setIncludePayload(true)
    filter.setMaxPayloadLength(10000)
    filter.isIncludeHeaders = false
    return filter
}
import org.apache.commons.io.output.TeeOutputStream
import org.springframework.mock.web.DelegatingServletOutputStream
import org.springframework.web.filter.CommonsRequestLoggingFilter
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.PrintStream
import java.io.PrintWriter
import javax.servlet.FilterChain
import javax.servlet.ServletOutputStream
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletResponseWrapper

class InfoRequestLoggingFilter : CommonsRequestLoggingFilter() {

    override fun beforeRequest(request: HttpServletRequest, message: String) {
        logger.info(message)
    }

    override fun afterRequest(request: HttpServletRequest, message: String) {
        // logger.info(message) - NOP, since doFilterInternal is logging it instead
    }

    override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {

        val outputStream = ByteArrayOutputStream()
        val printStream = PrintStream(outputStream)

        filterChain.doFilter(request, object : HttpServletResponseWrapper(response) {
            @Throws(IOException::class)
            override fun getOutputStream(): ServletOutputStream {
                return DelegatingServletOutputStream(TeeOutputStream(super.getOutputStream(), printStream)
                )
            }

            @Throws(IOException::class)
            override fun getWriter(): PrintWriter {
                return PrintWriter(DelegatingServletOutputStream(TeeOutputStream(super.getOutputStream(), printStream))
                )
            }
        })

        logger.info(String.format("%s ;status=%s ;payload=%s", createMessage(request, "", ""), response.status, outputStream.toString()))
    }
}