当前位置: 首页 > 面试题库 >

CXF记录请求和响应以及内容过滤或掩盖肥皂字段

申屠弘图
2023-03-14
问题内容

我想记录来自某个特定端点的所有传入请求和响应,并进行内容过滤。即当我有这样的要求时:

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
  <m:ProcessPhoto xmlns:m="http://www.w3schools.com/photos">
    <m:Name>Apples</m:Name>
    <m:Description>Photo with some apples in it</m:Description>
    <!-- large encoded binary below -->
    <m:Photo>anVzdCBhIHJhbmRvbSB0ZXh0DQpqdXN0IGEgcmFuZG9tIHRleHQNCmp1c3QgYSByYW5kb20gdGV4dA0KanVzdCBhIHJhbmRvbSB0ZXh0DQpqdXN0IGEgcmFuZG9tIHRleHQNCmp1c3QgYSByYW5kb20gdGV4dA0KanVzdCBhIHJhbmRvbSB0ZXh0DQp3b3csIGkgZGlkbid0IHRob3VnaHQgdGhhdCBhbnlvbmUgd291bGQgYmUgaW50ZXJlc3RlZCBpbiBkZWNvZGluZyB0aGlzLiBjb25ncmF0cyE=</m:Photo>
  </m:ProcessPhoto>
</soap:Body>
</soap:Envelope>

我想过滤它,以便它看起来像这样的日志

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
  <m:ProcessPhoto xmlns:m="http://www.w3schools.com/photos">
    <m:Name>Apples</m:Name>
    <m:Description>Photo with some apples in it</m:Description>
    <m:Photo>hidden</m:Photo>
  </m:ProcessPhoto>
</soap:Body>
</soap:Envelope>

或完全删除了m:Photo元素。

我发现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日志记录bean

<bean id="kpInInterceptor" class="com.kp.util.CustomLogInInterceptor" />

<cxf:bus>
        <cxf:inInterceptors>
            <ref bean="kpInInterceptor" />
        </cxf:inInterceptors>
        <cxf:inFaultInterceptors>
            <ref bean="kpInInterceptor" />
        </cxf:inFaultInterceptors>
</cxf:bus>

注意 我已经使用Apache commons-lang3 jar来进行String操作。同样,您也可以将其用于响应

更新

使用模式并使用属性使键可配置。

拦截器

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();

    }

}

豆创作

<bean id="kpInInterceptor" class="com.kp.util.CustomLogInInterceptor" init-method="init">
    <property name="keys">
        <array value-type="java.lang.String">
            <value>password</value>
            <value>accountId</value>
        </array>
    </property>
</bean>

样本输入

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <hello>adffas</hello>
    <vsdsd>dfsdf</vsdsd>
    <password>sdfsfs</password>
    <sdfsfsf>sdfsfsf</sdfsfsf>
    <password>3434</password>
    <name>password</name>
    <value>sdfsfs</value>
    <password />
    <name>password</name>
    <value />
    <accountId>123456</accountId>
    <hello>
        <inner1>
            <password>
                <password>sdfsfs</password>
            </password>
        </inner>
    </hello>
</test>

和输出

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <hello>adffas</hello>
    <vsdsd>dfsdf</vsdsd>
    <password>******</password>
    <sdfsfsf>sdfsfsf</sdfsfsf>
    <password>****</password>
    <name>password</name>
    <value>******</value>
    <password />
    <name>password</name>
    <value />
    <accountId>******</accountId>
    <hello>
        <inner1>
            <password>
                <password>******</password>
            </password>
        </inner>
    </hello>
</test>


 类似资料:
  • 我使用apache cxf编写了一个示例soap服务项目,并在此应用程序中使用log4j with进行日志记录。我可以将soap原始请求和响应记录到服务器控制台,但无法将其记录到日志文件或stingBuilder。和我的cxf bean。像这样的xml ** 客户端类 记录器。信息(“请求”客户端。getInInterceptors()。添加(new LoggingInInterceptor())

  • 我想通过REST API(最好使用Python或Java)发出请求。然而,我想过滤掉结果,因为我不想从响应中得到所有信息。例如,我只需要文本。作为初学者,我很难取得成功。到目前为止,我只在Python上用库“requests”完成了一个请求。有人能帮我吗?

  • 我试图记录应用程序中的每个传入请求和传出响应。我正在使用jee 6,所以我没有ContainerRequestFilter和ContainerResponseFilter类。所以我决定用滤镜。 我用@WebFilter(“/*”)注释了一个类,并实现了Filter接口。我成功地读取了请求头和请求正文。我也很难阅读响应标题和响应正文。下面是代码片段 MyHttpServletResponse seW

  • 我想使用 wsdl 文件从 Camel 调用第三方网络服务,而无需生成任何客户端代码(因为我认为如果我提供 wsdl 文件,那么 Camel 能够生成我们之前生成的客户端,并且在我们的旧代码中工作) 经过长时间的搜索,我找到了一些帮助我实现目标的代码 代码为 这工作正常,但这里我是手动生成soap信封 wsdl文件是 现在我想生成肥皂请求,而不是静态的 请帮助我 先谢谢了

  • 我正在使用CamelCXFendpoint连接到我的soap服务器。我想为客户端的请求添加超时。我正在为此使用continuationTimeout选项。但它不起作用。请求超时,而不等待我配置的时间。 下面是我的endpoint配置。

  • 我想通过REST API(最好使用Python或Java)发出请求。然而,我想过滤掉结果,因为我不想从响应中得到所有信息。例如,我只需要文本。作为初学者,我很难取得成功。到目前为止,我只在Python上用库“requests”完成了一个请求。有人能帮我吗?