¿Cómo se establece un encabezado HTTP personalizado (no encabezado SOAP) dinámicamente en el lado del cliente cuando se utiliza Spring-WS?Configuración de un encabezado HTTP personalizado dinámicamente con el cliente Spring-WS
Respuesta
public class AddHttpHeaderInterceptor implements ClientInterceptor {
public boolean handleFault(MessageContext messageContext)
throws WebServiceClientException {
return true;
}
public boolean handleRequest(MessageContext messageContext)
throws WebServiceClientException {
TransportContext context = TransportContextHolder.getTransportContext();
CommonsHttpConnection connection = (CommonsHttpConnection) context.getConnection();
PostMethod postMethod = connection.getPostMethod();
postMethod.addRequestHeader("fsreqid", "123456");
return true;
}
public boolean handleResponse(MessageContext messageContext)
throws WebServiceClientException {
return true;
}
}
config:
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
...
<property name="interceptors">
<list>
<bean class="com.blah.AddHttpHeaderInterceptor" />
</list>
</property>
</bean>
ClientInterceptor
funciona muy bien para el valor de encabezado estático. Pero no es posible usarlo cuando se debe aplicar un valor diferente por cada solicitud. En ese caso WebServiceMessageCallback
es útil:
final String dynamicParameter = //...
webServiceOperations.marshalSendAndReceive(request,
new WebServiceMessageCallback() {
void doWithMessage(WebServiceMessage message) {
TransportContext context = TransportContextHolder.getTransportContext();
CommonsHttpConnection connection = (CommonsHttpConnection) context.getConnection();
PostMethod postMethod = connection.getPostMethod();
postMethod.addRequestHeader("fsreqid", dynamicParameter);
}
}
Esta solución es más flexible que usar el interceptor del cliente. En mi humilde opinión, debería ser el preferido. –
Me estoy poniendo siguiente excepción java.lang.ClassCastException: en esta línea context.getConnection() org.springframework.ws.transport.http.HttpServletConnection no se puede convertir a org.springframework.ws.transport.http .CommonsHttpConnection –
FYI, 'org.springframework.ws.transport.http.CommonsHttpConnection' ha quedado en desuso en favor de' org.springframework.ws.transport.http.HttpComponentsConnection'. – ZeroOne
El siguiente fragmento ha sido probado con Spring 4.0. Se añade un WebServiceMessageCallback
a un método org.springframework.ws.client.core.WebServiceTemplate
final String DYNAMICVALUE = "myDynamo";
WebServiceMessageCallback wsCallback = new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
try {
SoapMessage soapMessage = (SoapMessage)message;
SoapHeader header = soapMessage.getSoapHeader();
header.addAttribute(new QName("myHeaderElement"), DYNAMICVALUE);
} catch (Exception e) {
e.printStackTrace();
}
}
};
JAXBElement<MyWsResponse> response = (JAXBElement<MyWsResponse>)
wsTemplate.marshalSendAndReceive(MyWsOP, wsCallback);
La pregunta era "¿Cómo se establece una costumbre HTTP encabezado (no encabezado SOAP) ", pero esta respuesta en realidad agrega un encabezado SOAP, no un encabezado HTTP. – ZeroOne
webServiceTemplate.marshalSendAndReceive de primavera (petición) utiliza internamente HttpComponentsMessageSender para enviar el mensaje SOAP a través de la red y esto aún más WebServiceConnection utiliza para hacer la conexión con el servidor HTTP. Todo lo que tiene que hacer es escribir su propio HttpComponentsMessageSender personalizado y establecer la cookie dentro de PostMethod.
Custome del código de remitente: Configuración
package com.swap.ws.sender;
import java.io.IOException;
import java.net.URI;
import javax.annotation.Resource;
import org.apache.http.client.methods.HttpPost;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.ws.transport.WebServiceConnect ion;
import org.springframework.ws.transport.http.HttpComponen tsConnection;
/**
*
* @author swapnil Z
*/
@Service("urlMessageSender")
public class CustomHttpComponentsMessageSender extends
org.springframework.ws.transport.http.HttpComponen tsMessageSender {
private static Logger _logger = Logger.getLogger("");
@Override
public WebServiceConnection createConnection(URI uri) throws IOException {
String cookie = null;
HttpComponentsConnection conn = (HttpComponentsConnection) super
.createConnection(uri);
HttpPost postMethod = conn.getHttpPost();
cookie = "<Your Custom Cookie>";
postMethod.addHeader("Cookie", cookie);
return conn;
}
}
primavera:
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMe ssageFactory" />
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshalle r">
<property name="contextPath" value="com.swap.provision" />
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServi ceTemplate">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="marshaller"></property>
<property name="unmarshaller" ref="marshaller"></property>
<property name="messageSender" ref="urlMessageSender"/>
<property name="defaultUri" value=<Server URL> />
</bean>
Después de esto simplemente obtener webServiceTemplate frijol y llamar al método marshalSendAndReceive. Por lo tanto, cada solicitud tendrá su cookie personalizada antes de realizar una llamada HTTP.
Cuando se utiliza de integración de resorte 3 y del resorte de integración-ws, el código siguiente se puede utilizar para el manejo de la solicitud:
public boolean handleRequest(MessageContext messageContext)
throws WebServiceClientException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpUrlConnection connection = (HttpUrlConnection) context
.getConnection();
connection.getConnection().addRequestProperty("HEADERNAME",
"HEADERVALUE");
return true;
}
El interceptor se puede conectar a la pasarela de salida de la siguiente manera:
<ws:outbound-gateway ...
interceptor="addPasswordHeaderInterceptor" >
</ws:outbound-gateway>
<bean id="addPasswordHeaderInterceptor class="com.yourfirm.YourHttpInterceptor" />
En realidad, es una versión actualizada de la respuesta @Tomasz, pero proporciona una nueva API Spring-WS, accesos directos Java 8, y se preocupa por crear una instancia WebServiceMessageCallback
con un método diferente.
Creo que es más obvio y autosuficiente.
final class Service extends WebServiceGatewaySupport {
/**
* @param URL the URI to send the message to
* @param payload the object to marshal into the request message payload
* @param headers HTTP headers to add to the request
*/
public Object performRequestWithHeaders(String URL, Object payload, Map<String, String> headers) {
return getWebServiceTemplate()
.marshalSendAndReceive(URL, payload, getRequestCallback(headers));
}
/**
* Returns a {@code WebServiceMessageCallback} instance with custom HTTP headers.
*/
private WebServiceMessageCallback getRequestCallback(Map<String, String> headers) {
return message -> {
TransportContext context = TransportContextHolder.getTransportContext();
HttpUrlConnection connection = (HttpUrlConnection)context.getConnection();
addHeadersToConnection(connection, headers);
};
}
/**
* Adds all headers from the {@code headers} to the {@code connection}.
*/
private void addHeadersToConnection(HttpUrlConnection connection, Map<String, String> headers){
headers.forEach((name, value) -> {
try {
connection.addRequestHeader(name, value);
} catch (IOException e) {
e.printStackTrace(); // or whatever you want
}
});
}
}
- 1. SoapClient set encabezado HTTP personalizado
- 2. Configuración de encabezado HTTP personalizado para formularios GWT
- 3. Encabezado de autorización HTTP personalizado
- 4. Configuración del encabezado HTTP Accept para JsonRestStore
- 5. Solicitar un archivo con un encabezado personalizado
- 6. Cómo agregar un encabezado Http personalizado para el servicio web C# Cliente que consume el servicio web Axis 1.4
- 7. Aumentar la autenticación de formularios para usar un encabezado http personalizado para el ticket
- 8. redirect_to con encabezado HTTP
- 9. ¿Establece más de un encabezado HTTP con el mismo nombre?
- 10. Cómo configurar el User-Agent personalizado con la biblioteca del cliente apache http 4.1?
- 11. Método HTTP personalizado con el servidor HTTP de Nodejs
- 12. ¿Debería un servidor adherirse a la conexión HTTP: cerrar el encabezado enviado desde un cliente?
- 13. WCF Soap Actions en el encabezado HTTP o encabezado SOAP?
- 14. redirect_to custom http encabezado
- 15. Cliente HTTP asíncrono con Netty
- 16. NSURLRequest configurar el encabezado HTTP
- 17. ¿Cómo envío un encabezado personalizado con urllib2 en una solicitud HTTP?
- 18. Enviando un encabezado personalizado junto con la solicitud qtwebkit
- 19. Establecer encabezado SOAP personalizado utilizando Axis 1.4
- 20. jQuery AJAX Encabezado personalizado
- 21. Enviar encabezado de solicitud HTTP personalizado con etiqueta de audio HTML5
- 22. ¿Cómo establecer el encabezado HTTP en el marco de cliente RESTEasy?
- 23. Configurar un proxy HTTP para insertar un encabezado
- 24. Conexión Kerberos utilizando el cliente HTTP
- 25. ¿Cómo creo una solicitud de cliente HTTP con una cookie?
- 26. analizar un encabezado de solicitud HTTP Authorization con Python
- 27. agregando encabezado personalizado con ASP clásico
- 28. HTTP rango encabezado
- 29. La solicitud HTTP no está autorizada con el esquema de autenticación de cliente 'Negociar'. el encabezado de autenticación
- 30. ¿Cómo eliminar un encabezado de respuesta HTTP?
Buena respuesta, para los usuarios en el futuro, utilice HttpComponentsConnection en lugar de CommonsHttpConnection, ya que ha quedado en desuso. – dardo
¿Funciona al ejecutar pruebas JUnit? En mi caso, no fue así porque 'context.getConnection()' devuelve 'MockSenderConnection'. Estoy usando 'MockWebServiceServer' para pruebas unitarias. – Gooseman