詳解AOP與Filter攔截請(qǐng)求打印日志實(shí)用例子
相信各位同道在寫代碼的時(shí)候,肯定會(huì)寫一些日志打印,因?yàn)檫@對(duì)往后的運(yùn)維而言,至關(guān)重要的。
那么我們請(qǐng)求一個(gè)restfull接口的時(shí)候,哪些信息是應(yīng)該被日志記錄的呢?
以下做了一個(gè)基本的簡單例子,這里只是示例說明基本常規(guī)實(shí)現(xiàn)記錄的信息,根據(jù)項(xiàng)目的真實(shí)情況選用:
1 . Http請(qǐng)求攔截器(Filter) : 從HttpServletRequest獲取基本的請(qǐng)求信息
import name.ealen.util.HttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by EalenXie on 2018/9/7 15:56. * Http請(qǐng)求攔截器,日志打印請(qǐng)求基本相關(guān)信息 */ @Configuration public class FilterConfiguration { private static final Logger log = LoggerFactory.getLogger(FilterConfig.class); @Bean @Order(Integer.MIN_VALUE) @Qualifier("filterRegistration") public FilterRegistrationBean filterRegistration() { FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>(); registration.setFilter(controllerFilter()); registration.addUrlPatterns("/*"); return registration; } private Filter controllerFilter() { return new Filter() { @Override public void init(FilterConfig filterConfig) { log.info("ControllerFilter init Success"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String requestId = request.getHeader("Request-Id"); if (requestId == null) requestId = request.getRequestedSessionId(); System.out.println(); log.info("Http Request Request-Id : " + requestId); log.info("Http Request Information : {\"URI\":\"" + request.getRequestURL() + "\",\"RequestMethod\":\"" + request.getMethod() + "\",\"ClientIp\":\"" + HttpUtil.getIpAddress(request) + "\",\"Content-Type\":\"" + request.getContentType() + "\"}"); chain.doFilter(request, response); } @Override public void destroy() { log.info("ControllerFilter destroy"); } }; } }
2 . Controller的攔截AOP : 獲取 請(qǐng)求的對(duì)象,請(qǐng)求參數(shù),返回?cái)?shù)據(jù),請(qǐng)求返回狀態(tài),內(nèi)部方法耗時(shí)。
import com.alibaba.fastjson.JSON; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * Created by EalenXie on 2018/9/7 14:19. * AOP打印日志 : 請(qǐng)求的對(duì)象,請(qǐng)求參數(shù),返回?cái)?shù)據(jù),請(qǐng)求狀態(tài),內(nèi)部方法耗時(shí) */ @Aspect @Component public class ControllerInterceptor { private static final Logger log = LoggerFactory.getLogger(ControllerInterceptor.class); @Resource private Environment environment; @Around(value = "execution (* name.ealen.web.*.*(..))") public Object processApiFacade(ProceedingJoinPoint pjp) { String appName; try { appName = environment.getProperty("spring.application.name").toUpperCase(); } catch (Exception e) { appName = "UNNAMED"; } long startTime = System.currentTimeMillis(); String name = pjp.getTarget().getClass().getSimpleName(); String method = pjp.getSignature().getName(); Object result = null; HttpStatus status = null; try { result = pjp.proceed(); log.info("RequestTarget : " + appName + "." + name + "." + method); log.info("RequestParam : " + JSON.toJSON(pjp.getArgs())); if (result instanceof ResponseEntity) { status = ((ResponseEntity) result).getStatusCode(); } else { status = HttpStatus.OK; } } catch (Throwable throwable) { status = HttpStatus.INTERNAL_SERVER_ERROR; result = new ResponseEntity<>("{\"Internal Server Error\" : \"" + throwable.getMessage() + "\"}", status); throwable.printStackTrace(); } finally { log.info("ResponseEntity : {" + "\"HttpStatus\":\"" + status.toString() + "\"" + ",\"ResponseBody\": " + JSON.toJSON(result) + "}"); log.info("Internal Method Cost Time: {}ms", System.currentTimeMillis() - startTime); } return result; } }
3 . 提供一個(gè)簡單的restfull接口 :
package name.ealen.web; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by EalenXie on 2018/9/7 14:24. */ @RestController public class SayHelloController { @RequestMapping("/sayHello") public String sayHello() { return "hello world"; } @RequestMapping("/say") public ResponseEntity<?> say(@RequestBody Object o) { return new ResponseEntity<>(o, HttpStatus.OK); } }
4 . 使用Postman進(jìn)行基本測(cè)試 :
5 . 控制臺(tái)可以看到基本效果 :
以上只是關(guān)于Controller應(yīng)該記錄日志的一個(gè)簡單的例子,完整代碼可見 https://github.com/EalenXie/springboot-controller-logger
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IDEA java出現(xiàn)無效的源發(fā)行版14解決方案
這篇文章主要介紹了IDEA java出現(xiàn)無效的源發(fā)行版14解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Spring boot中PropertySource注解的使用方法詳解
這篇文章主要給大家介紹了關(guān)于Spring boot中PropertySource注解的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12Java?ArrayList實(shí)現(xiàn)刪除指定位置的元素
目標(biāo):list中有0到39共40個(gè)元素,刪除其中索引是10、20、30的元素。本文為大家整理了三個(gè)不同的方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-01-01Java實(shí)現(xiàn)八種排序算法詳細(xì)代碼舉例
排序問題一直是程序員工作與面試的重點(diǎn),今天特意整理研究下與大家共勉!這篇文章主要介紹了Java實(shí)現(xiàn)八種排序算法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10java輸入時(shí)如何通過回車(enter)來結(jié)束輸入
這篇文章主要介紹了java輸入時(shí)如何通過回車(enter)來結(jié)束輸入,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05