当前位置: 首页 > news >正文

要解析做邮箱以及网站电商详情页模板免费套用

要解析做邮箱以及网站,电商详情页模板免费套用,建wap手机网站,上海网站建设制Spring MVC HandlerInterceptor 拦截请求及响应体 使用Spring MVC HandlerInterceptor拦截请求和响应体的实现方案。 通过自定义LoggingInterceptor在preHandle、postHandle和afterCompletion方法中记录请求信息,并利用RequestBodyCachingFilter缓存请求体以便多次…

Spring MVC HandlerInterceptor 拦截请求及响应体

使用Spring MVC HandlerInterceptor拦截请求和响应体的实现方案。
通过自定义LoggingInterceptorpreHandlepostHandleafterCompletion方法中记录请求信息,并利用RequestBodyCachingFilter缓存请求体以便多次读取。

具体步骤:

  1. 使用InterceptorRequest对象存储请求信息;
  2. 通过Filter实现请求体缓存;
  3. 使用RequestWrapper处理一次性读取的InputStream问题。

该方案适用于需要记录完整请求/响应信息的应用场景。

  • 前期想法
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {// create a InterceptorRequest object to store request info@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// save request header, request body into InterceptorRequest// set InterceptorRequest into request attribute, eg "InterceptorRequest"log.info("preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// get InterceptorRequest from request attribute "InterceptorRequest"// update response body, response code into InterceptorRequest// save into persistence systemif (null == ex) {log.info("afterCompletion");} else {            log.error("afterCompletion -ex - {}", ex.getMessage());}}
}
  • 将请求结果一次性塞入持久层
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {// create a InterceptorRequest object to store request info// ...// update code as below@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// get InterceptorRequest from request attribute "InterceptorRequest"// update response body, response code into InterceptorRequest// save into persistence system}
}
  • 使用 Filter 拦截获取Request Body,获取请求体
@Slf4j
public class HttpRequestContext {public static String getRequestBody(ServletRequest request) {StringBuilder builder = new StringBuilder();try (InputStream inputStream = request.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {String line;while ((null != (line = reader.readLine()))) {builder.append(line);}} catch (IOException e) {log.warn("Error reading request body", e);throw new RuntimeException(e);}return builder.toString();}
}
/*** It is a filter class used to cache request bodies, commonly employed in web applications,* especially when handling POST or PUT requests. Since the input stream (InputStream) of an **HTTP request*** can only be read once, it is necessary to cache the request body in scenarios where the content* of the request body needs to be accessed multiple times (such as logging, verification, filtering, etc.).*/
@Slf4j
public class RequestBodyCachingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {String requestId = request.getAttribute("requestId")if (null == requestId) {requestId  = UUID.randomUUID().toString().replaceAll("-", "");}MDC.put("requestId", requestId);ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);try {// Wrap the request to cache the request bodyServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request);chain.doFilter(requestWrapper, responseWrapper);} finally {responseWrapper.copyBodyToResponse();MDC.remove("requestId");}}@Getterstatic class RequestWrapper extends ContentCachingRequestWrapper {private final String requestBody;public RequestWrapper(HttpServletRequest request) {super(request);requestBody = HttpRequestContext.getRequestBody(request);}@Overridepublic ServletInputStream getInputStream() throws IOException {// Return a ServletInputStream that reads from the cached request bodyfinal ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());return new ServletInputStream() {@Overridepublic int read() throws IOException {return byteArrayInputStream.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener listener) {}};}}
}

需要将自定义的Filter注册到FilterRegistrationBean

    @Beanpublic FilterRegistrationBean<RequestBodyCachingFilter> requestBodyCachingFilter() {FilterRegistrationBean<RequestBodyCachingFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new RequestBodyCachingFilter());registration.addUrlPatterns("/*");registration.setOrder(1);return registration;}
  • 统一接口封装响应实体
@Getter
@Setter
public class ApiObj<T> {private  String code;private  String message;private  T data;public ApiObj(String code, String message, T data) {this.code = code;this.data = data;this.message = message;}public static <T> ApiObj<T> success(T data) {return new ApiObj<>("200", "success", data);}public static <T> ApiObj<T> failure(String code, String message) {return new ApiObj<>(code, message, null);}
}

封装异常返回。这样返回结果可以与对外接口提供的数据一致。
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class GlobalException {static final ObjectMapper objectMapper = new ObjectMapper();@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<ApiObj<String>> handleValidationExceptions(MethodArgumentNotValidException ex) throws JsonProcessingException {log.error("handleValidationExceptions - {}", ex.getMessage());Map<String, String> errors = new HashMap<>();ex.getBindingResult().getAllErrors().forEach((error) -> {String fieldName = ((FieldError) error).getField();String errorMessage = error.getDefaultMessage();errors.put(fieldName, errorMessage);});String message = objectMapper.writeValueAsString(errors);return new ResponseEntity<>(ApiObj.failure(String.valueOf(HttpStatus.BAD_REQUEST.value()), message), HttpStatus.BAD_REQUEST);}@ExceptionHandler(value = Exception.class)public ResponseEntity<ApiObj<String>> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {log.error("defaultErrorHandler - {}", e.getMessage());Map<String, String> map = Map.of("k1", "k2");String message = objectMapper.writeValueAsString(map);return new ResponseEntity<>(ApiObj.failure(String.valueOf(HttpStatus.BAD_REQUEST.value()), message), HttpStatus.BAD_REQUEST);}@ExceptionHandler(value = IOException.class)public ResponseEntity<ApiObj<String>> defaultIOException(HttpServletRequest req, IOException e) throws Exception {log.error("defaultIOException - {}", e.getMessage());Map<String, String> map = Map.of("k3", "k4");String message = objectMapper.writeValueAsString(map);return new ResponseEntity<>(ApiObj.failure(String.valueOf(HttpStatus.BAD_REQUEST.value()), message), HttpStatus.BAD_REQUEST);}
}

= 完整更新 LoggingInterceptor

@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {final static String INTERNAL_REQUEST_BODY = "INTERNAL_REQUEST_BODY";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// save request header, request body into InterceptorRequest// set InterceptorRequest into request attribute, eg "InterceptorRequest"log.info("preHandle");String requestBody = HttpRequestContext.getRequestBody(request);log.info("Request Body: {}", requestBody);request.setAttribute(INTERNAL_REQUEST_BODY, requestBody);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// get InterceptorRequest from request attribute "InterceptorRequest"// update response body, response code into InterceptorRequest// save into persistence systemlog.info("afterCompletion");String requestBody = (String) request.getAttribute(INTERNAL_REQUEST_BODY);log.info("Request Body: {}", requestBody);if (response instanceof ContentCachingResponseWrapper responseWrapper) {byte[] responseBody = responseWrapper.getContentAsByteArray();String responseBodyStr = new String(responseBody, response.getCharacterEncoding());log.info("Response Body: {}", responseBodyStr);// write response body to responseresponseWrapper.copyBodyToResponse();}request.removeAttribute(INTERNAL_REQUEST_BODY);}
}

logback-spring.xml

%X{requestId:-MISSING} 输出MDC requestId

<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %X{requestId:-MISSING} %logger{36} - %msg%n</pattern>        </encoder></appender><root level="info"><appender-ref ref="STDOUT" /></root>
</configuration>
http://www.dtcms.com/a/522201.html

相关文章:

  • 手机上可以创建网站吗哈尔滨制作网站工作室
  • 网站更新文章衡水网站建设03181688
  • 做整装的网站怎么才能创建一个网站
  • 怎么在360做网站浏网站建设补贴
  • 做网站的价钱西安网站开发建设
  • 网上推广手段包括合肥官网seo服务
  • 人工智能风险与伦理(6)
  • 江苏省工程建设标准定额网站做网站哪个公司
  • 企业网站ui模板下载wordpress 页面不存在
  • 网站规划与设计方向黑科技引流推广神器下载
  • 合阳县建设局网站企业网站建设的劣势
  • 网站开发百度百科wordpress的404页面如何做
  • 网站开发专业建设先进网站
  • 伊宁网站建设优化绍兴百度seo排名
  • 金华建设学校继续教育网站网站建设公司上海做网站公司
  • 没有工信部备案的网站是骗子吗浙江做网站公司有哪些
  • 浏阳企业网站建设最新手游2022首发排行
  • 网站运营推广郑州seo
  • 制作网站的公司做网站去哪里找郑州怎么做网站排名
  • 【经典书籍】C++ Primer 第15章类虚函数与多态 “友元、异常和其他高级特性” 精华讲解
  • 公司网站开发语言林业网站源码
  • 棋牌游戏网站怎么做如何做好高端品牌网站建设
  • h5企业网站只做快速seo关键词优化方案
  • 电商网站建设注意凡科网做网站怎么样
  • 国内网站免备案坦桑尼亚网站域名后缀
  • 丑陋网站设计赏析wordpress 注册 邮箱验证
  • 网站推广外贸网站备案 深圳
  • 外贸网站模板建立建设网站 托管 费用
  • 网站建设备案是什么意思一站传媒seo优化
  • 网站开发平台建设今天贵阳最新头条新闻