CXF使用内容过滤或屏蔽soap字段记录请求和响应
我想通过内容过滤记录来自某个特定端点的所有传入请求和响应。 即当我有这样的要求时:
Apples Photo with some apples in it anVzdCBhIHJhbmRvbSB0ZXh0DQpqdXN0IGEgcmFuZG9tIHRleHQNCmp1c3QgYSByYW5kb20gdGV4dA0KanVzdCBhIHJhbmRvbSB0ZXh0DQpqdXN0IGEgcmFuZG9tIHRleHQNCmp1c3QgYSByYW5kb20gdGV4dA0KanVzdCBhIHJhbmRvbSB0ZXh0DQp3b3csIGkgZGlkbid0IHRob3VnaHQgdGhhdCBhbnlvbmUgd291bGQgYmUgaW50ZXJlc3RlZCBpbiBkZWNvZGluZyB0aGlzLiBjb25ncmF0cyE=
我想过滤它,以便它看起来像这样的日志
Apples Photo with some apples in it hidden
或完全删除m:照片元素。
我发现CXF有一些LoggingInInterceptor和LoggingOutInterceptor,我可以编写自己的拦截器来做到这一点。 然而,这将是一项工作要做,所以我的问题是:你知道更好,开箱即用的解决方案吗?
我有类似的问题,我需要在输入请求中屏蔽密码。 我对现有的LogginInterceptor和重写格式方法做了一些小改动,并添加了我的方法来掩盖密码。 这是一个例子
public class CustomLogInInterceptor extends LoggingInInterceptor { @Override protected String formatLoggingMessage(LoggingMessage loggingMessage) { String str = loggingMessage.toString(); String output = maskPasswords(str); return(output); } private String maskPasswords(String str) { final String[] keys = { "password", "passwords" }; for (String key : keys) { int beginIndex = 0; int lastIndex = -1; boolean emptyPass = false; while (beginIndex != -1 && (beginIndex = StringUtils.indexOfIgnoreCase(str, key, beginIndex)) > 0) { beginIndex = StringUtils.indexOf(str, ">", beginIndex); if (beginIndex != -1) { char ch = str.charAt(beginIndex - 1); if (ch == '/') { emptyPass = true; } if (!emptyPass) { lastIndex = StringUtils.indexOf(str, "<", beginIndex); if (lastIndex != -1) { String overlay = "*"; String str2 = StringUtils.substring(str, beginIndex + 1, lastIndex); if (str2 != null && str2.length() > 1) { overlay = StringUtils.rightPad(overlay, str2.length(), "*"); str = StringUtils.overlay(str, overlay, beginIndex + 1, lastIndex); } } } if (emptyPass) { emptyPass = false; lastIndex = beginIndex + 1; } else { if (lastIndex != -1) { lastIndex = StringUtils .indexOf(str, ">", lastIndex); } } } beginIndex = lastIndex; } } return str; } }
并在我的cxf-bean.xml中添加了custtom cxf logging bean
注意我已经使用Apache commons-lang3 jar进行字符串操作。 同样,您也可以使用响应
UPDATE
使用模式并使用属性使密钥可配置。
拦截器
public class CustomLogInInterceptor extends LoggingInInterceptor { private static final String MASK_PATTERN = "<\\s*{}\\s*>(.*)\\s*{}\\s*>|<\\s*name\\s*>\\s*{}\\s*\\s*name\\s*>\\s*<\\s*value\\s*>(.*)<"; private Pattern pattern; private String[] keys; public void init() { StringBuilder builder = new StringBuilder(); for (String str : keys) { builder.append(MASK_PATTERN.replace("{}", str)); builder.append("|"); } builder.setLength(builder.length()-1); pattern = Pattern.compile(builder.toString(), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); } public void setKeys(String[] keys) { this.keys = keys; } @Override protected String formatLoggingMessage(LoggingMessage loggingMessage) { String output = maskPasswords(loggingMessage.toString()); return(output); } private String maskPasswords(String str) { Matcher matcher = pattern.matcher(str); final StringBuilder builder = new StringBuilder(str); while (matcher.find()) { int group = 1; while (group <= matcher.groupCount()) { if (matcher.group(group) != null) { for (int i = matcher.start(group); i < matcher.end(group); i++) { builder.setCharAt(i, '*'); } } group++; } } return builder.toString(); } }
豆创作
password accountId
样本输入
adffas dfsdf sdfsfs sdfsfsf 3434 password sdfsfs password 123456 sdfsfs
和输出
adffas dfsdf ****** sdfsfsf **** password ****** password ****** ******
我编写了一个开源库,旨在有效地打印SOAP消息: xml-formatter-components-cxf 。 function包括:
- XML的高性能重新格式化
- 高级过滤选项
- 最大文本和/或CDATA节点大小
- 在文本和/或CDATA节点中重新格式化XML
- 匿名化元素和/或属性内容
- 删除子树
弹簧的完整配置参考 。
编辑:上面的库已经被重构为更通用的库 ,这对于大多数正常的用例来说可能更好,即没有用XML包装的XML。