somoly.tistory.com
article thumbnail

Json 통신 request 및 response 패킷 로깅을 위한 필터를 작성해 보았습니다.

<code />
@Slf4j public class HttpLoggingFilter extends OncePerRequestFilter implements Filter { private static final List<MediaType> VISIBLE_TYPES = Arrays.asList( MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8, ); @Data private static class HttpLogData { private String method; private String uri; private Map<String, Collection<String>> headers = new HashMap<>(); private String rawBody; private Integer status; } @SuppressWarnings("NullableProblems") @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (isAsyncDispatch(request)) { filterChain.doFilter(request, response); } else { doFilterWrapped(wrapRequest(request), wrapResponse(response), filterChain); } } private void doFilterWrapped(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, FilterChain filterChain) throws ServletException, IOException { try { filterChain.doFilter(request, response); } finally { if (log.isInfoEnabled()) { HttpLogData req = getRequest(request); HttpLogData res = getResponse(request, response); log.info("{}", req); log.info("{}", res); } response.copyBodyToResponse(); } } private HttpLogData getHttpInfo(ContentCachingRequestWrapper request) { var data = new HttpLogData(); data.method = request.getMethod(); String queryString = request.getQueryString(); if (queryString == null) { data.uri = request.getRequestURI(); } else { data.uri = request.getRequestURI() + "?" + queryString; } return data; } private HttpLogData getRequest(ContentCachingRequestWrapper request) { HttpLogData data = getHttpInfo(request); Collections.list(request.getHeaderNames()).forEach(headerName -> data.headers.put(headerName, Collections.list(request.getHeaders(headerName)))); byte[] content = request.getContentAsByteArray(); if (content.length > 0) { data.rawBody = getContentString(content, request.getContentType(), request.getCharacterEncoding()); } return data; } private HttpLogData getResponse(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) { HttpLogData data = getHttpInfo(request); data.status = response.getStatus(); response.getHeaderNames().forEach(headerName -> data.headers.put(headerName, response.getHeaders(headerName))); byte[] content = response.getContentAsByteArray(); if (content.length > 0) { data.rawBody = getContentString(content, response.getContentType(), response.getCharacterEncoding()); } return data; } private String getContentString(byte[] content, String contentType, String contentEncoding) { var mediaType = MediaType.valueOf(contentType); boolean visible = VISIBLE_TYPES.stream().anyMatch(visibleType -> visibleType.includes(mediaType)); if (visible) { try { var contentString = new String(content, contentEncoding); if (!contentString.isBlank()) { try { var jsonObject = new JSONObject(contentString); return jsonObject.toString(); } catch (JSONException e) { } } return contentString; } catch (UnsupportedEncodingException e) { return ""; } } else { return ""; } } private ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) { if (request instanceof ContentCachingRequestWrapper) { return (ContentCachingRequestWrapper) request; } else { return new ContentCachingRequestWrapper(request); } } private ContentCachingResponseWrapper wrapResponse(HttpServletResponse response) { if (response instanceof ContentCachingResponseWrapper) { return (ContentCachingResponseWrapper) response; } else { return new ContentCachingResponseWrapper(response); } } }

 

디펜던시 추가

<code />
<!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- json --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> </dependency>

 

필터 설정 추가

<code />
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean<HttpLoggingFilter> httpLoggingFilter() { var registration = new FilterRegistrationBean<HttpLoggingFilter>(); registration.setFilter(new HttpLoggingFilter()); registration.addUrlPatterns("/api/*"); // 필터를 적용할 Url 패턴 registration.setName("httpLoggingFilter"); registration.setOrder(1); return registration; } }

 

'SpringBoot' 카테고리의 다른 글

Spring 6 의 HTTP Interface  (0) 2023.03.14
Retrying Feign Calls  (0) 2023.03.14
RedisTemplate 과 Json Serializer 설정  (0) 2019.07.09
MongoDB _class 필드 제거하기  (0) 2019.07.09
404 NoHandlerFoundException 설정  (1) 2019.07.04
profile

somoly.tistory.com

@RxCats

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!