有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法打印来自SOAP Web服务的XML响应

我无法打印来自Soap Web服务的响应

通过编辑生成的存根代码看到了一些解决方案。但是我不能编辑生成的代码,因为它在每次构建时都会恢复为原始形式。寻找一个解决方案,我可以得到解决方案打印而不改变生成的代码

我正在使用Spring Boot微服务中的SOAP服务

ServiceContext serviceConxt = omsSchedulingService._getServiceClient().getServiceContext();
        OperationContext operationContext = serviceConxt.getLastOperationContext();
MessageContext inMessageContext = operationContext.getMessageContext("Out");
log.info(inMessageContext.getEnvelope().toString());

共 (3) 个答案

  1. # 1 楼答案

    首先,您可以从客户端存根获取AxisConfiguration

    AxisConfiguration axisConf = stub._getServiceClient().getAxisConfiguration();
    

    处理传入和传出消息分为几个阶段。有一个阶段列表(一个流程),当一切正常(无错误)时进行处理,也有另一个阶段列表用于发生某些故障的情况,例如在消息处理过程中引发异常。每个流可能传入或传出,因此总共有4个流

    List<Phase> phasesIn = axisConf.getInFlowPhases(); // normal incoming communication i.e. response from webservice
    List<Phase> phasesOut = axisConf.getOutFlowPhases(); // normal outgoing communication
    List<Phase> phasesFaultIn = axisConf.getInFaultFlowPhases(); // faulty incoming communication e.g. when an exception occurs during message processing
    List<Phase> phasesFaultOut = axisConf.getOutFaultFlowPhases(); // faulty outgoing communication
    

    组织中定义了一些但不是所有的阶段名称。阿帕奇。axis2。相位解算器。PhaseMetadata。 例如,Rampart模块(Web服务安全模块)中处理的“安全”阶段在PhaseMetadata中找不到。 您可以向每个阶段添加处理程序,例如

    for (Phase p : phasesOut) {
        if (PhaseMetadata.PHASE_TRANSPORT_OUT.equals(p.getName())) {
            p.addHandler(new MessageContentLoggerHandler());
        }
    }
    

    Handler是一个扩展org的类。阿帕奇。axis2。处理程序。AbstractHandler。 你只需要实施

    public InvocationResponse invoke(MessageContext msgContext).
    

    在这里,您可以访问MessageContext。当然,您可以像这样获得整个SOAP信封:

    msgContext.getEnvelope().toString()
    

    例如,将其打印到日志或另存为单独的文件。 记得把

    return InvocationResponse.CONTINUE;
    

    在处理程序成功处理消息的情况下的invoke方法末尾。否则,处理将在此处理程序中停止,整个进程将无法进入任何其他阶段。 如果需要使用WSS头查看整个消息,可以添加自己的阶段。例如,这会将自定义阶段添加为传出消息的最后一个处理阶段(Rampart的安全阶段之后也是如此)

    Phase phase = new Phase("SomePhase");
    phase.addHandler(new SomeCustomHandler());
    axisConf.getOutFlowPhases().add(phase);
    

    当然,在生产环境中记录(并以任何其他方式公开)安全头是一个非常糟糕的主意。仅在某些测试环境中出于调试目的执行此操作

  2. # 2 楼答案

    如果您不想实现拦截器,最简单的方法是通过vm参数使用日志记录:

    JAVA_OPTS=-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog -Dorg.apache.commons.logging.simplelog.showdatetime=true -Dorg.apache.commons.logging.simplelog.log.httpclient.wire=debug -Dorg.apache.commons.logging.simplelog.log.org.apache.commons.httpclient=debug
    

    这样,您应该可以在控制台中看到带有标题的请求/响应日志

  3. # 3 楼答案

    您可以为soap消息添加消息处理程序

    然后,一旦使用处理程序截获消息,就可以打印出响应

    您将需要将处理程序添加到处理程序链中,这取决于您的项目,您可以通过编程或配置来完成

    final class MyMessageHandler implements SOAPHandler<SOAPMessageContext>{
    
    
    @Override
    public void close(MessageContext context) {
        handle(context);
    }
    
    private boolean handle(MessageContext context) {
        if (context != null) {
            try {
                Object httpResponseCodeObj = context.get(SOAPMessageContext.HTTP_RESPONSE_CODE);
    
                if (httpResponseCodeObj instanceof Integer)
                    httpResponseCode = ((Integer) httpResponseCodeObj).intValue();
    
                if (context instanceof SOAPMessageContext) {
                    SOAPMessage message = ((SOAPMessageContext) context).getMessage();
                    ByteArrayOutputStream byteOut = new ByteArrayOutputStream(512);
                    message.writeTo(byteOut);
                    String messageStr = byteOut.toString(getCharacterEncoding(message));
    
                    boolean outbound = Boolean.TRUE.equals(context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY));
    
    
                    Logger.info(loggingPrefix, outbound ? "SOAP request: " : "SOAP response: ", replaceNewLines(messageStr));
                }
    
            } catch (SOAPException e) {
                Logger.error(e, loggingPrefix, "SOAPException: ", e.getMessage(), NEWLINE);
            } catch (IOException e) {
                Logger.error(e, loggingPrefix, "IOException: ", e.getMessage(), NEWLINE);
            }
        }
    
        return true;
    }
    

    }