springBoot之如何獲取接口請求數(shù)據(jù)和返回數(shù)據(jù)實現(xiàn)日志
更新時間:2023年04月06日 10:17:47 作者:LonesomeRoad
這篇文章主要介紹了springBoot之如何獲取接口請求數(shù)據(jù)和返回數(shù)據(jù)實現(xiàn)日志問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
一、獲取接口請求的數(shù)據(jù)
可以在Interceptor的afterCompletion中實現(xiàn)但是要重寫RequestWrapper
代碼記錄如下:
HttpServletRequestFilter
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; ? import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; ? import java.io.IOException; ? @Component @WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/") @Order(10000) public class HttpServletRequestFilter implements Filter { ? ? @Override ? ? public void init(FilterConfig filterConfig) throws ServletException { ? ? ? } ? ? ? @Override ? ? public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ? ? ? ? ServletRequest requestWrapper = null; ? ? ? ? if(servletRequest instanceof HttpServletRequest) { ? ? ? ? ? ? requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest); ? ? ? ? } ? ? ? ? //獲取請求中的流如何,將取出來的字符串,再次轉(zhuǎn)換成流,然后把它放入到新request對象中 ? ? ? ? // 在chain.doFiler方法中傳遞新的request對象 ? ? ? ? if(null == requestWrapper) { ? ? ? ? ? ? filterChain.doFilter(servletRequest, servletResponse); ? ? ? ? } else { ? ? ? ? ? ? filterChain.doFilter(requestWrapper, servletResponse); ? ? ? ? } ? ? } ? ? ? @Override ? ? public void destroy() { ? ? ? } ? }
RequestWrapper
import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*;? ? public class RequestWrapper extends HttpServletRequestWrapper { ? ? private final String body; ? ? ? public RequestWrapper(HttpServletRequest request) { ? ? ? ? super(request); ? ? ? ? StringBuilder stringBuilder = new StringBuilder(); ? ? ? ? BufferedReader bufferedReader = null; ? ? ? ? InputStream inputStream = null; ? ? ? ? try { ? ? ? ? ? ? inputStream = request.getInputStream(); ? ? ? ? ? ? if (inputStream != null) { ? ? ? ? ? ? ? ? bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); ? ? ? ? ? ? ? ? char[] charBuffer = new char[128]; ? ? ? ? ? ? ? ? int bytesRead = -1; ? ? ? ? ? ? ? ? while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { ? ? ? ? ? ? ? ? ? ? stringBuilder.append(charBuffer, 0, bytesRead); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? stringBuilder.append(""); ? ? ? ? ? ? } ? ? ? ? } catch (IOException ex) { ? ? ? ? ? } finally { ? ? ? ? ? ? if (inputStream != null) { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? inputStream.close(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? if (bufferedReader != null) { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? bufferedReader.close(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? body = stringBuilder.toString(); ? ? } ? ? ? @Override ? ? public ServletInputStream getInputStream() throws IOException { ? ? ? ? final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); ? ? ? ? ServletInputStream servletInputStream = new ServletInputStream() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean isFinished() { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean isReady() { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public void setReadListener(ReadListener readListener) { ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public int read() throws IOException { ? ? ? ? ? ? ? ? return byteArrayInputStream.read(); ? ? ? ? ? ? } ? ? ? ? }; ? ? ? ? return servletInputStream; ? ? ? } ? ? ? @Override ? ? public BufferedReader getReader() throws IOException { ? ? ? ? return new BufferedReader(new InputStreamReader(this.getInputStream())); ? ? } ? ? ? public String getBody() { ? ? ? ? return this.body; ? ? } ? }
afterCompletion
? ? @Override ? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) ? ? ? ? ? ? throws Exception { ? ? ? ? ? logger.debug("SessionInterceptor"); ? ? ? ? // 獲取地址 ? ? ? ? String url = request.getRequestURL().toString(); ? ? ? ? String requestMethod = request.getMethod(); ? ? ? ? String servletPath = request.getServletPath(); ? ? ? ? String body = new RequestWrapper(request).getBody(); ? ? ? ? String contentType = request.getContentType(); ? ? ? ? Map reqMap = new HashMap(); ? ? ? ? if(requestMethod.equals("POST")) { ? ? ? ? ? ? if(!contentType.equals("text/plain"))? ? ? ? ? ? ? ?? ?body = "body is file,don't show."; ? ? ? ? ? ? if(body.length()>1000)? ? ? ? ? ? ? ?? ?body = body.substring(0, 1000); ? ? ? ? } ? ? ? ? if(requestMethod.equals("GET")) { ? ? ? ? ? ? // 獲取請求參數(shù) ? ? ?? ??? ?Map ParameterMap = ?request.getParameterMap(); ? ? ? ? ? ? Set<Map.Entry<String,String[]>> entry = ParameterMap.entrySet(); ? ? ? ? ? ? Iterator<Map.Entry<String,String[]>> it = entry.iterator(); ? ? ? ? ? ? while (it.hasNext()){ ? ? ? ? ? ? ? ? Map.Entry<String,String[]> ?me = it.next(); ? ? ? ? ? ? ? ? String key = me.getKey(); ? ? ? ? ? ? ? ? String value = me.getValue()[0]; ? ? ? ? ? ? ? ? reqMap.put(key,value); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? logger.error("url: "+url+",requestMethod: "+requestMethod+",servletPath: "+servletPath+",body: " + body+",parameterMap: "+reqMap.toString()); ? ? ? ?? ? ? ? ?? ? ? }
二、獲取接口返回的數(shù)據(jù)
可以在filter中實現(xiàn)但是要重寫ResponseWrapper,
代碼記錄如下:
HttpServletResponseFilter
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; ? import org.apache.log4j.Logger; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; ? import java.io.IOException; ? @Component @WebFilter(filterName = "HttpServletResponseFilter", urlPatterns = "/") @Order(10000) public class HttpServletResponseFilter implements Filter { ?? ?static Logger logger = Logger.getLogger(HttpServletResponseFilter.class.getName()); ? ? @Override ? ? public void init(FilterConfig filterConfig) throws ServletException { ? ? ? } ? ? ? @Override ? ? public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ? ? ?? ?HttpServletRequest req = (HttpServletRequest) servletRequest; ? ? ? ? HttpServletResponse resp = (HttpServletResponse) servletResponse; ? ? ? ? ResponseWrapper mResp = new ResponseWrapper(resp); // 包裝響應(yīng)對象 resp 并緩存響應(yīng)數(shù)據(jù) ? ? ? ? filterChain.doFilter(req, mResp); ? ? ? ? byte[] bytes = mResp.getBytes(); // 獲取緩存的響應(yīng)數(shù)據(jù) ?? ? ? ?logger.error(new String(bytes,"utf-8")); ? ? } ? ? ? @Override ? ? public void destroy() { ? ? ? } ? }
ResponseWrapper
import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.*; ? public class ResponseWrapper extends HttpServletResponseWrapper { ? ? ? private ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ? ? private HttpServletResponse response; ? ? private PrintWriter pwrite; ? ? ? public ResponseWrapper(HttpServletResponse response) { ? ? ? ? super(response); ? ? ? ? this.response = response; ? ? } ? ? ? @Override ? ? public ServletOutputStream getOutputStream() throws IOException { ? ? ? ? return new MyServletOutputStream(bytes); // 將數(shù)據(jù)寫到 byte 中 ? ? } ? ? ? /** ? ? ?* 重寫父類的 getWriter() 方法,將響應(yīng)數(shù)據(jù)緩存在 PrintWriter 中 ? ? ?*/ ? ? @Override ? ? public PrintWriter getWriter() throws IOException { ? ? ? ? try{ ? ? ? ? ? ? pwrite = new PrintWriter(new OutputStreamWriter(bytes, "utf-8")); ? ? ? ? } catch(UnsupportedEncodingException e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? ? ? return pwrite; ? ? } ? ? ? /** ? ? ?* 獲取緩存在 PrintWriter 中的響應(yīng)數(shù)據(jù) ? ? ?* @return ? ? ?*/ ? ? public byte[] getBytes() { ? ? ? ? if(null != pwrite) { ? ? ? ? ? ? pwrite.close(); ? ? ? ? ? ? return bytes.toByteArray(); ? ? ? ? } ? ? ? ? ? if(null != bytes) { ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? bytes.flush(); ? ? ? ? ? ? } catch(IOException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return bytes.toByteArray(); ? ? } ? ? ? class MyServletOutputStream extends ServletOutputStream { ? ? ? ? private ByteArrayOutputStream ostream ; ? ? ? ? ? public MyServletOutputStream(ByteArrayOutputStream ostream) { ? ? ? ? ? ? this.ostream = ostream; ? ? ? ? } ? ? ? ? ? @Override ? ? ? ? public void write(int b) throws IOException { ? ? ? ? ? ? ostream.write(b); // 將數(shù)據(jù)寫到 stream 中 ? ? ? ? } ? ?? ??? ?@Override ?? ??? ?public boolean isReady() { ?? ??? ??? ?// TODO Auto-generated method stub ?? ??? ??? ?return false; ?? ??? ?} ? ?? ??? ?@Override ?? ??? ?public void setWriteListener(WriteListener listener) { ?? ??? ??? ?// TODO Auto-generated method stub ?? ??? ??? ? ?? ??? ?} ? ? ? } ? }
總結(jié)
本文參考了許多網(wǎng)上前輩們的踩坑歷程,在此就不列舉了,只做一記錄
希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于SpringMVC的數(shù)據(jù)綁定@InitBinder注解的使用
這篇文章主要介紹了關(guān)于SpringMVC的數(shù)據(jù)綁定@InitBinder注解的使用,在SpringMVC中,數(shù)據(jù)綁定的工作是由 DataBinder 類完成的,DataBinder可以將HTTP請求中的數(shù)據(jù)綁定到Java對象中,需要的朋友可以參考下2023-07-07Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信)
這篇文章主要介紹了Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10