java—将数据从soap处理程序传递到webservice服务器类

vngu2lb8  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(399)

我有一个带有cxf的spring boot soap服务,我的消费者正在http头中向我传递sso令牌。。我能够使用jax-ws处理程序检索sso令牌。我将sso令牌保存到处理程序类级别的变量中,在控制遍历各个类之后,它会到达一个点,即我必须向另一个服务发出请求,并且必须传递相同的sso令牌,但在我的连接类中,sso令牌值为空。

@Component
public class EndPointHandler implements SOAPHandler<SOAPMessageContext> {
    private List<String> ssoToken;
    private Map<String, List<String>> headers;

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isResponse = (Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (!isResponse) {
            headers = ((Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS));
            if (headers != null) {
                if (!headers.get("SSOToken").get(0).isEmpty()) {
                    List<String> ssoToken = headers.get("SSOToken");
                    LOGGER.info(ssoToken.get(0));
                    this.ssoToken = ssoToken;
                } else {
                    LOGGER.error("SSO Token value cannot be empty");
                    return false;
                }
            }
        }
        return true;
    }

    public void setSSOToken() {
        headers.put("SSOToken", this.ssoToken);
    }
}

在我的连接类中,我必须将这个sso令牌设置为头并调用另一个服务,但是sso令牌值为null。
连接等级:

@Component
public class ConnectionManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class);

    @Autowired
    private EndPointHandler handler;

    private void establishConnection(String uri) throws FileNetIntegrationException {
        handler.ssoToken; //  --> I need SSO token here but the value is NULL;
    }
}

以下是我在webserviceconfig类中设置处理程序链的方式:

@Bean
public Endpoint endpoint(Bus bus) {
    EndpointImpl endpoint = new EndpointImpl(bus, changeServiceEndpoint);
    WebService ws = AnnotationUtils.findAnnotation(endpoint.getImplementorClass(), WebService.class);
    endpoint.setAddress("/" + ws.serviceName());
    endpoint.publish();
    SOAPBinding binding = (SOAPBinding) endpoint.getBinding();
    ArrayList<Handler> handlerChain = new ArrayList<>();
    handlerChain.add(new EndPointHandler());
    binding.setHandlerChain(handlerChain);
    return endpoint;
}
xbp102n0

xbp102n01#

我想,在这里发布了最后一段代码之后,我发现在将其添加到处理程序链时使用了new endpointhandler(),就找到了一个解决方案。。我试着用自动连线,它为我工作。

o3imoua4

o3imoua42#

据我所知, jax-ws 上下文和 spring-ws 上下文不相交。所以这不是一个解决方案,而是一个变通方法。作为另一种解决方法,您可以使用一些单例 synchronizedMap ,或使用
jax-ws Handler 使用扩展api将请求重定向到另一个端点。

使用jax-ws处理程序访问soap消息的http头

如果您已配置 SOAPHandler 为了你的
JAX-WS WebService ,然后可以访问http头并在 SOAPBody 作为世界的田野 SOAPElement 类型,反之亦然。为此,您必须使用注解为 XmlElement . 然后你可以从你的 WebService .
注意:如果您有一个基于java类的动态生成的wsdl模式,那么它也会改变。但是无论如何,旧的请求和响应都会被接受,因为这些字段在默认情况下不是必需的。
例子: UserService -传入消息有一个字段 String 类型和传出消息有一个字段 int 类型。让我们用一个来扩展它们 ssoToken 领域 String 类型。我们将从传入消息的http头读取此令牌,并将其发送回传出消息的http头中。
getuserrequest.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement(name = "getUserRequest")
public class GetUserRequest {
    @XmlElement
    protected String ssoToken;
    @XmlElement(required = true)
    protected String name;

    // getters + setters + constructor
}

getuserresponse.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement(name = "getUserResponse")
public class GetUserResponse {
    @XmlElement
    protected String ssoToken;
    @XmlElement(required = true)
    protected int age;

    // getters + setters + constructor
}

userservicehandler.java

public class UserServiceHandler implements SOAPHandler<SOAPMessageContext> {
    @Override
    public boolean handleMessage(SOAPMessageContext soapMessageContext) {
        Boolean isResponse =
                (Boolean) soapMessageContext
                        .get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (!isResponse) {
            // Request message
            return processIncomingMessage(soapMessageContext);
        } else {
            // Response message
            return processOutgoingMessage(soapMessageContext);
        }
    }
}

处理输入消息:

@SuppressWarnings("unchecked")
private boolean processIncomingMessage(SOAPMessageContext soapMessageContext) {
    Map<String, List<String>> headers =
            ((Map<String, List<String>>) soapMessageContext
                    .get(MessageContext.HTTP_REQUEST_HEADERS));
    if (headers == null || headers.isEmpty()) {
        return false;
    }
    List<String> ssoTokens = headers.get("SSOToken");
    if (ssoTokens == null || ssoTokens.size() != 1) {
        return false;
    }
    String ssoToken = ssoTokens.get(0);
    if (ssoToken == null || ssoToken.isEmpty()) {
        return false;
    }
    try {
        Iterator<Node> iterator =
                soapMessageContext.getMessage().getSOAPBody().getChildElements();
        while (iterator.hasNext()) {
            Node element = iterator.next();
            if (element.getNodeName().contains("getUserRequest")) {
                ((SOAPElement) element)
                        .addChildElement("ssoToken", element.getPrefix())
                        .setTextContent(ssoToken);
            }
        }
    } catch (SOAPException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

ProcessOutgoing消息:

@SuppressWarnings("unchecked")
private boolean processOutgoingMessage(SOAPMessageContext soapMessageContext) {
    Map<String, List<String>> headers =
            ((Map<String, List<String>>) soapMessageContext
                    .get(MessageContext.HTTP_RESPONSE_HEADERS));
    if (headers == null || headers.isEmpty()) {
        soapMessageContext
                .put(MessageContext.HTTP_RESPONSE_HEADERS, new HashMap<>());
        headers = ((Map<String, List<String>>) soapMessageContext
                .get(MessageContext.HTTP_RESPONSE_HEADERS));
    }
    try {
        Iterator<Node> iterator = soapMessageContext
                .getMessage().getSOAPBody().getChildElements();
        while (iterator.hasNext()) {
            Node element = iterator.next();
            if (element.getNodeName().contains("getUserResponse")) {
                Iterator<Node> iteratorResponse =
                        ((SOAPElement) element).getChildElements();
                while (iteratorResponse.hasNext()) {
                    Node childElement = iteratorResponse.next();
                    if (childElement.getNodeName().contains("ssoToken")) {
                        String ssoToken = childElement.getTextContent();
                        headers.put("SSOToken",
                                Collections.singletonList(ssoToken));
                        element.removeChild(childElement);
                    }
                }
            }
        }
    } catch (SOAPException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

用户服务.java

@WebService(endpointInterface = "com.example.UserPort",
        serviceName = "UserService")
@HandlerChain(file="handler-chain.xml")
public class UserService implements UserPort {
    public GetUserResponse getUser(GetUserRequest request) {
        GetUserResponse response = new GetUserResponse();
        response.setAge(23);
        response.setSsoToken(request.getSsoToken());
        return response;
    }
}

使用soapui进行测试:
请求标头:

POST http://localhost:8080/ws/userService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
SSOToken: 6cd506ac-738a-43ca-aee8-d13b78180605
Content-Length: 296
Host: localhost:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

请求消息:

<soapenv:Envelope
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:spr="http://example.com/jax-ws-sample">
    <soapenv:Header/>
    <soapenv:Body>
        <spr:getUserRequest>
            <spr:name>John</spr:name>
        </spr:getUserRequest>
    </soapenv:Body>
</soapenv:Envelope>

响应标头:

HTTP/1.1 200 
SSOToken: 6cd506ac-738a-43ca-aee8-d13b78180605
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 27 Aug 2020 15:54:33 GMT
Keep-Alive: timeout=20
Connection: keep-alive

响应消息:

<S:Envelope 
        xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <S:Body>
        <getUserResponse xmlns="http://example.com/jax-ws-sample">
            <age>23</age>
        </getUserResponse>
    </S:Body>
</S:Envelope>

相关问题