안녕하세요. 외부 SOAP RCP 스타일 서비스에 커넥터를 쓰는 방법을 배우고 있습니다. jaxws-maven-plugin 플러그인을 사용하여 WSDL 파일에서 Java 클래스를 생성합니다. 그리고 웹 서비스 클라이언트 빈을 생성하기 위해 Spring을 사용하고 있습니다 :SOAP 메시지를 클라이언트 측에 기록하는 방법은 무엇입니까?
@Configuration
public class StoreServiceConfig {
@Bean
public StoreWS storeWS() throws IOException {
JaxWsPortProxyFactoryBean factoryBean = new JaxWsPortProxyFactoryBean();
factoryBean.setServiceInterface(StoreWS.class);
factoryBean.setWsdlDocumentUrl(new ClassPathResource("/wsdl/StoreWS.wsdl").getURL());
factoryBean.setNamespaceUri("urn_store");
factoryBean.setServiceName("StoreWSService");
factoryBean.setEndpointAddress("https://10.34.45.82/storeservice/services/StoreWS");
factoryBean.setUsername("testuser");
factoryBean.setPassword("testpassword");
factoryBean.afterPropertiesSet();
return (StoreWS) factoryBean.getObject();
}
}
클라이언트를 테스트하기 위해 JUnit을 사용하여 테스트 클래스를 작성했습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = StoreServiceTestConfig.class)
public class StoreServiceImplTest {
@Autowired
private StoreWS storeWS;
...
@Test
public void testExecuteQuery() throws Exception {
...
StoreResponseType response = storeWS.executeQuery(storeRequest);
...
}
}
가 지금은 콘솔로 전체 발신 및 수신 SOAP 메시지를 기록 할 수있는 테스트가 필요합니다 나는 클라이언트에게 이런 식으로 호출합니다. 제발 어떻게 그럴 수있어? 더 쉬운 방법.
나는 다음과 같은 시스템 매개 변수를 사용하여 조언을 발견하지만, 그들 중 누구도 나를 위해 작동하지 : 나는 봄 구성 클래스 (NO XMLS) 및 모든 종속성의 최신 버전을 사용하고
com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true
com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
com.sun.xml.ws.transport.local.LocalTransportPipe.dump=true
com.sun.xml.ws.transport.http.HttpAdapter.dump=true
.
내가 발견 한 this answer하지만 내 시나리오에서 사용하는 방법을 모르겠다.
미리 감사드립니다. Vojtech
편집 : 내 logback.xml은 다음과 같습니다하지만, 난 여전히 콘솔의 모든 비누 메시지를 볼 수 없습니다 :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n
</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<logger name="org.springframework.ws.client.MessageTracing">
<level value="DEBUG" />
<appender-ref ref="consoleAppender" />
</logger>
<logger name="org.springframework.ws.server.MessageTracing">
<level value="DEBUG" />
<appender-ref ref="consoleAppender" />
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="consoleAppender" />
</root>
</configuration>
편집 2 : 상위 프로젝트 지정의 의 pom.xml 이러한 종속성 :
: 테스트 클래스가 위치한 모듈의<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.1.2.RELEASE</spring.version>
<spring-ws-core.version>2.2.0.RELEASE</spring-ws-core.version>
<slf4j.version>1.7.7</slf4j.version>
<logback.version>1.1.2</logback.version>
<junit.version>4.12</junit.version>
<commons-logging.version>1.1.1</commons-logging.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>${spring-ws-core.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- LOGGING -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- TESTING -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
의 pom.xml은에 따라 달라집니다3210
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>vinweb-connector-ws</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>vinweb-connector-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- LOGGING -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<!-- TESTING -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
편집 3 : I'v 내 프로젝트에 LoggingHandler 클래스를 추가 :
package storeservice.log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.xml.namespace.QName;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
@Component
public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {
private final Logger LOG = LoggerFactory.getLogger(LoggingHandler.class);
@Override
public Set<QName> getHeaders() {
return Collections.emptySet();
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
logMessage(context, "SOAP message : ");
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
logMessage(context, "SOAP error : ");
return true;
}
@Override
public void close(MessageContext context) {
}
private void logMessage(SOAPMessageContext context, String type) {
try {
if(LOG.isDebugEnabled()) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(outboundProperty) {
LOG.debug("Outbound " + type);
} else {
LOG.debug("Inbound " + type);
}
SOAPMessage message = context.getMessage();
// Print out the MIME headers
MimeHeaders headers = message.getMimeHeaders();
Iterator<MimeHeader> headersIterator = headers.getAllHeaders();
MimeHeader mimeHeader;
LOG.debug(" Mime headers :");
while(headersIterator.hasNext()) {
mimeHeader = headersIterator.next();
LOG.debug(" " + mimeHeader.getName() + " : " + mimeHeader.getValue());
}
// Print out the message body
LOG.debug(" Message body :");
try(OutputStream outStream = new ByteArrayOutputStream()) {
message.writeTo(outStream);
LOG.debug(" " + outStream.toString());
}
}
} catch (Exception e){
if(LOG.isErrorEnabled()) {
LOG.error("Error logging SOAP message", e);
}
}
}
}
그리고 웹 서비스 클라이언트 빈 생성하는 데 사용
이@Configuration
public class StoreServiceConfig {
@Autowired
private LoggingHandler loggingHandler;
@Bean
public StoreWS storeWS() throws IOException {
JaxWsPortProxyFactoryBean factoryBean = new JaxWsPortProxyFactoryBean();
factoryBean.setServiceInterface(StoreWS.class);
factoryBean.setWsdlDocumentUrl(new ClassPathResource("/wsdl/StoreWS.wsdl").getURL());
factoryBean.setNamespaceUri("urn_store");
factoryBean.setServiceName("StoreWSService");
factoryBean.setEndpointAddress("https://10.34.45.82/storeservice/services/StoreWS");
factoryBean.setUsername("testuser");
factoryBean.setPassword("testpassword");
factoryBean.setHandlerResolver(handlerResolver());
factoryBean.afterPropertiesSet();
return (StoreWS) factoryBean.getObject();
}
@Bean
public HandlerResolver handlerResolver() {
return new HandlerResolver() {
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<>();
handlerChain.add(loggingHandler);
return handlerChain;
}
};
}
}
그 결과입니다 SOAP 메시지는 기록되지만 storeWS.executeQuery 호출 응답은 NULL입니다.
StoreResponseType response = storeWS.executeQuery(storeRequest);
내가 행 다음에 주석 경우 691,363,210
그런 다음 다시 일을 시작하고 응답 객체를 할당하지만 SOAP 메시지가 기록되지 않습니다 :
// factoryBean.setHandlerResolver(handlerResolver());
내가 수업 시간에 라인을 다음 중 응답 것을 원인 LoggingHandler 것을 발견했다 서비스 호출은 null입니다.
SOAPMessage message = context.getMessage();
예, 나는 봄 옵션에 관심하시기 바랍니다. org.springframework.ws.server.MessageTracing과 org.springframework.ws.client.MessageTracing의 로그 레벨을 DEBUG로 설정했지만 (내 질문에 편집 참조) 콘솔에서 비누 메시지를 볼 수 없습니다. 고맙습니다. – Vojtech
커먼즈 로깅 의존성 (문서에 따르면 1.1 이상)을 클래스 패스에 추가 했습니까? 그렇지 않으면 root-logger를 DEBUG 레벨로 설정하면 Spring 로그를 볼 수 있습니까? 웹 서비스 구성보다 로거 구성/종속성 문제가 더 많을 수 있습니다. – KevinHol
첫 번째 답변을 수정합니다. 로깅 구성을 조사하기 전에 해당 솔루션을 사용해보십시오. – KevinHol