Custom soapHeader for a soap request with Spring - java

I'm making a SOAP request with custom headers which contains the security part of the request.
But the request now contains two headers and its throwing the following error :
[Request processing failed; nested exception is org.springframework.ws.soap.client.SoapFaultClientException: No WS-Security header found] with root cause
The headers that is formed is :
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><soapenv:Envelope xmlns:ser="dasdasdasd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><wsse:Security xmlns:wsse="asdasdasdas" soapenv:mustUnderstand="1"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-2"><wsse:Username>test</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">adasdasdasdasd</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">!##!####$#!#!##%*(&*&^%#$##</wsse:Nonce><wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header></soapenv:Envelope></SOAP-ENV:Header><SOAP-ENV:Body><ns2:CreateSaleOrderRequest xmlns:ns2="http://uniware.unicommerce.com/services/"><ns2:SaleOrder><ns2:DisplayOrderCode>200</ns2:DisplayOrderCode></ns2:SaleOrder></ns2:CreateSaleOrderRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
My code for the above request is below :
private static final String uri = "http://requestb.in/1eh2un81";
public String createSaleOrder(Suborder suborder)
{
SaleOrder saleorder = new SaleOrder();
saleorder = setSaleOrderObject(suborder);
CreateSaleOrderRequest request = new CreateSaleOrderRequest();
request.setSaleOrder(saleorder);
String response = this.getWebServiceTemplate().marshalSendAndReceive(uri, request,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException
{
SoapMessage soapmessage = (SoapMessage)message;
SoapHeader header = soapmessage.getSoapHeader();
//soapmessage.getEnvelope().addAttribute(, "soapenv");
StringBuilder soapheader = new StringBuilder();
soapheader.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"zsdasdasdasd">");
soapheader.append("<soapenv:Header>");
soapheader.append("<wsse:Security soapenv:mustUnderstand=\"1\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"> ");
soapheader.append("<wsse:UsernameToken wsu:Id=\"UsernameToken-2\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");
soapheader.append("<wsse:Username>test</wsse:Username>");
soapheader.append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">adasdasdasdasd</wsse:Password>");
soapheader.append("<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">!2312312!##!##!#$##%R</wsse:Nonce>");
soapheader.append("<wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created>");
soapheader.append("</wsse:UsernameToken>");
soapheader.append("</wsse:Security>");
soapheader.append("</soapenv:Header>");
soapheader.append("</soapenv:Envelope>");
StringSource HeaderSource = new StringSource(soapheader.toString());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(HeaderSource,header.getResult());
}
}).toString();
System.out.println(response);
Please suggest how do i resolve this error.TIA!

Uhm provided you're using spring you would have to go something like this.. inside your xml for the ws you should have:
<bean id="YourWsClientBean" class="eu.europa.acer.aris.dciws.client.DciWsClient">
<constructor-arg ref="webServiceTemplate"></constructor-arg>
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory"/>
<property name="marshaller" ref="marshaller"></property>
<property name="unmarshaller" ref="unMarshaller"></property>
<property name="messageSender">
<bean
class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
</bean>
</property>
<!-- NON PROXY
<property name="messageSender" ref = "httpSender"></property> -->
<property name="defaultUri" value="https://testframework.test-acer-remit.eu/dci-ws/" />
<property name="interceptors">
<list>
<ref bean="securityConfInterceptor" />
</list>
</property>
</bean>
<bean id="securityConfInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration" value="classpath:securityPolicy.xml" />
<property name="callbackHandlers">
<!-- <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore" /> <property name="privateKeyPassword"
value="changeit" /> <property name="trustStore" ref="trustStore" /> </bean> -->
<list>
<ref bean="keyStoreHandler"/>
</list>
</property>
</bean>
marshaller and unmarshaller should be clear to you i suppose.
The most important part in your case is
inside the securityPolicy.xml you will be able to define your desirede policy for outgoing//incoming messages, be it signature, usernameandpassword, etc..
The following file for example is for signing the request with a certain certificate.
<?xml version="1.0" encoding="UTF-8"?>
<!-- <xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:Sign includeTimestamp="false"> <xwss:X509Token certificateAlias="ceremp
staging ca"/> </xwss:Sign> </xwss:SecurityConfiguration> -->
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<!-- <xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/>
<xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/>
<xwss:Timestamp /> <xwss:UsernameToken name="mojo" password="mojopass" digestPassword="true"
useNonce="true"/> -->
<xwss:Sign>
<xwss:X509Token certificateAlias="acerprivate" />
<!-- <xwss:X509Token certificateAlias="acer staging cert" /> -->
<xwss:CanonicalizationMethod algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<xwss:SignatureMethod algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<xwss:SignatureTarget type="xpath"
value="./SOAP-ENV:Envelope/SOAP-ENV:Body">
<xwss:DigestMethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<xwss:Transform algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<xwss:AlgorithmParameter name="XPATH"
value="./SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature[1]/ds:KeyInfo/wsse:SecurityTokenReference" />
</xwss:Transform>
<xwss:Transform
algorithm="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform">
<xwss:AlgorithmParameter name="CanonicalizationMethod"
value="http://www.w3.org/2001/10/xml-exc-c14n#" />
</xwss:Transform>
</xwss:SignatureTarget>
</xwss:Sign>
</xwss:SecurityConfiguration>
Hope this give you an hand as a general concept.
At times I advice some colleague new with ws to take the dirty alternative, if they want to keep the altering as simple as possible.
E.g. this is from spring forum -->
public void sendAndReceiveXMLPayload(String xmlFileNamePath) throws IOException {
ClassPathResource
classPathResource =
new ClassPathResource(xmlFileNamePath);
Source
requestSource =
new ResourceSource(classPathResource);
StringResult
result =
new StringResult();
getWebServiceTemplate().
sendSourceAndReceiveToResult(
requestSource,
new WSSESecurityHeaderRequestWebServiceMessageCallback(),
result
);
}
notice WSSESecurityHeaderRequestWebServiceMessageCallback
define a
public class WSSESecurityHeaderRequestWebServiceMessageCallback implements WebServiceMessageCallback {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
try {
// Assumption: We are using the default SAAJWebMessageFactory
SaajSoapMessage
saajSoapMessage =
(SaajSoapMessage)message;
SOAPMessage
soapMessage =
saajSoapMessage.getSaajMessage();
SOAPPart
soapPart =
soapMessage.getSOAPPart();
SOAPEnvelope
soapEnvelope =
soapPart.getEnvelope();
SOAPHeader
soapHeader =
soapEnvelope.getHeader();
Name
headerElementName =
soapEnvelope.createName(
"Security",
"wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
);
// Add "Security" soapHeaderElement to soapHeader
SOAPHeaderElement
soapHeaderElement =
soapHeader.addHeaderElement(headerElementName);
// This may be important for some portals!
soapHeaderElement.setActor(null);
// Add usernameToken to "Security" soapHeaderElement
SOAPElement
usernameTokenSOAPElement =
soapHeaderElement.addChildElement("UsernameToken");
// Add username to usernameToken
SOAPElement
userNameSOAPElement =
usernameTokenSOAPElement.addChildElement("Username");
userNameSOAPElement.addTextNode("myUserName");
// Add password to usernameToken
SOAPElement
passwordSOAPElement =
usernameTokenSOAPElement.addChildElement("Password");
passwordSOAPElement.addTextNode("myPassword");
} catch (SOAPException soapException) {
throw new RuntimeException("WSSESecurityHeaderRequestWebServiceMessageCallback", soapException);
}
}
}
in this class feel free to change what you do with your header as you see fit and you're done...

Related

Springboot: redirect and reverse-proxy

I'm having a SpringBoot and SpringMVC internal application (internal meaning hidden from the internet by a firewall) and a public authentication (OAuth2) service in the DMZ.
I'm accessing the landing page from the from a client in the internal area.
This page has a login button. When I press it, I'm forwarding the client to the auth server (in the DMZ), that I can access only going through a proxy.
I tried setting the VM env variables:
-Dhttp.proxyHost=xx -Dhttp.proxyPort=yy -Dhttp.proxySet=true
and setting them in the System.properties
System.setProperty("http.proxyHost", "http://xx");
System.setProperty("http.proxyPort", "xx");
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
but both with no effect.
I also tried to define a SimpleClientHttpRequestFactory bean :
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="requestFactory"
class="org.springframework.http.client.SimpleClientHttpRequestFactory">
<property name="proxy">
<bean id="proxy" class="java.net.Proxy">
<constructor-arg>
<util:constant static-field="java.net.Proxy.Type.HTTP" />
</constructor-arg>
<constructor-arg>
<bean class="java.net.InetSocketAddress">
<constructor-arg value="xx" />
<constructor-arg value="yy" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
</beans>
without anymore success.
Question
How can I configure Spring to proxify my redirect ?
Thanks!
Got it work as follow (see restTemplateProxy)
private final String server = "xx";
private final int port = yy;
private final SimpleClientHttpRequestFactory clientHttpReq = new SimpleClientHttpRequestFactory();
private final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
private RestTemplate restTemplateProxy = null;
{
clientHttpReq.setProxy(proxy);
restTemplateProxy = new RestTemplate(clientHttpReq);
}
#RequestMapping(value = "getLightToken", method = RequestMethod.GET)
private String getLightToken(Model model) throws JsonProcessingException, IOException {
/* Header */
headers.clear();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
/* Body */
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add(CLIENT_ID.key, CLIENT_ID.val);
body.add(CLIENT_SECRET.key, CLIENT_SECRET.val);
body.add(GRANT_TYPE.key, GRANT_TYPE.val);
body.add(SCOPE.key, SCOPE.val);
/* Set the body and header of the request */
HttpEntity<?> request = new HttpEntity<>(body, headers);
/* Request Authorisation */
ResponseEntity<String> response = restTemplateProxy.exchange(BASE_URL + TOKEN_URI, HttpMethod.POST, request, String.class);
return response.getBody();
}

Can I have the XML in the log when sending FastInfoset request with Apache CXF?

I need to to have the requests and responses in the logs of the application but the requests sent by Apache CXF are in FastInfoset (Content-Type: application/fastinfoset) which results in the log of the request and response being unreadable (since it's binary). Is there a way around that so that I keep FastInfoset messages (for performance reasons) but I get proper XML in the logs?
Here is the CXF configuration I have right now, if that helps:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="logInbound" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="logOutbound" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="logOutbound" />
</cxf:outFaultInterceptors>
<cxf:inFaultInterceptors>
<ref bean="logInbound" />
</cxf:inFaultInterceptors>
</cxf:bus>
</beans>
Thank you in advance for any help.
I have taken a look at LoggingInInterceptor.logInputStream and it seems that it does not support fastinfoset. But you can use a custom interceptor instead of LoggingInInterceptor and LoggingOutInterceptor to extract the payload, decode it, and log the original message.
public class CustomInterceptor extends AbstractPhaseInterceptor<Message> {
public CustomInterceptor () {
super(Phase.RECEIVE);
}
public void handleMessage(Message message) {
//Get the message body into payload[] and set a new non-consumed inputStream into Message
InputStream in = message.getContent(InputStream.class);
byte payload[] = IOUtils.readBytesFromStream(in);
ByteArrayInputStream bin = new ByteArrayInputStream(payload);
message.setContent(InputStream.class, bin);
//Decode from FastInfoset and write the payload in your preferred log system
OutputStream out = System.out
decodeFI(in,out);
}
public void handleFault(Message messageParam) {
//Invoked when interceptor fails
//Exception e = message.getContent(Exception.class);
}
}
Replace in the XML file
<bean id="logInbound" class="test.CustomInterceptor" />
<bean id="logOutbound" class="test.CustomInterceptor" />
Finding an example of how to decode a FastInfoset has not been easy. Try this using DOM and FastInfoset-1.2.12.jar. In this repo you have several examples using sTAX and SAX
public void decodeFI(InputStream in, OutputStream out) throws Exception{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
DOMDocumentParser parser = new DOMDocumentParser();
parser.parse(doc, in);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(out);
transformer.transform(source, result);
}

send a message using freemarker

I need to send a letter with the body:
Lector {LectorName} had created a new course
----------------------------------------------------
Name: {CourseName}
Category: {CourseCategory}
Description: {CourseDescription}
Links: {CourseLinks}
----------------------------------------------------
Please, review this course at {CourseApproveLink}
I made on a page freemarker
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<p> ${LectorName} had created a new course</p>
<p>----------------------------------------------------</p>
<p>Name: ${Course.title}</p>
<p>Category: ${Course.category.name}</p>
<p>Description: ${Course.descr}</p>
<p>Links: ${Course.links}</p>
<p>----------------------------------------------------</p>
<p>Please, review this course at ${CourseApproveLink}</p>
</body>
</html>
how to fill it and pass the values in the method of sending the letter?
Here is my code. My method sendMail and Bean "mailSender" with my settings.
It is necessary to do so new MimeMessage(session) ?
How do I get the settings from the bean into the session?
#Service("mailService")
public class MailService {
#Autowired
private MailSender mailSender;
#Autowired
private SimpleMailMessage alertMailMessage;
#Resource(name = "freemarkerEmailConfig")
private Configuration emailConfiguration;
public void sendMail(String from, String to, String subject, String body) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(body);
mailSender.send(message);
}
public void sendAlertMail(String alert) {
SimpleMailMessage mailMessage = new SimpleMailMessage(alertMailMessage);
mailMessage.setText(alert);
mailSender.send(mailMessage);
}
}
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.mail.ru" />
<property name="port" value="465" />
<property name="username" value="user#mail.ru" />
<property name="password" value="***********" />
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.ssl.enable">true</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="alertMailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from">
<value>dima4nolimit#mail.ru</value>
</property>
<property name="to">
<value>bizanrus#mail.ru</value>
</property>
<property name="subject"
value="Alert - Exception occurred. Please investigate" />
</bean>
You need to pass in a map to the method that sends email with freemarker template. In your case the map will look something like:
Map<Object, Object> map = new HashMap<Object, Object>();
map.put("LectorName", "...");
map.put("Course", course);
map.put("CourseApproveLink", "...");
Freemarker will resolve variable names based on the keys you passed in.
If you use Spring, then configure the template directory in applicationContext.xml like this:
<!-- FreeMarker Configuration -->
<bean id="freemarkerEmailConfig" class="freemarker.template.Configuration">
<property name="directoryForTemplateLoading" value="templates/email" />
<property name="objectWrapper">
<bean class="freemarker.template.DefaultObjectWrapper"/>
</property>
</bean>
Put your template under templates/email folder (relative to your webapp). Inject the freemarkerEmailConfig bean defined in applicationContext into your service class:
#Resource(name = "freemarkerEmailConfig")
private Configuration emailConfiguration;
Now in your service class you can use emailConfiguration to retrieve the template and then process it with the map above like this:
Template template = emailConfiguration.getEmailTemplate(templateName);
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
FreeMarkerTemplateUtils is a class from Spring. Now text will contain the html with the all the variables substituted by values from the map. Just send the email with text as html content:
MimeMessage msg = mailSender.createMimeMessage();
msg.setFrom(new InternetAddress(EMAIL_SENDER_ADDRESS, EMAIL_SENDER_PERSONAL));
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setContent(text, "text/html; charset=UTF-8");
for (EmailInternetAddress emailInternetAddress :emailInternetAddresses) {
msg.addRecipient(emailInternetAddress.getRecipientType(),
emailInternetAddress.getInternetAddress());
}
mailSender.send(msg);

Create listener using Spring Rabbit MQ for publisher returns

I am trying to create a listener using spring-amqp(RabbitMQ) that supports publisher returns. I couldn't find any example for this case, but I tried to do the following:
#Component
public class ImportModelHandler {
#Autowired
private ModelService modelService;
public byte[] handleMessage(byte[] file) throws Exception {
try {
if (file == null || file.length == 0) {
throw new IllegalArgumentException("File is empty");
}
return ModelService.OBJECT_MAPPER.writeValueAsBytes(
modelService.importModel(file));
} catch (Exception e) {
return ModelService.OBJECT_MAPPER.writeValueAsBytes(Response.createErrorResponse(e));
}
}
}
Xml configuration:
<bean id="importModelListener"
class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="importModelHandler"/>
</bean>
<rabbit:connection-factory id="connectionFactory" host="192.168.1.50" port="5672" username="guest" password="guest"
publisher-returns="true"/>
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:queue name="import.model"/>
<rabbit:queue name="download.model"/>
<bean id="rabbitListenerContainerFactory"
class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="concurrentConsumers" value="3"/>
<property name="maxConcurrentConsumers" value="10"/>
</bean>
<rabbit:annotation-driven container-factory="rabbitListenerContainerFactory"/>
<rabbit:direct-exchange name="import.model.exchange">
<rabbit:bindings>
<rabbit:binding queue="import.model"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<rabbit:listener-container
connection-factory="connectionFactory">
<rabbit:listener ref="importModelListener" queue-names="import.model"/>
</rabbit:listener-container>
Then I tried to create code for calling this listener:
URL resource = ImportModelTest.class.getResource("/models/model.jar");
File file = new File(resource.toURI());
byte[] bytes = IOUtils.toByteArray(new FileInputStream(file));
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_BYTES);
Message message = new Message(bytes, messageProperties);
rabbitTemplate.convertAndSend("import.model", message);
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
#Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println(new String(message.getBody()));
}
});
But I have got:
org.springframework.amqp.AmqpException: Cannot determine ReplyTo
message property value: Request message does not contain reply-to
property, and no default response Exchange was set.
How could I create a listener that will use Publisher Returns mechanism?

SoapEnvelopeLoggingInterceptor: how log client remote URL

I have a custom SoapEnvelopeLoggingInterceptor to log the soap envelope of the ws service calls using a transformer.
Is there a way to log the remote URL of the call in this class? (ex. ip address)
The best is to manipulate something like HttpServletRequest.
In context I have:
<sws:interceptors>
<bean id="envelopeLoggingInterceptor" class="path.to.my.CustomSoapEnvelopeLoggingInterceptor">
<property name="loggerName" value="myLogger" />
<property name="logRequest" value="true" />
<property name="logResponse" value="true" />
<property name="logFault" value="true" />
</bean>
</sws:interceptors>
My CustomSoapEnvelopeLoggingInterceptor:
public class CustomSoapEnvelopeLoggingInterceptor extends SoapEnvelopeLoggingInterceptor {
#Override
protected void logMessageSource(String message, Source source) throws TransformerException {
if (source != null){
Transformer trf = this.getTransformerFactory().newTransformer();
trf.setOutputProperty(OutputKeys.INDENT, "yes");
trf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
StringWriter writer = new StringWriter();
StreamResult stream = new StreamResult(writer);
trf.transform(source, stream);
writer.flush();
this.logger.debug(message + stream.getWriter().toString());
}
}
}

Categories

Resources