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