JAVA 打印Http请求及响应的消息体

这篇具有很好参考价值的文章主要介绍了JAVA 打印Http请求及响应的消息体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有时候需要记录打印出服务的请求接口及请求体, 响应接口及返回体,可以使用以下方法文章来源地址https://www.toymoban.com/news/detail-545805.html

package com.zhengqing.config.security.filter;


import com.zhengqing.config.Constants;
import com.zhengqing.config.security.dto.SecurityUser;
import com.zhengqing.config.security.log.MultiReadHttpServletResponse;
import com.zhengqing.config.security.service.impl.UserDetailsServiceImpl;
import com.zhengqing.modules.common.utils.MultiReadHttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.filter.OncePerRequestFilter;


/**
 * @author hj
 */
@Slf4j
@Component
public class DemoFilter implements Filter {

    private String logRequestBody(MultiReadHttpServletRequest request) {
        MultiReadHttpServletRequest wrapper = request;
        if (wrapper != null) {
            try {
                String bodyJson = wrapper.getBodyJsonStrByJson(request);
                String url = wrapper.getRequestURI().replace("//", "/");
                System.out.println("-------------------------------- 请求url: " + url + " --------------------------------");
                Constants.URL_MAPPING_MAP.put(url, url);
                log.info("`{}` 接收到的参数: {}",url , bodyJson);
                return bodyJson;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private void logResponseBody(MultiReadHttpServletRequest request, MultiReadHttpServletResponse response, long useTime) {
        MultiReadHttpServletResponse wrapper = response;
        if (wrapper != null) {
            byte[] buf = wrapper.getBody();
            if (buf.length > 0) {
                String payload;
                try {
                    payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
                } catch (UnsupportedEncodingException ex) {
                    payload = "[unknown]";
                }
                log.info("`{}`  耗时:{}ms  返回的参数: {}", Constants.URL_MAPPING_MAP.get(request.getRequestURI()), useTime, payload);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        long endTime = 0;
        HttpServletRequest req =(HttpServletRequest)servletRequest;
        HttpServletResponse resp =(HttpServletResponse)servletResponse;
        MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(req);
        MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(resp);
        try{

            // 记录请求的消息体
            logRequestBody(wrappedRequest);
            endTime = System.currentTimeMillis();
            filterChain.doFilter(req, resp);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 记录响应的消息体
            logResponseBody(wrappedRequest, wrappedResponse, endTime - startTime);
        }


    }
}

package com.zhengqing.modules.common.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * <p> 多次读写BODY用HTTP REQUEST - 解决流只能读一次问题 </p>
 *
 * @author : zhengqing
 * @description :
 * @date : 2019/10/12 15:42
 */
@Slf4j
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {

    private final byte[] body;

    public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        body = getBodyString(request).getBytes(Charset.forName("UTF-8"));
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    private String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

    /**
     * 将前端请求的表单数据转换成json字符串 - 前后端一体的情况下使用
     * @param request:
     * @return: java.lang.String
     */
    public String getBodyJsonStrByForm(ServletRequest request){
        Map<String, Object> bodyMap = new HashMap<>(16);
        try {
            // 参数定义
            String paraName = null;
            // 获取请求参数并转换
            Enumeration<String> e = request.getParameterNames();
            while (e.hasMoreElements()) {
                paraName = e.nextElement();
                bodyMap.put(paraName, request.getParameter(paraName));
            }
        } catch(Exception e) {
            log.error("请求参数转换错误!",e);
        }
        // json对象转json字符串 转javabean
//        SecurityUser user = JSONObject.parseObject(JSONObject.toJSONString(bodyMap), SecurityUser.class);
        // json对象转json字符串
        return JSONObject.toJSONString(bodyMap);
    }

    /**
     * 将前端传递的json数据转换成json字符串 - 前后端分离的情况下使用
     * @param request:
     * @return: java.lang.String
     */
    public String getBodyJsonStrByJson(ServletRequest request){
//        StringBuilder requestStrBuilder = new StringBuilder();
//        try {
//            BufferedReader streamReader = new MultiReadHttpServletRequest(request).getReader();
//            String inputStr;
//            while ((inputStr = streamReader.readLine()) != null) {
//                requestStrBuilder.append(inputStr);
//            }
//            // 将json字符串转化为jsonbean对象
            User user = JSON.parseObject(requestStrBuilder.toString(), User.class);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return requestStrBuilder.toString();
        StringBuffer json = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            while((line = reader.readLine()) != null) {
                json.append(line);
            }
        }
        catch(Exception e) {
            log.error("请求参数转换错误!",e);
        }
        return json.toString();
    }

}

package com.zhengqing.config.security.log;

import lombok.AllArgsConstructor;
import lombok.Data;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

/**
 * <p> 多次读写BODY用HTTP RESPONSE - 解决流只能读一次问题 </p>
 *
 * @author : zhengqing
 * @description :
 * @date : 2019/10/12 15:42
 */
public class MultiReadHttpServletResponse extends HttpServletResponseWrapper {

    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    private HttpServletResponse response;

    public MultiReadHttpServletResponse(HttpServletResponse response) {
        super(response);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        this.response = response;
    }

    public byte[] getBody() {
        return byteArrayOutputStream.toByteArray();
    }

    @Override
    public ServletOutputStream getOutputStream() {
        return new ServletOutputStreamWrapper(this.byteArrayOutputStream, this.response);
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(new OutputStreamWriter(getOutputStream(), this.response.getCharacterEncoding()));
    }


    @Data
    @AllArgsConstructor
    private static class ServletOutputStreamWrapper extends ServletOutputStream {

        private ByteArrayOutputStream outputStream;
        private HttpServletResponse response;

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setWriteListener(WriteListener listener) {

        }

        @Override
        public void write(int b) throws IOException {
            this.outputStream.write(b);
        }

        @Override
        public void flush() throws IOException {
            if (!this.response.isCommitted()) {
                byte[] body = this.outputStream.toByteArray();
                ServletOutputStream outputStream = this.response.getOutputStream();
                outputStream.write(body);
                outputStream.flush();
            }
        }
    }
}

到了这里,关于JAVA 打印Http请求及响应的消息体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • http 请求报文响应报文的格式以及Token cookie session 区别

    HTTP 请求报文和响应报文的格式如下: HTTP 请求报文格式: 方法 : 请求方法,例如 GET、POST、PUT、DELETE 等。 路径 : 请求的路径,表示需要访问的资源。 协议版本 : 使用的协议版本,通常是 HTTP/1.1 或 HTTP/2。 请求头部字段:包含了关于请求的附加信息,每个字段由字段名和对

    2024年02月16日
    浏览(52)
  • HTTP 和 HTTPS(请求响应报文格式 + 请求方法 + 响应状态码 + HTTPS 加密流程 + Cookie 和 Session)

    HTTP 全称 “ 超文本传输协议 ”,是一种基于传输层 TCP 协议实现的应用非常广泛的 应用层协议 我们平时打开一个网站,就是通过 HTTP 协议来传输数据的 当我们在浏览器中访问一个 “ 网址 ”(URL),浏览器就会给这个 URL 的服务器发送一个 HTTP 请求,服务器返回一个 HTTP 响

    2023年04月19日
    浏览(42)
  • Java http 响应式请求和非响应式请求有什么区别

    以下是一个使用Spring WebFlux实现真正的流式编程的案例: 运行Spring Boot应用程序,并使用浏览器或类似cURL的工具发送GET请求: 获取所有用户的请求:http://localhost:8080/users/stream 你将会看到一个持续不断的流式响应,每秒钟返回一个用户对象。这个案例中,我们使用了 @GetMapp

    2024年01月17日
    浏览(61)
  • Java课题笔记~ HTTP协议(请求和响应)

    Servlet最主要的作用就是处理客户端请求,并向客户端做出响应。为此,针对Servlet的每次请求,Web服务器在调用service()方法之前,都会创建两个对象 分别是HttpServletRequest和HttpServletResponse。 其中HttpServletRequest用于封装HTTP请求消息,简称request对象; HttpServletResponse用于封装HTT

    2024年02月13日
    浏览(35)
  • 【HTTP】URL结构、HTTP请求和响应的报文格式、HTTP请求的方法、常见的状态码、GET和POST有什么区别、Cookie、Session等重点知识汇总

    目录 URL格式 HTTP请求和响应报文的字段? HTTP请求方法 常见的状态码 GET 和 POST 的区别 Cookie 和 Session ? :是用来分割URL的主体部分(通常是路径)和查询字符串(query string)查询字符串是一组键值对的参数 query string :是键值对的结构,分割键值对,=分割键和值 Content-Type

    2024年02月07日
    浏览(48)
  • HTTP介绍 原理 消息结构 客户端请求 服务器响应 HTTP状态码

    HTTP协议 是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(www.world wide web)服务器传输超文本到本地浏览器的传送协议 HTTP 是基于TCP/IP(三次握手,四次挥手)通信协议来传输数据(HTML文件,图片文件,查询结果等) TCP:可靠的,丢包重传 UTP:不可靠的,直播,

    2024年02月05日
    浏览(52)
  • nginx脚本,Nginx变量截取字符串,拼接字符串,nginx打印日志,添加修改HTTP请求头,添加修改HTTP响应头

    nginx变量命名,以$开头。 打印日志的目的,是想知道某个变量的值是多少,通过add_header设置响应头,间接地打印日志。 通过设置响应头,然后在浏览器上请求nginx地址,然后得到的响应头,就知道变量值是多少了。 这个需要注意一下,特别是正则 ~   ,后面截取字符串需要

    2024年02月12日
    浏览(72)
  • Http---HTTP响应报文

    1. HTTP响应报文分析 HTTP 响应报文效果图: 响应报文说明: 原始响应报文说明: 说明: 每项数据之间使用: rn 2. HTTP 状态码介绍 HTTP 状态码是 用于表示web服务器响应状态的3位数字代码 。 状态码 说明 200 请求成功 307 重定向 400 错误的请求,请求地址或者参数有误 404 请求资源在服

    2024年03月10日
    浏览(48)
  • WebServer 解析HTTP 响应报文

    一、基础API部分,介绍stat、mmap、iovec、writev、va_list 1.1 stat​  作用 :获取文件信息 返回值:成功返回0,失败返回-1; 参数:文件路径(名),struct stat 类型的结构体  struct stat 结构体详解: stat结构体中的st_mode 则定义了下列数种情况: 1.2 mmap 用于将一个文件或其他对象

    2024年02月09日
    浏览(42)
  • HTTP/1.1协议中的响应报文

    2023年8月30日,周三下午 目录 概述 响应报文示例 详述 HTTP/1.1协议的响应报文由以下几个部分组成: 状态行(Status Line) 响应头部(Response Headers) 空行(Blank Line) 响应体(Response Body) 需要注意的是,响应头部是可选的,而状态行和空行是必需的。 在这个示例中, 状态行

    2024年02月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包