Last active
June 3, 2022 00:47
-
-
Save m-cakir/9112f0bd5442c28995f47433818ce3af to your computer and use it in GitHub Desktop.
Apache CXF - Interceptor Example (Inbound/Outbound Message)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* | |
* | |
* | |
* | |
<bean class="com.interceptor.ResponseTimeInInterceptor" id="responseTimeInInterceptor"/> | |
<bean class="com.interceptor.LoggingOutInterceptor" id="loggingOutInterceptor"> | |
<property name="ignoredStatusCodes" value="200,504,505"/> | |
</bean> | |
<jaxws:endpoint ...> | |
<jaxws:outInterceptors> | |
<ref bean="loggingOutInterceptor"/> | |
</jaxws:outInterceptors> | |
<jaxws:inInterceptors> | |
<ref bean="responseTimeInInterceptor"/> | |
</jaxws:inInterceptors> | |
</jaxws:endpoint> | |
* | |
* | |
* | |
* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com; | |
import java.lang.reflect.Method; | |
import java.util.List; | |
import javax.servlet.http.HttpServletRequest; | |
import org.apache.cxf.interceptor.Fault; | |
import org.apache.cxf.message.Message; | |
import org.apache.cxf.phase.AbstractPhaseInterceptor; | |
import org.apache.cxf.phase.Phase; | |
import org.apache.cxf.service.model.MessageInfo; | |
import org.apache.cxf.transport.http.AbstractHTTPDestination; | |
public class LoggingOutInterceptor2 extends AbstractPhaseInterceptor<Message> { | |
private String[] ignoredStatusCodes; | |
public LoggingOutInterceptor2() { | |
super(Phase.PRE_STREAM); | |
} | |
@Override | |
public void handleMessage(Message message) throws Fault { | |
LogBean log = new LogBean(); | |
try { | |
Message incomingMessage = message.getExchange().getInMessage(); | |
log.setMethod(getOperationName(incomingMessage)); | |
log.setIp(getIp(incomingMessage)); | |
setRequestResponseTime(log, incomingMessage); | |
setRequestParams(log, incomingMessage); | |
setResponseParams(log, message); | |
} catch (Throwable e) { | |
} | |
try { | |
log.setInstanceName("Instance Name"); | |
} catch(Exception e) { | |
} | |
if(!String.valueOf(log.getResult()).matches(getIgnoredStatusCodesMatchString())) { | |
// db insert log bean | |
} | |
} | |
public String getIgnoredStatusCodesMatchString() { | |
if(ignoredStatusCodes == null) { | |
ignoredStatusCodes = new String[] {}; | |
} | |
return "(" + join(ignoredStatusCodes, "|") + ")"; | |
} | |
public void setIgnoredStatusCodes(String[] ignoredStatusCodes) { | |
this.ignoredStatusCodes = ignoredStatusCodes; | |
} | |
private String getIp(Message context){ | |
HttpServletRequest request = (HttpServletRequest) context.get(AbstractHTTPDestination.HTTP_REQUEST); | |
String remoteIp = request.getRemoteAddr(); | |
String proxyIp = request.getHeader("X-Forwarded-For"); | |
if (proxyIp != null && proxyIp.trim().length() > 1){ | |
String forwardedIp = proxyIp; | |
String [] ipTokens = forwardedIp.split(","); | |
if(ipTokens != null && ipTokens.length > 1) forwardedIp = ipTokens[ipTokens.length -2].trim(); | |
return forwardedIp != null && forwardedIp.trim().length() > 1 ? remoteIp : forwardedIp; | |
} | |
return remoteIp; | |
} | |
private void setRequestResponseTime(LogBean log, Message incomingMessage) { | |
Long requestTime = (Long) incomingMessage.remove(ResponseTimeInInterceptor.REQUEST_TIME_KEY); | |
if (requestTime != null) { | |
log.setRequestTime(requestTime); | |
log.setResponseTime(System.currentTimeMillis()); | |
} | |
} | |
private void setRequestParams(LogBean log, Message incomingMessage) { | |
/* invoke method lists | |
* * * * * * * * * * * | |
* getters | |
* */ | |
if(incomingMessage == null) return; | |
if(log == null) log = new LogBean(); | |
final List inContents = incomingMessage.getContent(List.class); | |
for (final Object object : inContents) { | |
log.setRequest(object.toString()); | |
String userId = getMethodResult(object, "getUserId"); // example | |
log.setUserId(userId); | |
} | |
} | |
private void setResponseParams(LogBean log, Message outgoingMessage) { | |
/* invoke method list | |
* * * * * * * * * * * | |
* getStatusCode | |
* getStatusDesc | |
* */ | |
if(outgoingMessage == null) return; | |
if(log == null) log = new LogBean(); | |
final List outContents = outgoingMessage.getContent(List.class); | |
for (final Object object : outContents) { | |
Integer result = getMethodResult(object, "getStatusCode"); | |
log.setResult(result); | |
String response = getMethodResult(object, "getStatusDesc"); | |
log.setResponse(response); | |
} | |
} | |
private String getOperationName(Message inMessage) { | |
try { | |
MessageInfo mi = (MessageInfo) inMessage.get(MessageInfo.class.getName()); | |
return mi.getOperation().getInputName(); | |
} catch(Exception e) { | |
} | |
return null; | |
} | |
@SuppressWarnings("unchecked") | |
private <T> T getMethodResult(Object object, String methodName) { | |
try { | |
Method method = object.getClass().getMethod(methodName); | |
if(method != null) { | |
return (T) method.invoke(object); | |
} | |
} catch(Exception e) { | |
} | |
return null; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com; | |
import org.apache.cxf.interceptor.Fault; | |
import org.apache.cxf.message.Message; | |
import org.apache.cxf.phase.AbstractPhaseInterceptor; | |
import org.apache.cxf.phase.Phase; | |
public class ResponseTimeInInterceptor extends AbstractPhaseInterceptor<Message> { | |
public static final String REQUEST_TIME_KEY = "interceptor.request.time"; | |
public ResponseTimeInInterceptor() { | |
super(Phase.RECEIVE); | |
} | |
@Override | |
public void handleMessage(Message message) throws Fault { | |
message.put(REQUEST_TIME_KEY, System.currentTimeMillis()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like this technique. Leverages CXF message bus in fashion not cleanly possible in servlet/Spring model.
Thanks!