-
aop 实现Java日志功能
2020-12-03 09:35:48在请求么此进到一个controller时,获取到它的请求方法,用户信息,异常等信息记录到数据库里。 1.第一步 自定义一个@Log注解,标记到你要记录日志的controller上面。我的注解有三个参数,分别是事件类型,操作...aop 是一个强大的..,思路很简单,就是在进入到一个方法时,获取到进入前,中,后,环绕。这四个状态时的这个方法的属性。我们可以利用它来实现日志功能,可以保证日志模块到业务代码最小化的侵入(就只有一个注解)。在请求每次进到一个controller时,获取到它的请求方法,用户信息,异常等信息记录到数据库里。
1.第一步 自定义一个@Log注解,标记到你要记录日志的controller上面。我的注解有三个参数,分别是事件类型,操作类型,描述。可以在切面里面获取到他们分别标记在控制层上面的值。
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { String eventType() default ""; String operationType() default ""; String description() default ""; }
2.第二部 标记到你要记录日志的controller上面,如下,参数可以自定义内容,在切面里面获取。
/** * @Title gettq * @Date 2019年8月7日 上午11:25:55 * @author liunn * @Description 天气 * @param request * @param entity * @return * @throws Exception */ @Log(eventType="1",operationType="3",description="天气") @RequestMapping(value = "/gettq", method = { RequestMethod.POST }) public @ResponseBody JSONObject gettq(HttpServletRequest request, @ModelAttribute(" entity ") Entity entity) throws Exception { }
3.第三步,切面获取值,写入到数据库中
import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.scheduling.annotation.Async; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.core.JsonProcessingException; import com.sgcc.zcqsm.reshandover.annotation.Log; import com.sgcc.zcqsm.reshandover.config.AppProperties; import com.sgcc.zcqsm.reshandover.entity.PageEntity; import com.sgcc.zcqsm.reshandover.service.IWebsService; import com.sgcc.zcqsm.reshandover.service.LogService; import com.sgcc.zcqsm.reshandover.util.DataUtil; import com.sgcc.zcqsm.reshandover.util.ResponseInfo; import com.sgcc.zcqsm.util.ContextHolderUtils; import com.sgcc.zcqsm.util.JsonUtil; import com.sgcc.zcqsm.util.ToolUtil; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import com.fasterxml.jackson.databind.ObjectMapper; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @Aspect @Order(5) @Component @EnableConfigurationProperties(AppProperties.class) public class LogAspect { // private Logger logger = LoggerFactory.getLogger(LogAspect.class); @Autowired private RedisTemplate<Object,Object> redisTemplate; @Autowired private LogService logService; @Autowired private IWebsService iWebsService; @Autowired ObjectMapper objectMapper; @Autowired private AppProperties appProperties; private ThreadLocal<Date> startTime = new ThreadLocal<Date>(); @Pointcut("@annotation(com.sgcc.zcqsm.reshandover.annotation.Log)") public void pointcut() { } /** * 前置通知,在Controller层操作前拦截 * * @param joinPoint 切入点 */ @Before("pointcut()") public void doBefore(JoinPoint joinPoint) { // logger.info("进入["+joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+"]方法里面"); // 获取当前调用时间 startTime.set(new Date()); } /** * 正常情况返回 * * @param joinPoint 切入点 * @param rvt 正常结果 */ @AfterReturning(pointcut = "pointcut()") public void doAfter(JoinPoint joinPoint) throws Exception { //1正常 // logger.info("退出["+joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+"]方法"); handleLog(joinPoint, null,1); } /** * 异常信息拦截 * * @param joinPoint * @param e */ @AfterThrowing(pointcut = "pointcut()", throwing = "e") public void doAfter(JoinPoint joinPoint, Exception e) throws Exception { //0 失败 // logger.info("退出["+joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+"]方法"); handleLog(joinPoint, e,0); } @Async private void handleLog(final JoinPoint joinPoint, final Exception e,int eventResultCode) throws Exception{ if(isOpen()) { // 获得注解 Method method = getMethod(joinPoint); Log log = getAnnotationLog(method); if (log == null) { return; } HttpServletRequest request = ToolUtil.getRequest(); String lrrName=request.getHeader("userId"); // Date now = new Date(); // // 操作数据库日志表 // ErpLog erpLog = new ErpLog(); // erpLog.setErrorCode(0); // erpLog.setIsDeleted(0); // // 请求信息 // erpLog.setType(ToolUtil.isAjaxRequest(request) ? "Ajax请求" : "普通请求"); // erpLog.setTitle(log.value()); // erpLog.setHost(request.getRemoteHost()); // erpLog.setUri(request.getRequestURI().toString()); erpLog.setHeader(request.getHeader(HttpHeaders.USER_AGENT)); // erpLog.setHttpMethod(request.getMethod()); // erpLog.setClassMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); // // // // 请求的方法参数值 // Object[] args = joinPoint.getArgs(); // // 请求的方法参数名称 // LocalVariableTableParameterNameDiscoverer u= new LocalVariableTableParameterNameDiscoverer(); // String[] paramNames = u.getParameterNames(method); // if (args != null && paramNames != null) { // StringBuilder params = new StringBuilder(); // params = handleParams(params, args, Arrays.asList(paramNames)); // erpLog.setParams(params.toString()); // } // String retString = JsonUtil.bean2Json(rvt); // erpLog.setResponseValue(retString.length() > 5000 ? JsonUtil.bean2Json("请求参数数据过长不与显示") : retString); // if (e != null) { // erpLog.setErrorCode(1); // erpLog.setErrorMessage(e.getMessage()); // } // Date stime = startTime.get(); // erpLog.setStartTime(stime); // erpLog.setEndTime(now); // erpLog.setExecuteTime(now.getTime() - stime.getTime()); // erpLog.setUsername(MySysUser.loginName()); // HashMap<String, String> browserMap = ToolUtil.getOsAndBrowserInfo(request); // erpLog.setOperatingSystem(browserMap.get("os")); // erpLog.setBrower(browserMap.get("browser")); // erpLog.setId(IdUtil.simpleUUID()); // logService.insertSelective(erpLog); if (e != null) { iWebsService.saveCwrz(DataUtil.returnExceptionLx(e), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "程序报错:"+DataUtil.returnExceptionInfo(e), lrrName); } //日志信息记录到数据库中 logService.saveLog(lrrName, Integer.parseInt(log.eventType()), Integer.parseInt(log.operationType()),eventResultCode, log.description(),request.getRemoteAddr()); } } /** * 是否存在注解,如果存在就获取 */ private Log getAnnotationLog(Method method) { if (method != null) { return method.getAnnotation(Log.class); } return null; } private Method getMethod(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method; } return null; } private StringBuilder handleParams(StringBuilder params, Object[] args, List paramNames) throws JsonProcessingException { for (int i = 0; i < args.length; i++) { if (args[i] instanceof Map) { Set set = ((Map) args[i]).keySet(); List list = new ArrayList(); List paramList = new ArrayList<>(); for (Object key : set) { list.add(((Map) args[i]).get(key)); paramList.add(key); } return handleParams(params, list.toArray(), paramList); } else { if (args[i] instanceof Serializable) { Class<?> aClass = args[i].getClass(); try { aClass.getDeclaredMethod("toString", new Class[]{null}); // 如果不抛出NoSuchMethodException 异常则存在 toString 方法 ,安全的writeValueAsString ,否则 走 Object的 toString方法 params.append(" ").append(paramNames.get(i)).append(": ").append(objectMapper.writeValueAsString(args[i])); } catch (NoSuchMethodException e) { params.append(" ").append(paramNames.get(i)).append(": ").append(objectMapper.writeValueAsString(args[i].toString())); } } else if (args[i] instanceof MultipartFile) { MultipartFile file = (MultipartFile) args[i]; params.append(" ").append(paramNames.get(i)).append(": ").append(file.getName()); } else { params.append(" ").append(paramNames.get(i)).append(": ").append(args[i]); } } } return params; } private boolean isOpen() { String logOpen=appProperties.getLogOpen(); if(getRedis("requestPrivateKey")==null||getRedis("requestPrivateKey")=="") { String requestPrivateKey =appProperties.getFilterPwd(); setRedis("requestPrivateKey",requestPrivateKey); } if(getRedis("SessionOutTimeStr")==null||getRedis("SessionOutTimeStr")=="") { String SessionOutTimeStr =appProperties.getSessionOutTime(); setRedis("SessionOutTimeStr",SessionOutTimeStr); } if(logOpen.equals("true")) { return true; }else { return false; } } private void setRedis(String rkey,Object ObjectStr) { redisTemplate.opsForValue().set(rkey, ObjectStr, 1L, TimeUnit.DAYS); } private Object getRedis(String rkey) { Object rObject =redisTemplate.opsForValue().get(rkey); return rObject; } }
这里面 需要注意的是
@Pointcut("@annotation(com.sgcc.zcqsm.reshandover.annotation.Log)")
这个注解的值是Log自定义注解的位置,也就是它的包名加类名。
handleLog这个方法是实现日志写入数据库的地方,可以根据实际情况写日志属性。这里面分别对应异常日志,和业务日志。
这时候,日志就实现了。至于怎么写入数据库,持久层。这个简单,不会的话自行百度。
AppProperties是一个自定义的配置文件类。这个也不难。里面配置是否开启日志。sm2公钥。会话超时。
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Configuration @ConfigurationProperties(prefix = "app", ignoreInvalidFields = false) @PropertySource("classpath:app.properties") @Component public class AppProperties { private String logOpen; private String sessionOutTime; private String filterPwd; public String getLogOpen() { return logOpen; } public void setLogOpen(String logOpen) { this.logOpen = logOpen; } public String getSessionOutTime() { return sessionOutTime; } public void setSessionOutTime(String sessionOutTime) { this.sessionOutTime = sessionOutTime; } public String getFilterPwd() { return filterPwd; } public void setFilterPwd(String filterPwd) { this.filterPwd = filterPwd; } }
app.properties
app.logOpen=true app.sessionOutTime=30 app.filterPwd=216c9f564c4b1891864b4b35d05db181864832802f6addf95e7651d28a988184
这里面有一些工具类。我把他们粘贴出来。
import com.google.common.collect.Maps; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.HashMap; public class ToolUtil { /** * 获取客户端的ip信息 * * @param request * @return */ public static String getClientIp(HttpServletRequest request) { String ip = request.getHeader("X-Real-IP"); if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Forwarded-For"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } public static ServletRequestAttributes getRequestAttributes() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return (ServletRequestAttributes) attributes; } /** * 获取request */ public static HttpServletRequest getRequest() { return getRequestAttributes().getRequest(); } /** * 获取response */ public static HttpServletResponse getResponse() { return getRequestAttributes().getResponse(); } /** * 获取session */ public static HttpSession getSession() { return getRequest().getSession(); } /** * 是否是Ajax异步请求 */ public static boolean isAjaxRequest(HttpServletRequest request) { String accept = request.getHeader("accept"); if (accept != null && accept.indexOf("application/json") != -1) { return true; } String xRequestedWith = request.getHeader("X-Requested-With"); if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) { return true; } String uri = request.getRequestURI(); if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) { return true; } String ajax = request.getParameter("__ajax"); if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) { return true; } return false; } /** * 获取操作系统,浏览器及浏览器版本信息 * * @param request * @return */ public static HashMap<String, String> getOsAndBrowserInfo(HttpServletRequest request) { HashMap<String, String> map = Maps.newHashMap(); String browserDetails = request.getHeader("User-Agent"); String userAgent = browserDetails; String user = userAgent.toLowerCase(); String os = ""; String browser = ""; //=================OS Info======================= if (userAgent.toLowerCase().contains("windows")) { os = "Windows"; } else if (userAgent.toLowerCase().contains("mac")) { os = "Mac"; } else if (userAgent.toLowerCase().contains("x11")) { os = "Unix"; } else if (userAgent.toLowerCase().contains("android")) { os = "Android"; } else if (userAgent.toLowerCase().contains("iphone")) { os = "IPhone"; } else { os = "UnKnown, More-Info: " + userAgent; } //===============Browser=========================== if (user.contains("edge")) { browser = (userAgent.substring(userAgent.indexOf("Edge")).split(" ")[0]).replace("/", "-"); } else if (user.contains("msie")) { String substring = userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0]; browser = substring.split(" ")[0].replace("MSIE", "IE") + "-" + substring.split(" ")[1]; } else if (user.contains("safari") && user.contains("version")) { browser = (userAgent.substring(userAgent.indexOf("Safari")).split(" ")[0]).split("/")[0] + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1]; } else if (user.contains("opr") || user.contains("opera")) { if (user.contains("opera")) { browser = (userAgent.substring(userAgent.indexOf("Opera")).split(" ")[0]).split("/")[0] + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1]; } else if (user.contains("opr")) { browser = ((userAgent.substring(userAgent.indexOf("OPR")).split(" ")[0]).replace("/", "-")) .replace("OPR", "Opera"); } } else if (user.contains("chrome")) { browser = (userAgent.substring(userAgent.indexOf("Chrome")).split(" ")[0]).replace("/", "-"); } else if ((user.contains("mozilla/7.0")) || (user.contains("netscape6")) || (user.contains("mozilla/4.7")) || (user.contains("mozilla/4.78")) || (user.contains("mozilla/4.08")) || (user.contains("mozilla/3"))) { browser = "Netscape-?"; } else if (user.contains("firefox")) { browser = (userAgent.substring(userAgent.indexOf("Firefox")).split(" ")[0]).replace("/", "-"); } else if (user.contains("rv")) { String IEVersion = (userAgent.substring(userAgent.indexOf("rv")).split(" ")[0]).replace("rv:", "-"); browser = "IE" + IEVersion.substring(0, IEVersion.length() - 1); } else { browser = "UnKnown, More-Info: " + userAgent; } map.put("os", os); map.put("browser", browser); return map; } }
-
JAVA获取客户端内外网IP、主机名、浏览器相关信息
2020-07-27 10:36:22在项目中大部分需要记录客户端操作日志,因此备忘一下,这些获取客户端相关信息的方法 只需两步:导包+工具方法 1.导包,在maven中加入相关依赖 <!-- 请求头参数分析包 --> <dependency> <groupId&...简介:
在项目中大部分需要记录客户端操作日志,因此备忘一下,这些获取客户端相关信息的方法。
一般使用ThreadLocal和Interceptor实现信息存储,存放在自定义的BaseContextHandler类。
只需两步:导包+工具方法1.导包,在maven中加入相关依赖
<!-- 请求头参数分析包 --> <dependency> <groupId>eu.bitwalker</groupId> <artifactId>UserAgentUtils</artifactId> <version>1.20</version> </dependency>
2.工具方法
/** * 获取客户端的真实IP地址 * * @param request * @return */ public static String getClientRealIp(HttpServletRequest request) { String ipAddress = null; ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if ("127.0.0.1".equals(ipAddress)) { // 根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); ipAddress = inet.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } } // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 // "***.***.***.***".length() if (ipAddress != null && ipAddress.length() > 15) { // = 15 if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } return ipAddress; } /** * @param * @todo 获取外网ip * @author xiaotao */ public static String getOuterNetIp() { String result = ""; URLConnection connection; BufferedReader in = null; try { URL url = new URL("http://www.icanhazip.com"); connection = url.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "KeepAlive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setConnectTimeout(3000); connection.setReadTimeout(3000); connection.connect(); in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.getMessage(); } } return result; } /** * 获取客户端的真实主机名 * * @param request * @return */ public static String getClientHostName(HttpServletRequest request) { return request.getRemoteHost(); } /** * 获取客户端的浏览器名 * * @param request * @return */ public static String getClientBrowserName(HttpServletRequest request) { UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); // 获取客户端操作系统 String os = userAgent.getOperatingSystem().getName(); // 获取客户端浏览器 String browser = userAgent.getBrowser().getName(); return browser; } /** * 获取客户端的浏览器 * * @param request * @return */ public static String getUserAgent(HttpServletRequest request) { String agent = request.getHeader("User-Agent"); if (StringUtils.hasText(agent)) { StringTokenizer st = new StringTokenizer(agent, ";"); String browser = st.nextToken(); if (browser != null && browser.length() > 20) { browser = browser.substring(0, 20); } return browser; } return null; }
complete!!!
有问题可在评论区互动,共同学习进步!!! -
JAVA_API1.6文档(中文)
2010-04-12 13:31:34java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.... -
现在是一些关键操作要记录操作日志,但是在insert的时候,偶然会出现插入失败的问题.现在找不到问题所在?
2019-08-30 10:21:05}//请求参数 Object[] method_param = null; Object object; try { method_param = point.getArgs(); //获取方法参数 object = point.proceed(); } catch (Exception e) { ssOperLogEntity.... -
java api最新7.0
2013-10-26 17:34:06java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util... -
微服务下一个系统被拆分为多个服务,但是像 安全认证,流量控制,日志,监控等功能是每个服务都需要的,没有网关的话,我们就需要在每个服务中单独实现,这使得我们做了很多重复的事情并且没有一个全局的视图来统一...
-
java开源包1
2013-06-28 09:14:34集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包12
2013-06-28 10:14:45集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
Java资源包01
2016-08-31 09:16:25集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包101
2016-07-13 10:11:08集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包11
2013-06-28 10:10:38集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包2
2013-06-28 09:17:39集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包3
2013-06-28 09:20:52集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包6
2013-06-28 09:48:32集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包5
2013-06-28 09:38:46集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包10
2013-06-28 10:06:40集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包4
2013-06-28 09:26:54集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包8
2013-06-28 09:55:26集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包9
2013-06-28 09:58:55集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
java开源包7
2013-06-28 09:52:16集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息... -
JAVA上百实例源码以及开源项目
2016-01-03 17:37:40Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,... -
JAVA上百实例源码以及开源项目源代码
2018-12-11 17:07:42Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证... -
Oracle9i的init.ora参数中文说明
2008-11-07 20:14:11监听程序进程需要一个监听地址, 以便处理系统所用的各个网络协议的连接请求。 除非 MTS_MULTIPLE_LISTENERS=TRUE, 否则每个条目都必须有一个独立的相邻值。此参数自 8.1.3 版起已废弃 语法 : (ADDRESS=(PROTOCOL=... -
Java 1.6 API 中文 New
2013-10-26 14:08:22java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util... -
[Java参考文档]
2013-03-19 16:56:15java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.... -
java jdk-api-1.6 中文 chmd
2018-03-22 11:32:15java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.... -
aop 获取方法入参出参_Spring AOP 记录接口信息(获取接口入参,出参)
2020-12-23 19:59:36需求:为系统中所有的提交,修改,删除等等操作做日志记录,记录的内容包括:请求参数,返回参数,如果报错就存储报错信息。日志要添加一个日志类型。因为有用到工具类,先放工具类吧import java.util.List;import ...需求:为系统中所有的提交,修改,删除等等操作做日志记录,记录的内容包括:请求参数,返回参数,如果报错就存储报错信息。日志要添加一个日志类型。
因为有用到工具类,先放工具类吧
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonUtil {
// 定义jackson对象
private static final ObjectMapper mapper = new ObjectMapper();
/**
* 将对象转换成json字符串
* @param data
* @return
*/
public static String toJSONString(Object data) {
try {
String string = mapper.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
* @param jsonData
* @param beanType
* @return
*/
public static T parseObject(String jsonData, ClassbeanType) {
try {
T t = mapper.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成list
* @param jsonData
* @param beanType
* @return
*/
public static ListparseArray(String jsonData, ClassbeanType) {
JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType);
try {
Listlist = mapper.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
然后开始正题
因为我的接口都是通过controller , 里面已经做过了@RequestBody,所以拿出参的时候试了好多方法
知道最后看到了一个大佬发的才醍醐灌顶,伪代码如下
/*@AfterReturning注解用于获取方法的返回值*/
@AfterReturning(pointcut = "print()", returning = "object")
public void getAfterReturn(Object object) {
endTime = System.currentTimeMillis() - startTime;
//返回参数
String outParam = JsonUtil.toJSONString(object);//这里用到了JsonUtil 工具类
System.out.println(outParam);//直接获取出参了
}
整个代码就在下面了
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName HttpRequestAspect
* @Description 项目
* @uthor zhangxubin
* @Date 2019/6/25 18:19
* @Version 1.0
*/
@Aspect
@Component
public class HttpRequestAspect {
@Autowired
private SystemTbApilogMapper systemTbApilogMapper;
public static long startTime;
public static long endTime;
/*@PointCut注解表示表示横切点,哪些方法需要被横切*/
/*切点表达式*/
@Pointcut("execution(public * com.reijing.his.rest.modular.controller.*.*(..))")
/*切点签名*/
public void print() {
}
/*@Before注解表示在具体的方法之前执行*/
@Before("print()")
public void before(JoinPoint joinPoint){
// log.info("前置切面before……");
startTime = System.currentTimeMillis();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
//入参
String inParam = JsonUtil.toJSONString(joinPoint.getArgs());//入参
String basePath1 = request.getServerName() + ":" + request.getServerPort() ;//IP地址 , 可以自己打印看一下
String requestURI = (request).getRequestURI();
String setRequestUrl = request.getScheme() + "://" +basePath1+requestURI;//十分完整的 Ip地址+方法路径 controller全路径
String results=request.getHeader("LoginInfo"); // getHead 头信息
String contextPath = request.getContextPath();//被请求的控制器
}
/*@After注解表示在方法执行之后执行*/
@After("print()")
public void after() throws IOException {
}
/*@AfterReturning注解用于获取方法的返回值*/
@AfterReturning(pointcut = "print()", returning = "object")
public void getAfterReturn(Object object) {
endTime = System.currentTimeMillis() - startTime;
//返回参数
String outParam = JsonUtil.toJSONString(object);
}
}
-
[Java参考文档].JDK_API 1.6
2017-09-21 22:32:08java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util... -
JavaAPI中文chm文档 part2
2011-08-19 08:58:42java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java....