aop - LoggingAspect - WebServiceTemplate.marshalSendAndReceive
问题描述
我正在尝试在调用 marshalSendAndReceive 时记录 Web 服务操作。这样我就可以记录任何使用 marshalSendAndReceive 的 Web 服务调用,如下所示。但不知何故 logWebserviceOperation 下面没有被调用。我的@Before 有问题吗 ..?还是我错过了什么。
package com.julia;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
package com.julia.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;
import com.julia.service.SOAPConnector;
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_1; //contstants to set the Jaxb context path
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_2;
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_3;
@Configuration
@RefreshScope
public class ParserConfig {
@Value("${application.WSSessionTimeoutInMilliSec}")
private int timeout;
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan(CONTEXT_PATH_1,CONTEXT_PATH_2, CONTEXT_PATH_3);
return marshaller;
}
@Bean
public SOAPConnector soapConnector(Jaxb2Marshaller marshaller) {
SOAPConnector client = new SOAPConnector();
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setConnectionTimeout(timeout);
client.setMessageSender(messageSender);
return client;
}
}
package com.julia.service;
import java.io.IOException;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
import org.springframework.ws.transport.http.HttpUrlConnection;
@Service
@RefreshScope
public class SOAPConnector extends WebServiceGatewaySupport {
private static final Logger LOGGER = LogManager.getLogger(SOAPConnector.class);
public Object callWebService(String url, Object request) {
return getWebServiceTemplate().marshalSendAndReceive(url, request);
}
}
package com.julia.logging;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
private static final Logger LOGGER = LogManager.getLogger(LoggingAspect.class);
public LoggingAspect() {
}
@Before("execution(* org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(..))")
public void logWebserviceOperation(JoinPoint jp) {
Object[] methodArgs = jp.getArgs();
String uri = methodArgs[0].toString();
String payload = String.valueOf(methodArgs[1]);
LOGGER.log("uri:" + uri);
LOGGER.log("payload :" + payload);
}
解决方案
Spring AOP 只能建议 Spring 容器管理的 bean。
从共享的代码来看,WebServiceTemplate
建议的目标实例不是 Spring bean。
public Object callWebService(String url, Object request) {
return getWebServiceTemplate().marshalSendAndReceive(url, request);
}
WebServiceGatewaySupport.getWebServiceTemplate()方法是从那里获取WebServiceTemplate
实例的。默认逻辑是构造一个新的类实例WebServiceTemplate
。
基于参考文档 WebServiceTemplateBuilder
可以用来创建一个WebServiceTemplate
bean。
然后可以使用WebServiceGatewaySupport.setWebServiceTempate()来设置 bean。这样做时请阅读注释。
或者,您可以建议SOAPConnector.callWebService(..)
哪个应该为您提供相同的日志。
@Before("execution(* com.julia.service.SOAPConnector.callWebService(..)) && args(url,request)")
public void logWebserviceOperation(JoinPoint jp,String url, Object request) {
LOGGER.log("uri:" + url);
LOGGER.log("payload :" + request);
}
推荐阅读
- r - 停止 lavaan 的 `sem()` 函数以打印输出
- docker - 需要 docker 网络做什么?
- google-apps-script - 如何确定哪个时间驱动的触发器调用了函数?
- python - 未找到 Docker 资源 wordnet
- angular - Angular:ChildView 与 getDocumentById
- go - 如何优雅地从 http.Request 更新默认值?
- tsql - T-SQL STRING_AGG() 的排序内容
- r - 在 R Shiny 中,如何消除不再需要的自定义函数?
- java - Java 抽象 Step Builder 模式
- r - 使用 dplyr、group_by 和折叠或汇总连接字符串/行,但保持 NA 值