我採取了過濾方法,這就是我想出的。它似乎工作。
我已經包含了我的Filter
的doFilter
方法的代碼。我也寫了一個自定義HttpServletResponseWrapper
,但是這個實現非常簡單。
Apache reverse-proxy將x-forwarded-host
值添加到HTTP標頭(並且是我用來替換應用程序服務器名稱的名稱)。我想到的另一種選擇是將代理服務器的地址作爲應用服務器上的一個屬性,並抓住它。最終,我認爲這是一個更清潔的方式。
/*
* Replace the server URL with the proxy server URL when called from a proxy server
*/
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
WsdlResponseWrapper myResponse = new WsdlResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(request, myResponse);
boolean isResponseOutputStream = myResponse.getOutputStreamContent().length > 0;
/*
* The servlet response sent into this method only allows access to
* getOutputStream or getWriter, not both. It will throw an
* exception if an attempt is made to to access both.
*
* If this reason, I'm checking the output stream first and writing
* that content if it exists, then printing to the writer only if
* the output stream is empty.
*/
StringBuffer responseBuffer;
if (isResponseOutputStream) {
responseBuffer = new StringBuffer(new String(myResponse.getOutputStreamContent()));
} else {
responseBuffer = new StringBuffer(myResponse.getWriterContent());
}
// Change the URL when called from a proxy server
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestedHostname = httpServletRequest.getHeader("x-forwarded-host");
if ((null != requestedHostname) && !requestedHostname.isEmpty()) {
String myHostname = httpServletRequest.getHeader("host");
int myPort = httpServletRequest.getLocalPort();
// change the hostname
int index = responseBuffer.indexOf(myHostname);
int length = myHostname.length();
while (index > -1) {
responseBuffer.replace(index, index+length, requestedHostname);
index = responseBuffer.indexOf(myHostname);
}
// remove the port
String portString = ":" + myPort;
length = portString.length();
index = responseBuffer.indexOf(portString);
while (index > -1) {
responseBuffer.replace(index, index+length, "");
index = responseBuffer.indexOf(portString);
}
}
}
// forward the response
if (isResponseOutputStream) {
response.getOutputStream().write(responseBuffer.toString().getBytes());
} else {
response.getWriter().print(responseBuffer);
}
}
你有沒有試過在'@ WebService'註釋使用'wsdlLocation'屬性?你可以指定WSDL返回給客戶端。 – ewernli 2010-01-27 20:24:28
CXF有一個特別的功能。 – bmargulies 2010-01-27 20:39:17
@ewernli - 謝謝,但容器(Glassfish)似乎仍然覆蓋了端點地址。它似乎沒有工作。 – Vinnie 2010-01-27 21:01:48