有时候需要记录打印出服务的请求接口及请求体, 响应接口及返回体,可以使用以下方法文章来源地址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();
}
}
}
}
文章来源:https://www.toymoban.com/news/detail-545805.html
到了这里,关于JAVA 打印Http请求及响应的消息体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!