3

如何在集成服务器中为http-503请求服务不可用错误设置响应标头。由于它没有命中我的服务,我无法使用它pub.flow:setResponseHeader来设置标头。有什么办法可以让拦截器设置响应标头?

4

1 回答 1

2

Unfortunately there is no blessed public API for intercepting HTTP requests to Integration Server.

However you can use private APIs to do what you want, which is to return an HTTP 503 Service Unavailable response to an HTTP GET or POST request to a /invoke URL when the requested service doesn't exist.

The following is an example class which implements the com.wm.app.b2b.server.HTTPHandler interface, and processes HTTP requests to the /invoke directive. If the requested service exists, the HTTP request is passed on to the built-in Integration Server invoke handler com.wm.app.b2b.server.HTTPInvokeHandler to handle. If it doesn't exist, an HTTP response code and message of your choice is returned to the HTTP client.

import com.wm.app.b2b.server.AccessException;
import com.wm.app.b2b.server.BaseService;
import com.wm.app.b2b.server.HTTPDispatch;
import com.wm.app.b2b.server.HTTPHandler;
import com.wm.app.b2b.server.HTTPInvokeHandler;
import com.wm.app.b2b.server.ProtocolState;
import com.wm.app.b2b.server.ServerAPI;
import com.wm.app.b2b.server.ns.Namespace;
import com.wm.lang.ns.NSName;
import com.wm.util.Config;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * webMethods Integration Server HTTP invoke handler which returns a
 * custom HTTP response code and message when the invoked service does
 * not exist.
 */
public class MissingServiceResponseHandler implements HTTPHandler {
    private static final String DEFAULT_INVOKE_DIRECTIVE = "invoke";
    private static final String INVOKE_DIRECTIVE_CONFIG_KEY = "watt.server.invokeDirective";

    private int responseCode;
    private String responseMessage;
    private Set<String> directives;
    private Map<String, HTTPHandler> originalHandlers;
    private HTTPInvokeHandler invokeHandler;
    private boolean registered;

    /**
     * Constructs a new MissingServiceResponseHandler that returns the specified
     * HTTP response code and message when the invoked service does not exist.
     * @param responseCode      The HTTP response code returned when the invoked
     *                          service does not exist.
     * @param responseMessage   The HTTP response message returned when the invoked
     *                          service does not exist.
     */
    public MissingServiceResponseHandler(int responseCode, String responseMessage) {
        this.responseCode = responseCode;
        this.responseMessage = responseMessage;
        this.directives = getDirectives();
        this.originalHandlers = new TreeMap<String, HTTPHandler>();
        this.invokeHandler = new HTTPInvokeHandler();
        this.registered = false;
    }

    /**
     * Processes an HTTP request; called by the webMethods Integration Server HTTP request dispatcher.
     * @param  state           The HTTP request to be processed.
     * @return                 True if this object was able to process the HTTP request, otherwise false.
     * @throws IOException     If an I/O problem is encountered reading from or writing to the client socket.
     * @throws AccessException If the the HTTP request requires authentication or is not authorized.
     */
    @Override
    public final boolean process(ProtocolState state) throws IOException, AccessException {
        boolean result;

        String directive = getDirective(state);
        String path = state.getHttpRequestUrl().substring(directive.length());
        StringTokenizer tokenizer = new StringTokenizer(path, "/:");
        NSName serviceName = null;
        BaseService service = null;

        if (tokenizer.countTokens() > 1) {
            serviceName = NSName.create(tokenizer.nextToken(), tokenizer.nextToken());
            service = Namespace.getService(serviceName);
        }

        if (serviceName == null || service == null) {
            // service does not exist, to return custom response code and message
            state.setResponse(responseCode, responseMessage);
            result = true;
        } else {
            state.getInvokeState().setService(service);
            result = invokeHandler._process(state, ServerAPI.getContentHandler(state.getContentType()), serviceName);
        }

        return result;
    }

    /**
     * Returns the relevant directive that matches the given protocol state.
     * @param state The protocol state to resolve the directive against.
     * @return      The relevant directive that matches the given protocol state.
     */
    private String getDirective(ProtocolState state) {
        String directive = DEFAULT_INVOKE_DIRECTIVE;
        if (!state.getHttpRequestUrl().startsWith(directive)) {
            directive = Config.getProperty(DEFAULT_INVOKE_DIRECTIVE, INVOKE_DIRECTIVE_CONFIG_KEY);
        }
        return directive;
    }

    /**
     * Returns all the configured invoke directives for this Integration Server.
     * @return All the configured invoke directives for this Integration Server.
     */
    private static Set<String> getDirectives() {
        Set<String> directives = new TreeSet<String>();

        directives.add(DEFAULT_INVOKE_DIRECTIVE);

        String alternateDirective = Config.getProperty(DEFAULT_INVOKE_DIRECTIVE, INVOKE_DIRECTIVE_CONFIG_KEY);
        if (!DEFAULT_INVOKE_DIRECTIVE.equals(alternateDirective)) {
            directives.add(alternateDirective);
        }

        return directives;
    }

    /**
     * Registers this object as a handler for the invoke directives with the
     * Integration Server HTTP request dispatcher.
     */
    public synchronized void register() {
        if (!registered) {
            for (String directive : directives) {
                // save the original handler, so we can restore it later
                originalHandlers.put(directive, HTTPDispatch.getHandler(directive));
                // replace the original handler with this custom handler
                HTTPDispatch.addHandler(directive, this);
            }
            registered = true;
        }
    }

    /**
     * Unregisters this object as a handler of the invoke directives from the
     * Integration Server HTTP request dispatcher, and reinstates the original
     * handlers.
     */
    public synchronized void unregister() {
        if (registered) {
            for (String directive : directives) {
                // remove this custom handler from the dispatcher
                HTTPDispatch.removeHandler(directive);
                // then restore the original handler
                HTTPDispatch.addHandler(directive, originalHandlers.get(directive));
            }
            registered = false;
        }
    }
}

An example use of this class is as follows:

// create a new handler, specifying the desired HTTP response code and message
// returned when the requested service does not exist
MissingServiceResponseHandler handler = new MissingServiceResponseHandler(503, "Service Unavailable");

// register our custom handler with the Integration Server HTTP request dispatcher
handler.register();

// ...
// now all HTTP requests to the /invoke directive will be handled by our custom handler
// ...

// unregister our custom handler with the Integration Server HTTP request dispatcher, restoring the built-in invoke handler
handler.unregister();

// ...
// now all HTTP requests to the /invoke directive will revert to being handled by the built-in invoke handler
// ...
于 2015-07-11T02:34:26.317 回答