Журнал jax-ws http запроса и ответа
Мне нужно зарегистрировать полный http-запрос и ответ в вызове JAX-WS WebService. Для запроса мне нужны заголовки запроса и тело, а для ответа - заголовки ответа и тело.
После некоторых исследований я обнаружил, что могу получить эту информацию с помощью свойства:
-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
и показать информацию, которая мне нужна, но она выводит ее на консоль, и мне нужно сохранить ее в базе данных с внутренним идентификатором запроса.
Я попытался реализовать обработчик:
public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
System.out.println("SOAP outbound!!!!!");
Map<String, List<String>> responseHeaders = (Map<String, List<String>>) context
.get(SOAPMessageContext.HTTP_RESPONSE_HEADERS);
try {
String headers = getHeaders(responseHeaders);
System.out.println(headers);
String body = getBody(context.getMessage());
System.out.println(body);
} catch (Exception ex) {
// TODO: What do I have to do in this case?
}
} else {
System.out.println("SOAP inbound!!!!!");
Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context
.get(SOAPMessageContext.HTTP_REQUEST_HEADERS);
try {
String headers = getHeaders(requestHeaders);
System.out.println(headers);
String body = getBody(context.getMessage());
System.out.println(body);
} catch (Exception ex) {
// TODO: What do I have to do in this case?
}
}
return true;
}
private String getBody(SOAPMessage message) throws SOAPException, IOException {
OutputStream stream = new ByteArrayOutputStream();
message.writeTo(stream);
return stream.toString();
}
public String getFullHttpRequest(HttpServletRequest request) throws IOException {
InputStream in = request.getInputStream();
String encoding = request.getCharacterEncoding();
encoding = encoding == null ? "UTF-8" : encoding;
String body = IOUtils.toString(in, encoding);
return body;
}
private String getHeaders(Map<String, List<String>> headers) throws IOException {
StringBuffer result = new StringBuffer();
if (headers != null) {
for (Entry<String, List<String>> header : headers.entrySet()) {
if (header.getValue().isEmpty()) {
// I don't think this is legal, but let's just dump it,
// as the point of the dump is to uncover problems.
result.append(header.getValue());
} else {
for (String value : header.getValue()) {
result.append(header.getKey() + ": " + value);
}
}
result.append("\n");
}
}
return result.toString();
}
}
но в этом случае я могу получить заголовки и тело http-запроса, но в ответе я получаю только тело, заголовки HTTP-ответа всегда пусты.
Есть идеи, как это заархивировать? Цель состоит в том, чтобы иметь возможность хранить полный HTTP-запрос и ответ в базе данных.
Спасибо!!
1 ответ
Вы также можете попробовать
-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
Я предполагаю, что вы предоставляете свой веб-сервис изнутри сервера приложений Java EE (а не из автономного клиента). У вас не может быть доступа к инфраструктуре Java EE, такой как HttpServletRequest
а также HttpServletResponse
вне контекста контейнера Web/Java EE.
Вы можете попытаться получить фактический объект ответа сервлета (в веб-контексте) с
HttpServletResponse response = (HttpServletResponse) messageContext.get(SOAPMessageContext.SERVLET_RESPONSE); //messageContext is the SOAPMessageContext
List<String> responseHeaderNames = (List<String>)response.getHeaderNames();
for(String headerName : responseHeaderNames){
//Do whatever you want with it.
}
Я серьезно сомневаюсь, что вы сможете получить полные заголовки ответа в обработчике. Ваш вопрос действительно заинтриговал меня, и я потратил довольно много времени на изучение этой части. Во всех примерах кода, которые я видел, даже в примере на сайте метро не пытались реализовать эту функцию, и я думаю, что причина проста. Как и в тот момент, когда вызывается обработчик, у контейнера может не хватить определенной информации, чтобы пометить заголовок http в исходящем сообщении. Вы можете добавить что-то, но это тоже сомнительно.